PUT files to Google Cloud Storage (GCS) via Signed URLs

Finally managed to PUT files to Google Cloud Storage using signed URLs. This was done by creating a simple Java program to simulate:

  • Server to sign & encode a string as signature.
  • Uploader as an unauthenticated user submitting the PUT request using only the signature provided by Server. Browser is simulated using Apache's HTTP Client library.

You can see the demo app here.

I do not really understand why it did not work when I submitted through Chrome's Postman extension.


Though the doc says Content-Type is optional, it actually means you must set correct content-Type correspond to your http request header.

In this case, your must add content-type: text/plain in the signing string.

https://cloud.google.com/storage/docs/access-control/create-signed-urls-program


I was struggling with PUT and the signed URL (with GAE Cloud Endpoints) but here are the two things I needed to do:

  1. Make sure you have the latest GAE gradle dependencies. The auto generated ones but android studio are not always the latest.
  2. For PUT you need to have your string to sign look like this:

    String url_signature = sign(verb + "\n" + contentMD5 + "\n" + contentType + "\n" + expiration + "\n" + "/" + BUCKET_NAME + "/" + objectName );

As explained here: https://cloud.google.com/storage/docs/access-control/signed-urls the format is:

StringToSign = HTTP_Verb + "\n" +
               Content_MD5 + "\n" +
               Content_Type + "\n" +
               Expiration + "\n" +
               Canonicalized_Extension_Headers +
               Canonicalized_Resource

Those return "\n" are important. If you have too many or not enough, you will get that error. If you are not passing a contentMD5, for example, just pass in an empty string so you get the right number of return "\n"