4242
4343
4444def generate_signed_url (service_account_file , bucket_name , object_name ,
45- expiration , http_method = 'GET' , query_parameters = None ,
46- headers = None ):
45+ subresource = None , expiration = 604800 , http_method = 'GET' ,
46+ query_parameters = None , headers = None ):
4747
4848 if expiration > 604800 :
4949 print ('Expiration Time can\' t be longer than 604800 seconds (7 days).' )
5050 sys .exit (1 )
5151
5252 # [START storage_signed_url_canonical_uri]
5353 escaped_object_name = quote (six .ensure_binary (object_name ), safe = b'/~' )
54- canonical_uri = '/{}/{} ' .format (bucket_name , escaped_object_name )
54+ canonical_uri = '/{}' .format (escaped_object_name )
5555 # [END storage_signed_url_canonical_uri]
5656
5757 # [START storage_signed_url_canonical_datetime]
@@ -73,7 +73,8 @@ def generate_signed_url(service_account_file, bucket_name, object_name,
7373 if headers is None :
7474 headers = dict ()
7575 # [START storage_signed_url_canonical_headers]
76- headers ['host' ] = 'storage.googleapis.com'
76+ host = '{}.storage.googleapis.com' .format (bucket_name )
77+ headers ['host' ] = host
7778
7879 canonical_headers = ''
7980 ordered_headers = collections .OrderedDict (sorted (headers .items ()))
@@ -99,6 +100,8 @@ def generate_signed_url(service_account_file, bucket_name, object_name,
99100 query_parameters ['X-Goog-Date' ] = request_timestamp
100101 query_parameters ['X-Goog-Expires' ] = expiration
101102 query_parameters ['X-Goog-SignedHeaders' ] = signed_headers
103+ if subresource :
104+ query_parameters [subresource ] = ''
102105
103106 canonical_query_string = ''
104107 ordered_query_parameters = collections .OrderedDict (
@@ -138,10 +141,9 @@ def generate_signed_url(service_account_file, bucket_name, object_name,
138141 # [END storage_signed_url_signer]
139142
140143 # [START storage_signed_url_construction]
141- host_name = 'https://storage.googleapis.com'
142- signed_url = '{}{}?{}&X-Goog-Signature={}' .format (host_name , canonical_uri ,
143- canonical_query_string ,
144- signature )
144+ scheme_and_host = '{}://{}' .format ('https' , host )
145+ signed_url = '{}{}?{}&x-goog-signature={}' .format (
146+ scheme_and_host , canonical_uri , canonical_query_string , signature )
145147 # [END storage_signed_url_construction]
146148 return signed_url
147149# [END storage_signed_url_all]
@@ -151,18 +153,26 @@ def generate_signed_url(service_account_file, bucket_name, object_name,
151153 parser = argparse .ArgumentParser (
152154 description = __doc__ ,
153155 formatter_class = argparse .RawDescriptionHelpFormatter )
154- parser .add_argument ('service_account_file' ,
155- help = 'Path to your Google service account.' )
156156 parser .add_argument (
157- 'request_method' , help = 'A request method, e.g GET, POST.' )
157+ 'service_account_file' ,
158+ help = 'Path to your Google service account keyfile.' )
159+ parser .add_argument (
160+ 'request_method' ,
161+ help = 'A request method, e.g GET, POST.' )
158162 parser .add_argument ('bucket_name' , help = 'Your Cloud Storage bucket name.' )
159163 parser .add_argument ('object_name' , help = 'Your Cloud Storage object name.' )
160- parser .add_argument ('expiration' , help = 'Expiration Time.' )
164+ parser .add_argument ('expiration' , type = int , help = 'Expiration time.' )
165+ parser .add_argument (
166+ '--subresource' ,
167+ default = None ,
168+ help = 'Subresource of the specified resource, e.g. "acl".' )
161169
162170 args = parser .parse_args ()
171+
163172 signed_url = generate_signed_url (
164173 service_account_file = args .service_account_file ,
165174 http_method = args .request_method , bucket_name = args .bucket_name ,
166- object_name = args .object_name , expiration = int (args .expiration ))
175+ object_name = args .object_name , subresource = args .subresource ,
176+ expiration = int (args .expiration ))
167177
168178 print (signed_url )
0 commit comments