Moshe Rubin
Moshe Rubin

Reputation: 1982

Multipart upload to OneDrive cloud server returns code 400 ("invalidRequest" error code)

I'm trying to upload a file using multipart POST from my C++/curl code to OneDrive's cloud server using the REST API. The OneDrive documentation on multipart upload is not particularly helpful, talking in very slipshod terms, when a wrong byte can make the difference between succeeding and failing.

As careful as I've tried to be, I'm receiving an HTTP response code of 400 with a JSON error message saying:

{
    "error": {
        "code": "invalidRequest",
        "message": "Bad Argument"
    }
}

The symptoms I'm encountering matching almost exactly those in this entry in the OneDrive API Docs Github project. I've tried to incorporate the points mentioned there (i.e., using a content type of "multipart/related" rather than "multipart/form-data", specifying the "@content.sourceUrl" key in the JSON, metadata, inserting a blank line between the end of a header section and the related data) but to no avail.

The requests and responses look like this (".." is a CR/LF pair):

POST /v1.0/drive/root:/CloudSampler_Test_Root/Test_1/Folder-1%E2%80%99/:/children HTTP/1.1..
User-Agent: curl/7.19.3..
Host: api.onedrive.com..
Accept: */*..
Authorization: bearer EwB4Aq1DBAAUGCCX...G4Ipkx/y4JxqVTtgtutstYqGYQE=..
Content-Type: multipart/related; boundary="220BF741_A0E3_4458_A2B2_D6BA6F3DBFC6"..
Content-Length: 12226..
Expect: 100-continue..
..
//--------------------------------------------
HTTP/1.1 100 Continue..
//--------------------------------------------
..
--220BF741_A0E3_4458_A2B2_D6BA6F3DBFC6..
Content-Disposition: form-data; name="metadata"..
Content-Type: application/json; charset=UTF-8..
Content-Length: 109..
Content-Transfer-Encoding: binary..
..
{"file":{},"name":"odrive-test.png", "@content.sourceUrl":"cid:content", "@name.conflictBehavior": "replace"}..
--220BF741_A0E3_4458_A2B2_D6BA6F3DBFC6..
Content-Disposition: form-data; name="content"..
Content-Type: application/octet-stream..
Content-Length: 11691..
Content-Transfer-Encoding: binary..
..
<file content: 11691 octets>
--220BF741_A0E3_4458_A2B2_D6BA6F3DBFC6--
//--------------------------------------------

The following are hex dumps of precisely what I'm sending/receiving to/from the OneDrive cloud server (after authenticating, of course). I'm posting the hex dumps so anyone can see the precise bytes being sent/received.

libCurl debug information (type=CURLINFO_HEADER_OUT)
000000: 50 4f 53 54 20 2f 76 31 2e 30 2f 64 72 69 76 65  POST /v1.0/drive
000010: 2f 72 6f 6f 74 3a 2f 43 6c 6f 75 64 53 61 6d 70  /root:/CloudSamp
000020: 6c 65 72 5f 54 65 73 74 5f 52 6f 6f 74 2f 54 65  ler_Test_Root/Te
000030: 73 74 5f 31 2f 46 6f 6c 64 65 72 2d 31 25 45 32  st_1/Folder-1%E2
000040: 25 38 30 25 39 39 2f 3a 2f 63 68 69 6c 64 72 65  %80%99/:/childre
000050: 6e 20 48 54 54 50 2f 31 2e 31 0d 0a 55 73 65 72  n HTTP/1.1..User
000060: 2d 41 67 65 6e 74 3a 20 63 75 72 6c 2f 37 2e 31  -Agent: curl/7.1
000070: 39 2e 33 0d 0a 48 6f 73 74 3a 20 61 70 69 2e 6f  9.3..Host: api.o
000080: 6e 65 64 72 69 76 65 2e 63 6f 6d 0d 0a 41 63 63  nedrive.com..Acc
000090: 65 70 74 3a 20 2a 2f 2a 0d 0a 41 75 74 68 6f 72  ept: */*..Author
0000a0: 69 7a 61 74 69 6f 6e 3a 20 62 65 61 72 65 72 20  ization: bearer 
0000b0: 45 77 42 34 41 71 31 44 42 41 41 55 47 43 43 58  EwB4Aq1DBAAUGCCX
. . .
0003e0: 47 34 49 70 6b 78 2f 79 34 4a 78 71 56 54 74 67  G4Ipkx/y4JxqVTtg
0003f0: 74 75 74 73 74 59 71 47 59 51 45 3d 0d 0a 43 6f  tutstYqGYQE=..Co
000400: 6e 74 65 6e 74 2d 54 79 70 65 3a 20 6d 75 6c 74  ntent-Type: mult
000410: 69 70 61 72 74 2f 72 65 6c 61 74 65 64 3b 20 62  ipart/related; b
000420: 6f 75 6e 64 61 72 79 3d 22 32 32 30 42 46 37 34  oundary="220BF74
000430: 31 5f 41 30 45 33 5f 34 34 35 38 5f 41 32 42 32  1_A0E3_4458_A2B2
000440: 5f 44 36 42 41 36 46 33 44 42 46 43 36 22 0d 0a  _D6BA6F3DBFC6"..
000450: 43 6f 6e 74 65 6e 74 2d 4c 65 6e 67 74 68 3a 20  Content-Length: 
000460: 31 32 32 32 36 0d 0a 45 78 70 65 63 74 3a 20 31  12226..Expect: 1
000470: 30 30 2d 63 6f 6e 74 69 6e 75 65 0d 0a 0d 0a     00-continue....

