1
votes

I am using the Google Drive SDK to upload files from javascript (https://developers.google.com/drive/v2/reference/files/insert, using uploadType multipart to specify both content and metadata).

I can upload images (mimeType image/jpeg) fine. However, uploading plain text (mimeType text/plain) or JSON (mimeType application/json) files would result in an empty file being created.

My work around was to specify the file content mimeType as 'application/octet-stream' and everything works fine.

Anyone have any idea why specifying a mimeType of application/json for json content, or text/plain for text content would result in an empty file while changing to application/octet-stream works fine?

I should note that because my code is running as a part of a Chrome App, I have had to make a modified gapi client (since the standard one violates CORS). As an aside, is the google javascript api (gapi) client code available in a code repository somewhere to check out?

An excerpt of my upload code is:

        var metadata = {
            'title': ufilename,
            'mimeType': contentType,
            'modifiedDate' : modifiedDate,
            'parents': [{'id':parentGuid}]
        };

        var multipartRequestBody =
            delimiter +
            'Content-Type: application/json\r\n\r\n' +
            JSON.stringify(metadata) +
            delimiter +
            'Content-Type: ' + contentType + '\r\n' +
            '\r\n' +
            JSON.stringify(jsonObj) +
            close_delim;

        var reqObj = {
                'path': '/upload/drive/v2/files',
                'method': 'POST',
                'params': {'uploadType': 'multipart'},
                'headers': {
                  'Content-Type': 'multipart/mixed; boundary="' + boundary + '"'
                },
                'body': multipartRequestBody
        };

        var request = gapi.client.request(reqObj);

As requested, a sample request is:

headers: Content-Type: "multipart/mixed; boundary="-------314159265358979323846"
method: "POST"
params: uploadType: "multipart"
path: "https://www.googleapis.com/upload/drive/v2/files"
body:
---------314159265358979323846
Content-Type: application/json

{"title":"survey.json","mimeType":"application/octet-stream","modifiedDate":"2014-10-24T08:17:45.099-06:00","parents":[{"id":"0B4ho7vdmkgJOczc4NENqd0d0TDg"}]}
---------314159265358979323846
Content-Type: application/octet-stream

{"model":{"DateTime":{"type":"datetime","required":true},"Bird":{"type":"string"},"Photo":         {"type":"image"},"Notes":{"type":"string"},"Location":{"type":"geopoint"}},"settings":[{"setting":"form_id","value":"birdwatching"},{"setting":"form_version","value":1},{"setting":"form_category","value":"Tracking"},{"setting":"form_title","value":"Bird Watching"}],"survey":[{"name":"DateTime","type":"datetime","label":"Date and Time"},{"name":"Location","type":"geopoint","label":"Location"},{"name":"Bird","type":"string-auto","label":"Bird"},{"type":"text","name":"Notes","label":"Notes"},{"name":"Photo","type":"image","label":"Photo"}],"choices":{}}
---------314159265358979323846-- 

In all cases (regardless of mime-type) I get a return object with readyState 4/status 200. The only difference is the fileSize is 0 if Content-Type is I specify mimetype of application/json.

2
can you paste the http request and responsepinoyyid
pinoyyid: I pasted an example in the original request. Is there something specific you are looking for?dwhogg
It's just easier to read the http than code. I've provided an answer since I can't paste code into comments.pinoyyid

2 Answers

3
votes

Turns out problem was my custom gapi client which was not properly setting "uploadType" as "multipart". For some reason this didn't seem to matter as long as the mime-type wasn't text/plain or application/json.

Setting the uploadType properly works as expected for all mime-types.

1
votes

Here is an example http multipart generated using http://www.clevernote.co/app/drivecrud.html

Looking at it, I'd say the only difference is the base64 encoding of the data, and I can't see x-upload-content-length:6564 and x-upload-content-type:text/plain in yours.

hth

:host:www.googleapis.com

:method:POST

:path:/upload/drive/v2/files?uploadType=multipart&alt=json

accept:application/json, text/plain, /

accept-encoding:gzip,deflate

accept-language:en-US,en;q=0.8,en-AU;q=0.6

authorization:Bearer ya29.qAAz3aEs6QohclT8eRlX0pqEwvSQv8nS4FHXjhN7OG

content-length:6824

content-type:multipart/mixed; boundary="-------3141592ff65358979323846"

origin:http://www.clevernote.co

referer:http://www.clevernote.co/app/drivecrud.html

x-client-data:CKS1yQEIh7bJAQiktskpPKAQjelsoB

x-upload-content-length:6564

x-upload-content-type:text/plain

Query String Parametersview sourceview URL encoded

uploadType:multipart

alt:json

Request Payload

---------3141592ff65358979323846

Content-Type: application/json

{"$promise":{},"title":"delme","mimeType":"text/plain"}

---------3141592ff65358979323846

Content-Type: text/plain

Content-Transfer-Encoding: base64

IERhdGUsRGVzY3JpcHRpb24sQmFuayAgICAgUmVmZXJlbmNlLEN1c3RvbWVyICBSZWZlcmVuY2UsQ3JlZGl0LERlYml...