"Resumable Upload" with "Signed URL" on Google Cloud Storage using Java


Jonathan Sylvester

Based on the documentation on how to create objects in google-cloud-storage (see the "create" method in https://googleapis.github.io/google-cloud-java/google-cloud-clients/apidocs/index.html ) ), when trying to upload large files, we should use the blob.writer(...) method, as it presumably handles resumable uploads automatically somehow. Is this correct?

But if we want resumable uploads of SIGNED urls, how can we do this in Java? (Any sample code or pointers would be greatly appreciated; my research so far leads me to believe that it is not possible to use the beautifully created Java library, and instead requires the use of "PUT" and "POST in Java" statements after generating the signed url. Is this the "best" approach so far?)

Joan Grau Noel

Regarding the first point, yes, the blob.writer(...)method handles resumable uploads automatically. Unfortunately, this method cannot be called from a signed URL, but can only upload files directly from the byte stream.

However, as you mentioned, there are other ways to create resumable uploads from signed URLs, e.g. using PUTmethod seems like a good workaround.

What I do is:

  1. Create a signed URL using the "PUT" method . You can do this by specifying SignUrlOption , and I specified a service account in the bucket with the required permissions.

  2. Use URLFetch to throw an HTTP request to this signed URL. I believe e.g. you can't use the curl command directly, and the UrlFetch API does the trick.

  3. Add the uploadType=resumable header to the urlFetchHTTP request. See this documentation for how it works and other parameters and information.

  4. I configured URLFetchto make an asynchronous call to the signed URL as I thought it would be more convenient when uploading large files.

Example code used in App Engine handler:

package com.example.storage;

import java.io.IOException;
import java.io.FileInputStream;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import java.util.HashMap;
import java.util.Map;
import java.nio.charset.StandardCharsets;

import java.net.URL;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

// Cloud Storage Imports
import com.google.cloud.storage.Bucket;
import com.google.cloud.storage.BucketInfo;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
import com.google.cloud.storage.Blob;
import com.google.cloud.storage.BlobId;
import com.google.cloud.storage.BlobInfo;
import com.google.cloud.storage.Storage.SignUrlOption;
import com.google.auth.oauth2.ServiceAccountCredentials;
import com.google.cloud.storage.HttpMethod;

// Url Fetch imports
import com.google.appengine.api.urlfetch.HTTPMethod;
import com.google.appengine.api.urlfetch.HTTPRequest;
import com.google.appengine.api.urlfetch.URLFetchService;
import com.google.appengine.api.urlfetch.URLFetchServiceFactory;
import com.google.appengine.api.urlfetch.HTTPHeader;

@WebServlet(name = "MainStorage", value = "/")
public class MainStorage extends HttpServlet {

        @Override
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
                // Bucket parameters 
                String bucketName = "MY-BUCKET-NAME";
                String blobName = "MY-BLOB-NAME";
                String keyPath = "/PATH-TO-SERVICE-ACCOUNT-KEY/key.json";

                BlobId blobId = BlobId.of(bucketName, blobName);
                Storage storage = StorageOptions.getDefaultInstance().getService();

                // Create signed URL with SignUrlOptions
                URL signedUrl = storage.signUrl(BlobInfo.newBuilder(bucketName, blobName).build(), 14, TimeUnit.DAYS,
                                                SignUrlOption.signWith(ServiceAccountCredentials.fromStream(new FileInputStream(keyPath))),
                                                SignUrlOption.httpMethod(HttpMethod.PUT));

                // Contents to upload to the Blob
                String content = "My-File-contents";

                // Build UrlFetch request
                HTTPRequest upload_request = new HTTPRequest(signedUrl, HTTPMethod.PUT);
                upload_request.setPayload(content.getBytes(StandardCharsets.UTF_8));

                // Set request to have an uploadType=resumable
                HTTPHeader set_resumable = new HTTPHeader("uploadType", "resumable");
                upload_request.setHeader(set_resumable);
                URLFetchService fetcher = URLFetchServiceFactory.getURLFetchService();

                // Do an asynchronous call to the signed URL with the contents
                fetcher.fetchAsync(upload_request);

                // Return response to App Engine handler call
                response.setContentType("text/plain");
                response.getWriter().println("Hello Storage");
        }
}

There may be a better way to do this, but I believe it gives an idea of ​​how to do this type of application.

Related


Resumable upload to Google Cloud Storage using PHP API

Fida Khattak I can successfully upload small files to Google Cloud Storage using Google PHP API CLIENT, but I can't upload 300MB files. returns with a memory error. Here is my code. $storage = new Google_Service_Storage($client); $file_name = "filenameo.z

Upload file to Google Cloud Storage signed URL using Python

Raj Chaudhary Can someone help me with the code, preferably using the Requests library to upload a file to a Google Cloud Storage signed URL in Python? Lundin Custer You can check out this sample code on Github . It shows a portable way to achieve this using P

Upload file to Google Cloud Storage signed URL using Python