libCurl debug information (type=CURLINFO_HEADER_IN)
000000: 48 54 54 50 2f 31 2e 31 20 31 30 30 20 43 6f 6e  HTTP/1.1 100 Con
000010: 74 69 6e 75 65 0d 0a                             tinue..

libCurl debug information (type=CURLINFO_DATA_OUT)
000000: 0d 0a 2d 2d 32 32 30 42 46 37 34 31 5f 41 30 45  ..--220BF741_A0E
000010: 33 5f 34 34 35 38 5f 41 32 42 32 5f 44 36 42 41  3_4458_A2B2_D6BA
000020: 36 46 33 44 42 46 43 36 0d 0a 43 6f 6e 74 65 6e  6F3DBFC6..Conten
000030: 74 2d 44 69 73 70 6f 73 69 74 69 6f 6e 3a 20 66  t-Disposition: f
000040: 6f 72 6d 2d 64 61 74 61 3b 20 6e 61 6d 65 3d 22  orm-data; name="
000050: 6d 65 74 61 64 61 74 61 22 0d 0a 43 6f 6e 74 65  metadata"..Conte
000060: 6e 74 2d 54 79 70 65 3a 20 61 70 70 6c 69 63 61  nt-Type: applica
000070: 74 69 6f 6e 2f 6a 73 6f 6e 3b 20 63 68 61 72 73  tion/json; chars
000080: 65 74 3d 55 54 46 2d 38 0d 0a 43 6f 6e 74 65 6e  et=UTF-8..Conten
000090: 74 2d 4c 65 6e 67 74 68 3a 20 31 30 39 0d 0a 43  t-Length: 109..C
0000a0: 6f 6e 74 65 6e 74 2d 54 72 61 6e 73 66 65 72 2d  ontent-Transfer-
0000b0: 45 6e 63 6f 64 69 6e 67 3a 20 62 69 6e 61 72 79  Encoding: binary
0000c0: 0d 0a 0d 0a 7b 22 66 69 6c 65 22 3a 7b 7d 2c 22  ....{"file":{},"
0000d0: 6e 61 6d 65 22 3a 22 6f 64 72 69 76 65 2d 74 65  name":"odrive-te
0000e0: 73 74 2e 70 6e 67 22 2c 20 22 40 63 6f 6e 74 65  st.png", "@conte
0000f0: 6e 74 2e 73 6f 75 72 63 65 55 72 6c 22 3a 22 63  nt.sourceUrl":"c
000100: 69 64 3a 63 6f 6e 74 65 6e 74 22 2c 20 22 40 6e  id:content", "@n
000110: 61 6d 65 2e 63 6f 6e 66 6c 69 63 74 42 65 68 61  ame.conflictBeha
000120: 76 69 6f 72 22 3a 20 22 72 65 70 6c 61 63 65 22  vior": "replace"
000130: 7d 0d 0a 2d 2d 32 32 30 42 46 37 34 31 5f 41 30  }..--220BF741_A0
000140: 45 33 5f 34 34 35 38 5f 41 32 42 32 5f 44 36 42  E3_4458_A2B2_D6B
000150: 41 36 46 33 44 42 46 43 36 0d 0a 43 6f 6e 74 65  A6F3DBFC6..Conte
000160: 6e 74 2d 44 69 73 70 6f 73 69 74 69 6f 6e 3a 20  nt-Disposition: 
000170: 66 6f 72 6d 2d 64 61 74 61 3b 20 6e 61 6d 65 3d  form-data; name=
000180: 22 63 6f 6e 74 65 6e 74 22 0d 0a 43 6f 6e 74 65  "content"..Conte
000190: 6e 74 2d 54 79 70 65 3a 20 61 70 70 6c 69 63 61  nt-Type: applica
0001a0: 74 69 6f 6e 2f 6f 63 74 65 74 2d 73 74 72 65 61  tion/octet-strea
0001b0: 6d 0d 0a 43 6f 6e 74 65 6e 74 2d 4c 65 6e 67 74  m..Content-Lengt
0001c0: 68 3a 20 31 31 36 39 31 0d 0a 43 6f 6e 74 65 6e  h: 11691..Conten
0001d0: 74 2d 54 72 61 6e 73 66 65 72 2d 45 6e 63 6f 64  t-Transfer-Encod
0001e0: 69 6e 67 3a 20 62 69 6e 61 72 79 0d 0a 0d 0a     ing: binary....

