Il codice del motore dell'app in basso utilizza app_identity.sign_blob() per richiedere un URL firmato. Questo codice funziona correttamente, quando non c'è spazio nel nome file GCS. Uno spazio è consentito in object names. Per il test ho usato l'SDK.NoSuchKey quando si ottiene un URL firmato per un oggetto cloudstorage con uno spazio nel nome
Ho visto un sacco di domande su questo problema, ma non ho potuto creare una soluzione
Si tratta di un bug o?
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
Aggiornamento
. La risposta quando uso l'url firmato:
<Error>
<Code>NoSuchKey</Code>
<Message>The specified key does not exist.</Message>
</Error>
Solo una teoria, ma sembra che tu stia usando il nome dell'oggetto senza escape. Credo che la sezione gcs_filename debba essere la porzione di percorso dell'URL, il che significa che il nome dell'oggetto dovrebbe essere URL-escape, cioè sostituire lo spazio con un segno più. Fammi sapere se lo fa. –
gcs_filename è preceduto da escape per la firma e la risorsa (= percorso) utilizzando urllib.quote() nel codice precedente. Ho anche provato urllib.quote_plus(). – voscausa
E riguardo urllib.quote_plus (path, safe = '/')? quote_plus sfugge alla barra per impostazione predefinita. –