9898IGNORED_HEADERS_LOWER = [
9999 'remote-addr' , 'host' , 'user-agent' , 'accept-encoding' ,
100100 'accept' , 'connection' , 'origin' ,
101- 'x-forwarded-for' , 'x-localstack-edge' , 'authorization'
101+ 'x-forwarded-for' , 'x-localstack-edge' , 'authorization' , 'date'
102102]
103103
104104# params are required in presigned url
@@ -326,6 +326,14 @@ def convert_origins_into_list(allowed_origins):
326326 return [allowed_origins ]
327327
328328
329+ def get_origin_host (headers ):
330+ origin = headers .get ('Origin' )
331+ if not origin :
332+ x_forwarded_header = re .split (r',\s?' , headers .get ('X-Forwarded-For' , '' ))
333+ origin = x_forwarded_header [len (x_forwarded_header ) - 1 ]
334+ return origin
335+
336+
329337def append_cors_headers (bucket_name , request_method , request_headers , response ):
330338 bucket_name = normalize_bucket_name (bucket_name )
331339
@@ -340,11 +348,7 @@ def append_cors_headers(bucket_name, request_method, request_headers, response):
340348 del response .headers [header ]
341349
342350 # Fetching origin of the request
343- origin = request_headers .get ('Origin' )
344-
345- if not origin :
346- x_forwarded_header = re .split (r',\s?' , request_headers .get ('X-Forwarded-For' ))
347- origin = x_forwarded_header [len (x_forwarded_header ) - 1 ]
351+ origin = get_origin_host (request_headers )
348352
349353 rules = cors ['CORSConfiguration' ]['CORSRule' ]
350354 if not isinstance (rules , list ):
@@ -1392,9 +1396,9 @@ def authenticate_presign_url(method, path, headers, data=None):
13921396 if key .lower () not in IGNORED_HEADERS_LOWER :
13931397 sign_headers .append (header )
13941398
1395- # Request's headers are more essentials than the query parameters in the requets .
1396- # Different values of header in the header of the request and in the query paramter of the requets url
1397- # will fail the signature calulation. As per the AWS behaviour
1399+ # Request's headers are more essentials than the query parameters in the request .
1400+ # Different values of header in the header of the request and in the query parameter of the
1401+ # request URL will fail the signature calulation. As per the AWS behaviour
13981402 presign_params_lower = [p .lower () for p in PRESIGN_QUERY_PARAMS ]
13991403 if len (query_params ) > 2 :
14001404 for key in query_params :
@@ -1403,13 +1407,17 @@ def authenticate_presign_url(method, path, headers, data=None):
14031407 sign_headers .append ((key , query_params [key ][0 ]))
14041408
14051409 # Preparnig dictionary of request to build AWSRequest's object of the botocore
1410+ request_url = url .split ('?' )[0 ]
1411+ origin = get_origin_host (headers )
1412+ if origin :
1413+ request_url = re .sub ('://[^/]+' , '://%s' % origin , request_url )
14061414 request_dict = {
14071415 'url_path' : path .split ('?' )[0 ],
14081416 'query_string' : {},
14091417 'method' : method ,
14101418 'headers' : dict (sign_headers ),
14111419 'body' : b'' ,
1412- 'url' : url . split ( '?' )[ 0 ] ,
1420+ 'url' : request_url ,
14131421 'context' : {
14141422 'is_presign_request' : True ,
14151423 'use_global_endpoint' : True ,
@@ -1428,7 +1436,8 @@ def authenticate_presign_url(method, path, headers, data=None):
14281436 signature = auth .get_signature (string_to_sign = string_to_sign )
14291437
14301438 # Comparing the signature in url with signature we calculated
1431- if query_params ['Signature' ][0 ] != signature :
1439+ query_sig = urlparse .unquote (query_params ['Signature' ][0 ])
1440+ if query_sig != signature :
14321441 return requests_error_response_xml_signature_calculation (
14331442 code = 403 ,
14341443 code_string = 'SignatureDoesNotMatch' ,
0 commit comments