I'm using the following two JAVA
methods to create a signed URL
to upload to Google Cloud Storage, using HTTP PUT
. The first method is supposed to generate the actual upload URL using POST
, while the second one is supposed to generate the URL
using serviceAccountCredentials
, to be used(to POST
) by the first one.
First Method
public String getUploadLink(String bucketName, String uuid, String objectName, String mimeType)
throws IOException, GenericAttachmentException {
if (!bucketExists(bucketName)) {
createBucket(bucketName);
}
URL myURL = new URL(getSignedUrlToPost(bucketName, uuid, objectName, mimeType));
HttpURLConnection myURLConnection = (HttpURLConnection) myURL.openConnection();
myURLConnection.setRequestMethod("POST");
myURLConnection.setRequestProperty("Content-Type", mimeType);
myURLConnection.setRequestProperty("x-goog-resumable", "start");
// Send POST request
myURLConnection.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(myURLConnection.getOutputStream());
wr.flush();
wr.close();
int responseCode = myURLConnection.getResponseCode();
if (responseCode != 201) {
throw new GenericAttachmentException(500,
"Error generating signed URL",
"Something went wrong while attempting to generate the URL.");
}
return myURLConnection.getHeaderField("Location");
}
Second Method
private String getSignedUrlToPost(String bucketName, String uuid, String objectName,
String mimeType) throws GenericAttachmentException {
try {
String verb = "POST";
long now = System.currentTimeMillis();
/* Expire in a minute. */
long expiryTimeInSeconds = (now + 60 * 1000L) / 1000;
String canonicalizedExtensionHeaders = "x-goog-resumable:start";
byte[] sr = serviceAccountCredentials.sign(
(verb + "\n\n" + mimeType + "\n" + expiryTimeInSeconds + "\n" + canonicalizedExtensionHeaders
+
"\n" + "/" + bucketName + "/" + uuid + "/" + objectName).getBytes());
String urlSignature = new String(Base64.encodeBase64(sr));
return "https://storage.googleapis.com/" + bucketName + "/" + uuid + "/" + objectName +
"?GoogleAccessId=" + serviceAccountEmail +
"&Expires=" + expiryTimeInSeconds +
"&Signature=" + URLEncoder.encode(urlSignature, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new GenericAttachmentException(500,
"Something went wrong while encoding the URL.",
e.getMessage());
}
}
This gives me an upload URL
, as follows:
https://storage.googleapis.com/bucket-name/7c9a5bd6-ece2-497d-b485-a9c53e27f253/a.pdf?GoogleAccessId=storage-dev@project-name-xxxxxx.iam.gserviceaccount.com&Expires=1592883655&Signature=IlTGvwGNN8VYrPE9qzSW0AIAwqMvbNoZ34TQ4nr4Po5vwZx78or9iiqBhO0jqoeoX6BYP%2BHGkWPIKMUijB%2FZ0L6Z%2BtnaZZkIJ581YQ3JK8BEHWqWyf0V07RwAN0TGAyld7h1JntWmGDyXKtjmy6Skt1C0GocJZA2x9GMxo94OD9kpFbjBucixgQDE%2BEtCzDUXWkymATls690pyLftXhAI0CVWg%2FPlcAe2Q%2F9M%2F68s5eWVSXa0%2BXIVQQ%2FucgXO8RbEDeu%2BWjrL3TcYQFTFd8Q%2BvcwKkpjbmKGpmMnYuTc7HSKrRWLLGxixsLBSjKdQDK4Tu14%2F0ROJVJo4Gv%2FX4oknQ%3D%3D&upload_id=AAANsUlwcmdpeCuME5YbeSpnfw5eQw_Sb65xl7t59b6GcNkNE0PUfe44tUDXHfobXRo-EBGI6X-I5zPqXyPBm4paSyBGyzZCWw
Issues:
- I'm able to upload an object, using the above
URL
, but the link doesn't expire after one minute. - The link doesn't invalidate itself after the initial upload is done,
meaning, when I use the same link to upload, for example,
xyz.jpg
usingHTTP PUT
, it returns200 OK
, even though it doesn't actually uploadxyz.jpg
and replace the original file.
Shouldn't the upload link invalidate itself once it is used to upload something to the server? Am i missing something here? Could really use some help.