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:
--287032381131322
Content-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:
--287032381131322
Content-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