locked
HttpClient sending content-disposition and content-type in the wrong order

    Question

  • Hi,

    I'm trying to upload a file to onedrive, so I´m creating a multipart message like this:

    var client = new HttpClient();
    var multipart = new HttpMultipartContent("form-data");
    var filePart = new HttpStreamContent(fileStream.AsInputStream());
    var contentDisposition = new HttpContentDispositionHeaderValue("form-data");
    contentDisposition.Name = "file";
    contentDisposition.FileName = fileName;
    contentDisposition.FileNameStar = "";
    filePart.Headers.ContentDisposition = contentDisposition;
    filePart.Headers.ContentType = new HttpMediaTypeHeaderValue(contentType);
    multipart.Add(filePart);
    var response = await client.PostAsync(uri, multipart).AsTask(cancel, new HttpReceiveProgressHandler(progress));
    

    which posts the following request

    POST https://apis.live.net/v5.0/folder.XXXXXXXXXXXX/files?access_token=XXXXXXXXXX HTTP/1.1

    Accept-Encoding: gzip, deflate

    Content-Length: 212

    Content-Type: multipart/form-data; boundary=a4269a35-f83f-4b15-80cd-a991515bbda4

    Host: apis.live.net

    Connection: Keep-Alive

    Cache-Control: no-cache

    --a4269a35-f83f-4b15-80cd-a991515bbda4

    Content-Type: application/pdf

    Content-Dis-data; name="file"; filename="file.pdf"

    asdfasdf sadf asdf asdf asf

    --a4269a35-f83f-4b15-80cd-a991515bbda4--

    But OneDrive server reject the package, because it expects the Content-Disposition header to be before the Content-Type header. How can I alter the header's order?, I tried many things but nothing worked.

    Thanks,

    Alvaro.


    Alvaro Rivoir

    Friday, August 8, 2014 8:55 PM

Answers

  • Hi Herro,

    Using "PUT" method worked to upload a file to skydrive. Anyway the http client "Windows.Web.Http.HttpClient" should allow to specify the order of the headers.

    Another problem I faced when using the following code

    var client = new HttpClient();
    var multipart = new HttpMultipartFormDataContent();
    multipart.Add(new HttpStreamContent(fileStream.AsInputStream()), "file", fileName);
    var response = await client.PostAsync(uri, multipart).AsTask(cancel, new Progress<HttpProgress>(p => { }));
    

    it adds "filename*" which is not accepted by OneDrive.

    PUT https://apis.live.net/v5.0/folder.XXXXXX/files/file.pdf?access_token=XXXXX HTTP/1.1

    Accept-Encoding: gzip, deflate

    Content-Length: 210

    Content-Type: multipart/form-data; boundary=9d421852-443e-4dc4-afd9-6c9e4ead3ab9

    Host: apis.live.net

    Connection: Keep-Alive

    Cache-Control: no-cache

    --9d421852-443e-4dc4-afd9-6c9e4ead3ab9

    Content-Dis-data; name="file"; filename="file.pdf"; filename*=UTF-8''file.pdf

    asdfasdf sadf asdf asdf asf

    --9d421852-443e-4dc4-afd9-6c9e4ead3ab9--

    Thank you very much,

    Alvaro.


    Alvaro Rivoir

    • Marked as answer by Alvaro Rivoir Tuesday, August 19, 2014 1:38 PM
    Monday, August 11, 2014 2:15 PM

