Enter the callback URL in the signed Google Cloud Storage URL

When uploading to GCS (Google Cloud Storage) using the BlobStore createUploadURL function, I can provide a callback along with the header data that will be sent to the callback URL.

There seems to be no way to do this using a GCS signed URL

I know that the Notification of object change , but this will not allow the user to provide certain information for loading in the POST header, this is possible using the createUploadURL callback.

I feel that if createUploadURL can do this, there must be a way to do this with a signed URL, but I cannot find any documentation on it. I was wondering if anyone could find out how createUploadURL achieves this callback call behavior.


PS: I'm trying to move away from createUploadURL because of the objects he created __BlobInfo__that I don’t need for my specific use case, and somehow seem indelible and lose storage space.


Update: It worked! Here's how:

Short answer: This cannot be done with PUT , but can be done with POST

Long answer:

signed-URL, HTTP_Verb , GET, HEAD, PUT DELETE, POST - . , .

HTTP Headers, , POST; success_action_redirect, voscausa.

POST Google " " PUT, . POST , PUT. , POST , .

, createUploadURL . :


:

Python voscausa code, .

apejs javascript Java-, :

            var exp = new Date()
            exp.setTime(exp.getTime() + 1000 * 60 * 100); //100 minutes

            json['GoogleAccessId'] = String(appIdentity.getServiceAccountName())
            json['key'] = keyGenerator()
            json['bucket'] = bucket
            json['Expires'] = exp.toISOString(); 
            json['success_action_redirect'] = "https://" + request.getServerName() + "/test2/";
            json['uri'] = 'https://' + bucket + '.storage.googleapis.com/'; 

            var policy = {'expiration': json.Expires
                        , 'conditions': [
                             ["starts-with", "$key", json.key],
                             {'Expires': json.Expires},
                             {'bucket': json.bucket},
                             {"success_action_redirect": json.success_action_redirect}
                           ]
                        };

            var plain = StringToBytes(JSON.stringify(policy))
            json['policy'] = String(Base64.encodeBase64String(plain))
            var result = appIdentity.signForApp(Base64.encodeBase64(plain, false));
            json['signature'] = String(Base64.encodeBase64String(result.getSignature()))

. . ( .getBytes Java. javascript). base64 . appidentity. , base64, .

json- , uri, .

        var formData = new FormData(document.forms.namedItem('upload'));
        var blob = new Blob([thedata], {type: 'application/json'})
        var keys = ['GoogleAccessId', 'key', 'bucket', 'Expires', 'success_action_redirect', 'policy', 'signature']
        for(field in keys)
          formData.append(keys[field], url[keys[field]])
        formData.append('file', blob)
        var rest = new XMLHttpRequest();
        rest.open('POST', url.uri)
        rest.onload = callback_function
        rest.send(formData)

, 204 . , 200. 403 400, . responseText. .


:

  • POST PUT , . POST .
  • PUT baseurl, ( ), URL-, POST,
  • PUT UNIX, POST , ISO.
  • PUT URL (Java: URLEncoder.encode). POST Base64.
  • POST Base64.encodeBase64String (result.getSignature()) Base64.encodeBase64URLSafeString
  • POST; , POST.
  • URL- success_action_redirect, GET , eTag.
  • POST , . PUT, , , , tera-.

createUploadURL?

createUploadURL. :


javascript:

function StringToBytes(sz) {
  map = function(x) {return x.charCodeAt(0)}
  return sz.split('').map(map)
}
+4
3

succes_action_redirect , post post.

: : https://cloud.google.com/storage/docs/xml-api/post-object
Python : https://github.com/voscausa/appengine-gcs-upload

:

def ok(self):
    """ GCS upload success callback """

    logging.debug('GCS upload result : %s' % self.request.query_string)
    bucket = self.request.get('bucket', default_value='')
    key = self.request.get('key', default_value='')
    key_parts = key.rsplit('/', 1)
    folder = key_parts[0] if len(key_parts) > 1 else None
+2

URL-:

HTTP-

., , , Content-Disposition, URL-:

public static String getSignedUrl(String httpVerb, String fileName, String gsKey) {
    try {
        long expiration = new Date().getTime()/1000 + 5 * 60 * 60;
        String unsigned = stringToSign(expiration, gsKey, httpVerb);
        String signature = sign(unsigned);
        return new StringBuilder(BASE_URL).append("/")
                .append(BUCKET)
                .append("/")
                .append(gsKey)
                .append("?GoogleAccessId=")
                .append(identityService.getServiceAccountName())
                .append("&Expires=")
                .append(expiration)
                .append("&response-content-disposition=")
                .append(URLEncoder.encode("attachment;filename=" + "\"" + fileName + "\"", "UTF-8"))
                .append("&Signature=")
                .append(URLEncoder.encode(signature, "UTF-8")).toString();
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    return null;
}

, - , createUploadUrl.

0

, , . , , Post URL- - - .

In doPost()I get all the information about the objects added to the GCS, and from there I can do anything.

This worked great in my App Engine project.

0
source

Source: https://habr.com/ru/post/1622564/


All Articles