@@ -38,18 +38,25 @@ def __init__(self):
3838 def __call__ (self , chain : HandlerChain , context : RequestContext , response : Response ):
3939 self .handle_cors (chain , context , response )
4040
41- def pre_parse_s3_request (self , context : RequestContext ) -> Tuple [bool , Optional [str ]]:
41+ def pre_parse_s3_request (self , request : Request ) -> Tuple [bool , Optional [str ]]:
42+ """
43+ Parse the request to try to determine if it's directed towards S3. It tries to match on host, then check
44+ if the targeted bucket exists. If we could not determine it was a s3 request from the host, but the first
45+ element in the path contains an existing bucket, we can think it's S3.
46+ :param request: Request from the context
47+ :return: is_s3, whether we're certain it's a s3 request, and bucket_name if the bucket exists
48+ """
4249 is_s3 : bool
4350 bucket_name : str
4451
45- path = context . request .path
46- host = context . request .host
52+ path = request .path
53+ host = request .host
4754
4855 # first, try to figure out best-effort whether the request is an s3 request
4956 if host .startswith (S3_VIRTUAL_HOSTNAME ):
5057 is_s3 = True
5158 bucket_name = path .split ("/" )[1 ]
52- # try to extract the bucket from the hostname (the "in" check is a minor optimization
59+ # try to extract the bucket from the hostname (the "in" check is a minor optimization)
5360 elif ".s3" in host and (match := _s3_virtual_host_regex .match (host )):
5461 is_s3 = True
5562 bucket_name = match .group (3 )
@@ -76,21 +83,23 @@ def handle_cors(self, chain: HandlerChain, context: RequestContext, response: Re
7683 if config .LEGACY_S3_PROVIDER or config .DISABLE_CUSTOM_CORS_S3 :
7784 return
7885
79- is_s3 , bucket_name = self .pre_parse_s3_request (context )
86+ request = context .request
87+ is_s3 , bucket_name = self .pre_parse_s3_request (context .request )
8088
81- if not is_s3 and not bucket_name :
89+ if not is_s3 :
8290 # continue the chain, let the default CORS handler take care of the request
8391 return
8492
8593 # set the service so that the regular CORS enforcer knows it needs to ignore this request
8694 context .service = self ._service
8795
88- request = context .request
8996 is_options_request = request .method == "OPTIONS"
9097
9198 def stop_options_chain ():
92- # FIXME: need to add it there as not handled by the serializer, we stop the chain to avoid the request
93- # being parsed
99+ """
100+ Stops the chain to avoid the OPTIONS request being parsed. The request is ready to be returned to the
101+ client. We also need to add specific headers normally added by the serializer for regular requests.
102+ """
94103 request_id = gen_amzn_requestid_long ()
95104 response .headers ["x-amz-request-id" ] = request_id
96105 response .headers [
@@ -134,11 +143,8 @@ def stop_options_chain():
134143 message = "CORSResponse: Bucket not found"
135144 else :
136145 message = "CORSResponse: CORS is not enabled for this bucket."
137- try :
138- context .operation = self ._get_op_from_request (request )
139- except Exception :
140- context .operation = context .service .operation_model ("GetObject" )
141146
147+ context .operation = self ._get_op_from_request (request )
142148 raise AccessForbidden (
143149 message , HostId = FAKE_HOST_ID , Method = "OPTIONS" , ResourceType = "BUCKET"
144150 )
@@ -147,11 +153,6 @@ def stop_options_chain():
147153 return
148154
149155 rules = self .bucket_cors_index .cors [bucket_name ]["CORSRules" ]
150- # check this but should not happen? maybe?
151- if not rules :
152- if is_options_request :
153- stop_options_chain ()
154- return
155156
156157 if not (rule := self .match_rules (request , rules )):
157158 if is_options_request :
0 commit comments