Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Batch upload requests to Google Cloud Storage using javascript

I'm trying to upload multiple images to google cloud storage in a batch request using javascript. I'm using https://developers.google.com/storage/docs/json_api/v1/how-tos/batch#example as reference.

I have an input file where the user can select multiple files, and an 'upload' btn to upload to GCS like so:

<input type="file" name="fileName" id="fileInput" multiple="multiple" onchange="javascript: loadFiles()"/> 
<input type="button" name="upload-btn" id="upload" value="Upload"/>

When the user selects the images, the 'loadFiles' function creates the 'body' of the batch request.

var tok = <token>;
var boundary = "---======= foo_bar_baz12034245623562346 ===";
var consolidated_request = '';

function loadFiles()
{
        var input = $('fileInput');
        for (var i = 0; i < input.files.length; i++) 
        {
            var f = input.files[i];

            var reader = new FileReader();
            reader.readAsBinaryString(f);

            reader.onload = function(e){

                var fbinary = e.target.result;
                var fsize = f.size;

                var url = 'https://www.googleapis.com/upload/storage/v1beta2/b/<mybucket>/o?';
                url += 'uploadType=media&name='+f.name+ ' HTTP/1.1';

                var req = boundary + 
                '\r\nContent-Type: application/http'+
                '\r\nContent-Transfer-Encoding: binary'+
                '\r\n\nPOST ' + url +
                '\r\nContent-Type: image/jpeg'+
                '\r\nContent-Length: '+ f.size +
                '\r\nAuthorization: '+tok+
                '\r\n\n'+ fbinary + '\n';

                consolidated_request += req;
            };

        }
}

When the user clicks on upload :

$('upload').onclick = function(e){

    var xhr = new XMLHttpRequest();
    xhr.open("POST", 'https://www.googleapis.com/batch', true);
    xhr.setRequestHeader("Authorization", tok);
    xhr.setRequestHeader("Content-Type", "multipart/mixed;boundary=" + boundary);
    xhr.send(consolidated_request);
 };

Here is a sample of the POST generated (using firebug):

Header:

Accept  text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding gzip, deflate
Accept-Language en-US,en;q=0.5
Authorization   Bearer ya29.AHES6ZQgu6gFurD6y7Bo2Mao1RNCFwyqNZcwvgDZ82RXIbQ4
Content-Length  159866
Content-Type    multipart/mixed; charset=UTF-8;boundary=---======= foo_bar_baz12034245623562346 ===
Host    www.googleapis.com

Body:

 --======= foo_bar_baz12034245623562346 === 
Content-Type: application/http 
Content-Transfer-Encoding: binary 

POST https://www.googleapis.com/upload/storage/v1beta2/b/<mybucket>/o?uploadType=media&name=myimage.jpg HTTP/1.1 
Content-Type: image/jpeg 
Content-Length: 69436 
Authorization: Bearer ya29.AHES6ZQgu6gFurD6y7Bo2Mao1RNCFwyqNZcwvgDZ82RXIbQ4 

ÿØÿà�JFIF���d�d��ÿì�Ducky�����<��ÿî�Adobe�dÀ���ÿÛ�� 
...

The problem is that there is no response because I get 400 bad request msg. What is wrong with that request?

like image 444
Sendy Avatar asked Nov 13 '22 01:11

Sendy


1 Answers

You are sending POST request as -

POST https://www.googleapis.com/upload/storage/v1beta2/b/<mybucket>/o?uploadType=media&name=myimage.jpg HTTP/1.1 

As stated in upload objects with POST request -

To upload media, you use a special URI. POST methods support media uploads have two URI endpoints:

  1. The /upload URI, for the media. The format of the upload endpoint is the standard resource URI with an “/upload” prefix. Use this URI when transferring the media data itself. Example: POST /upload/storage/v1beta2/b/myBucket/o.
  2. The standard resource URI, for the metadata. If the resource contains any data fields, those fields are used to store metadata describing the uploaded file. You can use this URI when creating or updating metadata values. Example: POST /storage/v1beta2/b/myBucket/o.

So you need to send POST request as -

POST /upload/storage/v1beta2/b/myBucket/o?uploadType=media&name=myimage.jpg HTTP/1.1

Try sending POST request by omitting prefix https://www.googleapis.com from url.

Thanks

Neelam Sharma

like image 153
Neelam Sharma Avatar answered Nov 15 '22 00:11

Neelam Sharma