Raj Chaudhary Can someone help me with the code, preferably using the Requests library to upload a file to a Google Cloud Storage signed URL in Python? Lundin Custer You can check out this sample code on Github . It shows a portable way to achieve this using P

Upload file to Google Cloud Storage signed URL using Python

Raj Chaudhary Can someone help me with the code, preferably using the Requests library to upload a file to a Google Cloud Storage signed URL in Python? Lundin Custer You can check out this sample code on Github . It shows a portable way to achieve this using P

upload file to google cloud storage with signed url using ajax

David I try to upload a file to my Google Cloud Storage using signed url. I have set CORS parameters on my bucket using gsutil Browser sends ajax request to Django backend to get signed url Django backend makes request to GCS to create signed url The signed ur

Create signed URL for Google Cloud Storage using NodeJS

Stuck Kennedy I'm trying to create a signature for a privately stored file in Google Cloud Storage; so I can distribute a limited time link. Currently doing this and the signature is too short...where am I going wrong? var crypto = require("crypto"); var ttl

Create signed URL for Google Cloud Storage using NodeJS

Stuck Kennedy I'm trying to create a signature for a privately stored file in Google Cloud Storage; so I can distribute a limited time link. Currently doing this and the signature is too short...where am I going wrong? var crypto = require("crypto"); var ttl

Upload file to Google Cloud Storage signed URL using Python

Raj Chaudhary Can someone help me with the code, preferably using the Requests library to upload a file to a Google Cloud Storage signed URL in Python? Lundin Custer You can check out this sample code on Github . It shows a portable way to achieve this using P

Upload file to Google Cloud Storage signed URL using Python

Raj Chaudhary Can someone help me with the code, preferably using the Requests library to upload a file to a Google Cloud Storage signed URL in Python? Lundin Custer You can check out this sample code on Github . It shows a portable way to achieve this using P

Upload to Google Cloud using signed URL

Roshan Upreti: I'm trying to generate download and upload links from Google Cloud to view and upload files using the following code: public class Test { public static void main(String[] args) throws IOException { Storage storage = StorageOptions.newBuilder().

Upload to Google Cloud using signed URL

Roshan Upreti: I'm trying to generate download and upload links from Google Cloud to view and upload files using the following code: public class Test { public static void main(String[] args) throws IOException { Storage storage = StorageOptions.newBuilder().

Upload to Google Cloud using signed URL

Roshan Upreti: I'm trying to generate download and upload links from Google Cloud to view and upload files using the following code: public class Test { public static void main(String[] args) throws IOException { Storage storage = StorageOptions.newBuilder().

Upload to Google Cloud using signed URL

Roshan Upreti: I'm trying to generate download and upload links from Google Cloud to view and upload files using the following code: public class Test { public static void main(String[] args) throws IOException { Storage storage = StorageOptions.newBuilder().

Upload to Google Cloud using signed URL

Roshan Upreti: I'm trying to generate download and upload links from Google Cloud to view and upload files using the following code: public class Test { public static void main(String[] args) throws IOException { Storage storage = StorageOptions.newBuilder().

Google storage with signed URL

Bouwan How to upload files of content type mutlipart/formdata ---boundaryStringusing Google Storage's signed URL ? The problem I'm facing is that when we upload the file using the browser, the browser places the mutlipart/formdata ---boundaryStringwhere bounda

Google storage with signed URL

Bouwan How to upload files of content type mutlipart/formdata ---boundaryStringusing Google Storage's signed URL ? The problem I'm facing is that when we upload the file using the browser, the browser places the mutlipart/formdata ---boundaryStringwhere bounda

Google storage with signed URL

Bouwan How to upload a file of content type mutlipart/formdata ---boundaryStringusing signed URL stored by Google ? The problem I'm facing is that when we upload the file using the browser, the browser places the mutlipart/formdata ---boundaryStringwhere bound

Google storage with signed URL

Bouwan How to upload files of content type mutlipart/formdata ---boundaryStringusing Google Storage's signed URL ? The problem I'm facing is that when we upload the file using the browser, the browser places the mutlipart/formdata ---boundaryStringwhere bounda

Google storage with signed URL

Bouwan How to upload files of content type mutlipart/formdata ---boundaryStringusing Google Storage's signed URL ? The problem I'm facing is that when we upload the file using the browser, the browser places the mutlipart/formdata ---boundaryStringwhere bounda

Put files into Google Cloud Storage (GCS) via signed URL

kctang: I'm trying to use a "signed URL" to access/upload files to Google Cloud Storage (GCS). Follow the instructions at https://developers.google.com/storage/docs/accesscontrol#Signing-Strings what did I do: "Web Application" is registered in Google Cloud Co

Provide callback URL in Google Cloud Storage signed URL

username When uploading to GCS (Google Cloud Storage) using BlobStore's createUploadURL function , I can provide a callback along with header data that will be sent to the callback URL. There doesn't seem to be a way to use GCS's signed URLs I know there are "