class Aws::Plugins::S3RequestSigner::BucketSigningErrorHandler
This handler detects when a request fails because signature version 4 is required but not used. It follows up by making a request to determine the correct region, then finally a version 4 signed request against the regional endpoint.
Constants
- SIGV4_MSG
Public Instance Methods
call(context)
click to toggle source
# File lib/aws-sdk-core/plugins/s3_request_signer.rb, line 148 def call(context) response = @handler.call(context) handle_region_errors(response) end
Private Instance Methods
detect_region_and_retry(resp)
click to toggle source
# File lib/aws-sdk-core/plugins/s3_request_signer.rb, line 187 def detect_region_and_retry(resp) context = resp.context updgrade_to_v4(context, 'us-east-1') resp = @handler.call(context) if resp.successful? resp else actual_region = region_from_location_header(context) updgrade_to_v4(context, actual_region) log_warning(context, actual_region) @handler.call(context) end end
extract_body_region_and_retry(context)
click to toggle source
# File lib/aws-sdk-core/plugins/s3_request_signer.rb, line 176 def extract_body_region_and_retry(context) actual_region = region_from_body(context) updgrade_to_v4(context, actual_region) log_warning(context, actual_region) @handler.call(context) end
handle_region_errors(response)
click to toggle source
# File lib/aws-sdk-core/plugins/s3_request_signer.rb, line 155 def handle_region_errors(response) if sigv4_required_error?(response) detect_region_and_retry(response) elsif wrong_sigv4_region?(response) extract_body_region_and_retry(response.context) else response end end
log_warning(context, actual_region)
click to toggle source
# File lib/aws-sdk-core/plugins/s3_request_signer.rb, line 215 def log_warning(context, actual_region) S3::BUCKET_REGIONS[context.params[:bucket]] = actual_region msg = "S3 client configured for #{context.config.region.inspect} " + "but the bucket #{context.params[:bucket].inspect} is in " + "#{actual_region.inspect}; Please configure the proper region " + "to avoid multiple unecessary redirects and signing attempts\n" if logger = context.config.logger logger.warn(msg) else warn(msg) end end
region_from_body(context)
click to toggle source
# File lib/aws-sdk-core/plugins/s3_request_signer.rb, line 183 def region_from_body(context) context.http_response.body_contents.match(/<Region>(.+?)<\/Region>/)[1] end
region_from_location_header(context)
click to toggle source
# File lib/aws-sdk-core/plugins/s3_request_signer.rb, line 210 def region_from_location_header(context) location = context.http_response.headers['location'] location.match(/s3[.-](.+?)\.amazonaws\.com/)[1] end
sigv4_required_error?(resp)
click to toggle source
# File lib/aws-sdk-core/plugins/s3_request_signer.rb, line 165 def sigv4_required_error?(resp) resp.context.http_response.status_code == 400 && resp.context.http_response.body_contents.match(SIGV4_MSG) && resp.context.http_response.body.respond_to?(:truncate) end
updgrade_to_v4(context, region)
click to toggle source
# File lib/aws-sdk-core/plugins/s3_request_signer.rb, line 201 def updgrade_to_v4(context, region) context.http_response.body.truncate(0) context.http_request.headers.delete('authorization') context.http_request.headers.delete('x-amz-security-token') context.http_request.endpoint.host = new_hostname(context, region) signer = Signers::V4.new(context.config.credentials, 's3', region) signer.sign(context.http_request) end
wrong_sigv4_region?(resp)
click to toggle source
# File lib/aws-sdk-core/plugins/s3_request_signer.rb, line 171 def wrong_sigv4_region?(resp) resp.context.http_response.status_code == 400 && resp.context.http_response.body_contents.match(/<Region>.+?<\/Region>/) end