All replies

  • Hi Alvaro,

    >How can I alter the header's order?

    Please try the code sample on the following link. http://stackoverflow.com/questions/24888439/sending-multipart-form-data-from-windows-phone-to-web-api.

    If your platforms that support PUT request, it’s recommend to use PUT to upload files to OneDrive. See code sample from MSDN. http://msdn.microsoft.com/en-us/library/dn659726.aspx.

    Regards,


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Monday, August 11, 2014 6:23 AM
    Moderator
  • Hi Herro,

    Using "PUT" method worked to upload a file to skydrive. Anyway the http client "Windows.Web.Http.HttpClient" should allow to specify the order of the headers.

    Another problem I faced when using the following code

    var client = new HttpClient();
    var multipart = new HttpMultipartFormDataContent();
    multipart.Add(new HttpStreamContent(fileStream.AsInputStream()), "file", fileName);
    var response = await client.PostAsync(uri, multipart).AsTask(cancel, new Progress<HttpProgress>(p => { }));
    

    it adds "filename*" which is not accepted by OneDrive.

    PUT https://apis.live.net/v5.0/folder.XXXXXX/files/file.pdf?access_token=XXXXX HTTP/1.1

    Accept-Encoding: gzip, deflate

    Content-Length: 210

    Content-Type: multipart/form-data; boundary=9d421852-443e-4dc4-afd9-6c9e4ead3ab9

    Host: apis.live.net

    Connection: Keep-Alive

    Cache-Control: no-cache

    --9d421852-443e-4dc4-afd9-6c9e4ead3ab9

    Content-Dis-data; name="file"; filename="file.pdf"; filename*=UTF-8''file.pdf

    asdfasdf sadf asdf asdf asf

    --9d421852-443e-4dc4-afd9-6c9e4ead3ab9--

    Thank you very much,

    Alvaro.


    Alvaro Rivoir

    • Marked as answer by Alvaro Rivoir Tuesday, August 19, 2014 1:38 PM
    Monday, August 11, 2014 2:15 PM
  • I can't seem to find the RFC now, but I remember reading that HTTP header order isn't important or guaranteed with the one exception that if there are two headers with the same name (left of =), the order is then relevant.

    That's deadly important stuff when you build a proxy server on a complete unrelated platform.

    Can you point out the where OneDrive says the headers have to be in a particular order, or the error message indicating headers are out of order?  I'd be interested for some of my own stuff that hasn't ever considered header order.

    Interesting...


    Darin R.

    Tuesday, August 12, 2014 12:05 AM
  • Hi Darin,

    OneDrive returns an error in the message

    The request entity body has an incorrect value in the 'Content-Disposition' header.

    The expected format for this value is

    'Content-Dis-data; name="file"; filename="[FileName]"'.

    If the Content-Disposition header is after Content-Type this error is returned. The same when the attribute "filename*" is included.

    Regards,

    Alvaro.


    Alvaro Rivoir

    Tuesday, August 12, 2014 1:39 PM
  • Content-Dis-Data has to appear after the content-type in this case, because the content is a multi-part body, so I'll have to modify my original statement that "headers' order isn't important" to HTTP Request headers' order isn't important.

    This is different. You're actually sending the form data in the http body section, not the headers.

    ========================
     POST /path/to/script.php HTTP/1.0
     Host: example.com
     Content-type: multipart/form-data, boundary=AaB03x
     Content-Length: $requestlen
    
     --AaB03x
     content-dis-data; name="field1"
    
     $field1
     --AaB03x
     content-dis-data; name="field2"
    
     $field2
     --AaB03x
     content-dis-data; name="userfile"; filename="$filename"
     Content-Type: $mimetype
     Content-Transfer-Encoding: binary
    
     $binarydata
     --AaB03x--
     ==========================

    In the above example, the HTTP header is everything up to the first blank line.  The HTTP request body is everything after.  You can't put a content disposition(in that format) in the HTTP request headers, it isn't valid.

    [EDIT.  The multipart-form section is the same too, though - headers order isn't important.  Get it to upload properly, then switch them - it won't matter.]

    Anyway, I've hijacked the post long enough about this, sorry.  I just needed to get a sense of the damage when my stuff would have failed later!


    Darin R.


    • Edited by Darin Rousseau Tuesday, August 12, 2014 2:30 PM two content-types in the post, I address both now.
    Tuesday, August 12, 2014 2:23 PM
  • Hi Darin,

    I was speaking of the order of the headers of every part inside a multipart message.

    Notice the message you post can't be performed with the api, no matter what you do, the library put the Content-Type before Content-Disposition, inside the multipart message, and that's not accepted by OneDrive.

    Regards,

    Alvaro.


    Alvaro Rivoir

    Tuesday, August 12, 2014 2:38 PM
  • Yeah, I edited that in. 

    The same goes though.  You can't process the multipart section without all the headers, so doing them one at a time would be quite useless.

    Anyway, I'd get a sample working and then swap the header order.  You'll see that when everything is syntactically correct, and properly formatted, the header order doesn't matter. 

    Unfortunately, I can't speak to the workings of the classes setting up the formatting correct or not, sorry.

    Have you tried Herro's PUT suggestion?  It seems easier.


    Darin R.

    Tuesday, August 12, 2014 2:49 PM
  • Alvaro,

    The name of the header should be 'Content-Disposition'.  Your problem is there is no content disposition header... and not the order:

    Content-Dis-data; name="file"; filename="file.pdf"



    Jeff Sanders (MSFT)

    @jsandersrocks - Windows Store Developer Solutions @WSDevSol
    Getting Started With Windows Azure Mobile Services development? Click here
    Getting Started With Windows Phone or Store app development? Click here
    My Team Blog: Windows Store & Phone Developer Solutions
    My Blog: Http Client Protocol Issues (and other fun stuff I support)

    Wednesday, August 13, 2014 3:13 PM
    Moderator