libCurl debug information (type=CURLINFO_DATA_OUT)
000000: 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52  .PNG........IHDR
000010: 00 00 02 a5 00 00 01 57 08 02 00 00 00 14 08 a0  .......W........
000020: ea 00 00 00 2c 74 45 58 74 43 72 65 61 74 69 6f  ....,tEXtCreatio
000030: 6e 20 54 69 6d 65 00 54 75 65 20 32 30 20 41 75  n Time.Tue 20 Au
. . .
002d70: 00 60 ff 21 de 03 00 00 ec 3f c4 7b 00 00 80 fd  .`.!.....?.{....
002d80: 87 78 0f 00 00 b0 ff d4 fb ef 9f 3c 79 32 b5 19  .x.........<y2..
002d90: 00 00 00 b0 43 fe 3f 62 c4 5f cf 41 5d 3b 97 00  ....C.?b._.A];..
002da0: 00 00 00 49 45 4e 44 ae 42 60 82                 ...IEND.B`.

libCurl debug information (type=CURLINFO_DATA_OUT)
000000: 2d 2d 32 32 30 42 46 37 34 31 5f 41 30 45 33 5f  --220BF741_A0E3_
000010: 34 34 35 38 5f 41 32 42 32 5f 44 36 42 41 36 46  4458_A2B2_D6BA6F
000020: 33 44 42 46 43 36 2d 2d                          3DBFC6--

libCurl debug information (type=CURLINFO_HEADER_IN)
000000: 48 54 54 50 2f 31 2e 31 20 34 30 30 20 42 61 64  HTTP/1.1 400 Bad
000010: 20 52 65 71 75 65 73 74 0d 0a                     Request..

libCurl debug information (type=CURLINFO_HEADER_IN)
000000: 43 6f 6e 74 65 6e 74 2d 4c 65 6e 67 74 68 3a 20  Content-Length: 
000010: 36 30 0d 0a                                      60..

libCurl debug information (type=CURLINFO_HEADER_IN)
000000: 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20 61 70  Content-Type: ap
000010: 70 6c 69 63 61 74 69 6f 6e 2f 6a 73 6f 6e 0d 0a  plication/json..

libCurl debug information (type=CURLINFO_HEADER_IN)
000000: 53 65 72 76 65 72 3a 20 4d 69 63 72 6f 73 6f 66  Server: Microsof
000010: 74 2d 48 54 54 50 41 50 49 2f 32 2e 30 0d 0a     t-HTTPAPI/2.0..

