How to use curl upload one image file using "Content-Type: multipart/related" How to use curl upload one image file using "Content-Type: multipart/related" curl curl

How to use curl upload one image file using "Content-Type: multipart/related"


I see it's a quite old post, but I just faced the same issue trying to use Google Drive API with curl and finally found the solution, but it's a bit tricky to use, specially on the content length calculation, so I will leave a reply in case it helps someone else!

According to google documentation, first of all, you should include the Content-Type, Content-Length and Authorization headers in the main request. For the Content-Length, you can let curl automatically calculate it, so add the other headers like this:

-H "Content-Type: multipart/related; boundary=287032381131322"-H "Authorization: Bearer <Your Oauth2 Access Token>"

Second, you need to include a multipart section with the metadata. This section need to start with the boundary, followed by the Content-Type header:

--287032381131322Content-Type: application/json; charset=UTF-8

Followed by your metadata content:

{\"name\":\"Test\"}

Next section, is the boundary start for the binary data, which must contain again the boundary delimiter and the Content-Type header:

--287032381131322Content-Type: application/octet-stream

Followed by the binary data you want to upload, which is simply passed as:

--data-binary @file.ext

And lastly, you should include a new section for closing the boundary delimiter:

--287032381131322--

So in my example, using a file of 5679 bytes, this will be the full command and reply from google:

curl -v -H "Content-Type: multipart/related; boundary=287032381131322"      \    -H "Authorization: Bearer <My Oauth2 Access Token>"                   \    --data-binary $'--287032381131322\r\nContent-Type: application/json; charset=UTF-8\r\n\r\n{\"name\":\"Test\"}\r\n--287032381131322\r\nContent-Type: application/octet-stream\r\n\r\n' \    --data-binary @b0c11d3b40b71ed08108e5dad7f6ecee-0                       \    --data-binary $'\r\n--287032381131322--'                                \    "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart"> POST /upload/drive/v3/files?uploadType=multipart HTTP/1.1> Host: www.googleapis.com> User-Agent: curl/7.47.0> Accept: */*> Content-Type: multipart/related; boundary=287032381131322> Authorization: Bearer <My Oauth2 Access Token>> Content-Length: 5848> Expect: 100-continue> < HTTP/1.1 100 Continue* We are completely uploaded and fine< HTTP/1.1 200 OK< X-GUploader-UploadID:  <My Uploader ID>< Vary: Origin< Vary: X-Origin< Content-Type: application/json; charset=UTF-8< Cache-Control: no-cache, no-store, max-age=0, must-revalidate< Pragma: no-cache< Expires: Mon, 01 Jan 1990 00:00:00 GMT< Date: Mon, 24 Jul 2017 20:56:50 GMT< Content-Length: 123< Server: UploadServer< Alt-Svc: quic=":443"; ma=2592000; v="39,38,37,36,35"< { "kind": "drive#file", "id": "0B-4U01-IEMlATjdfbVNqQURiN0U", "name": "Test", "mimeType": "application/octet-stream"}* Connection #0 to host www.googleapis.com left intact


Update: It was pointed out that I didn't read the question properly for my previous answer. curl -F is for multipart/form-data not for multipart/related.

In fact, curl has no convenient way to send a multipart/related stream that I can think of. Are you really sure that is what you want to send?

When you used your command line, you got the entire transfer logged in 'trace.txt'. Didn't that aid you in finding out what's wrong?