The app engine code below uses app_identity.sign_blob() to request a signed url. This code works fine, when there is no space in the GCS filename. A space is allowed in object names. For testing I used the SDK.
I've seen a lot of questions about this issue, but I could not create a solution
Is it a bug or?
def sign_url(bucket_object, expires_after_seconds=6, bucket=default_bucket):
method = 'GET'
gcs_filename = urllib.quote('/%s/%s' % (bucket, bucket_object))
content_md5, content_type = None, None
# expiration : number of seconds since epoch
expiration_dt = datetime.utcnow() + timedelta(seconds=expires_after_seconds)
expiration = int(time.mktime(expiration_dt.timetuple()))
# Generate the string to sign.
signature_string = '\n'.join([
method,
content_md5 or '',
content_type or '',
str(expiration),
gcs_filename])
signature_bytes = app_identity.sign_blob(signature_string)[1]
# Set the right query parameters. we use a gae service account for the id
query_params = {'GoogleAccessId': google_access_id,
'Expires': str(expiration),
'Signature': base64.b64encode(signature_bytes)}
# Return the built URL.
result = '{endpoint}{resource}? {querystring}'.format(endpoint=GCS_API_ACCESS_ENDPOINT,
resource=gcs_filename,
querystring=urllib.urlencode(query_params))
return result
Update. The response when I use the signed url:
<Error>
<Code>NoSuchKey</Code>
<Message>The specified key does not exist.</Message>
</Error>
The problem has been solved.
I do not know why. I did not change anything. You can try the GAE app using the code below and this link:
https://voscausa-gae.appspot.com/download_signed?bucket_object=download/test signed1 .txt
The code is here: appengine-gcs-signed-url
You can also use a signed url with a policy document for a direct upload to GCS.
The code: https://github.com/voscausa/appengine-gcs-upload
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With