libCurl debug information (type=CURLINFO_HEADER_IN)
000000: 50 33 50 3a 20 43 50 3d 22 42 55 53 20 43 55 52  P3P: CP="BUS CUR
000010: 20 43 4f 4e 6f 20 46 49 4e 20 49 56 44 6f 20 4f   CONo FIN IVDo O
000020: 4e 4c 20 4f 55 52 20 50 48 59 20 53 41 4d 6f 20  NL OUR PHY SAMo 
000030: 54 45 4c 6f 22 0d 0a                             TELo"..

libCurl debug information (type=CURLINFO_HEADER_IN)
000000: 58 2d 4d 53 4e 53 45 52 56 45 52 3a 20 42 4e 31  X-MSNSERVER: BN1
000010: 33 30 34 5f 5f 5f 5f 50 41 50 31 38 30 0d 0a     304____PAP180..

libCurl debug information (type=CURLINFO_HEADER_IN)
000000: 53 74 72 69 63 74 2d 54 72 61 6e 73 70 6f 72 74  Strict-Transport
000010: 2d 53 65 63 75 72 69 74 79 3a 20 6d 61 78 2d 61  -Security: max-a
000020: 67 65 3d 33 31 35 33 36 30 30 30 3b 20 69 6e 63  ge=31536000; inc
000030: 6c 75 64 65 53 75 62 44 6f 6d 61 69 6e 73 0d 0a  ludeSubDomains..

libCurl debug information (type=CURLINFO_HEADER_IN)
000000: 58 2d 51 6f 73 53 74 61 74 73 3a 20 7b 22 41 70  X-QosStats: {"Ap
000010: 69 49 64 22 3a 30 2c 22 52 65 73 75 6c 74 54 79  iId":0,"ResultTy
000020: 70 65 22 3a 32 2c 22 53 6f 75 72 63 65 50 72 6f  pe":2,"SourcePro
000030: 70 65 72 74 79 49 64 22 3a 30 2c 22 54 61 72 67  pertyId":0,"Targ
000040: 65 74 50 72 6f 70 65 72 74 79 49 64 22 3a 34 32  etPropertyId":42
000050: 7d 0d 0a                                         }..

libCurl debug information (type=CURLINFO_HEADER_IN)
000000: 58 2d 54 68 72 6f 77 53 69 74 65 3a 20 31 34 37  X-ThrowSite: 147
000010: 39 2e 62 38 39 31 0d 0a                          9.b891..

libCurl debug information (type=CURLINFO_HEADER_IN)
000000: 58 2d 41 73 6d 56 65 72 73 69 6f 6e 3a 20 55 4e  X-AsmVersion: UN
000010: 4b 4e 4f 57 4e 3b 20 31 39 2e 32 33 2e 30 2e 30  KNOWN; 19.23.0.0
000020: 0d 0a                                            ..

libCurl debug information (type=CURLINFO_HEADER_IN)
000000: 44 61 74 65 3a 20 54 68 75 2c 20 30 36 20 41 75  Date: Thu, 06 Au
000010: 67 20 32 30 31 35 20 32 30 3a 33 35 3a 30 34 20  g 2015 20:35:04 
000020: 47 4d 54 0d 0a                                   GMT..

libCurl debug information (type=CURLINFO_HEADER_IN)
000000: 0d 0a                                            ..

libCurl debug information (type=CURLINFO_DATA_IN)
000000: 7b 22 65 72 72 6f 72 22 3a 7b 22 63 6f 64 65 22  {"error":{"code"
000010: 3a 22 69 6e 76 61 6c 69 64 52 65 71 75 65 73 74  :"invalidRequest
000020: 22 2c 22 6d 65 73 73 61 67 65 22 3a 22 42 61 64  ","message":"Bad
000030: 20 41 72 67 75 6d 65 6e 74 22 7d 7d               Argument"}}

Trace statements in my log show that precisely 12,226 bytes were transmitted by curl to the OneDrive server, as expected.

Can anyone help point out what the error in my multipart request is?

Upvotes: 0

Views: 340

Answers (1)

mmilo
mmilo

Reputation: 806

I ran into this as well. If you see yegodz post on the issue you linked, you need to add the Content-ID headers to each part, as appropriate.

As he also said, the documentation is misleading as Content-Disposition isn't really required (it seems, for the metadata part, anyway).

Ex. For the metadata part, Content-ID: <metadata> Note that <metadata> is not some placeholder. It's the actual text.

Upvotes: 1

Related Questions