Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions gems/aws-sdk-s3/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
Unreleased Changes
------------------

* Issue - Handle 200 errors for all S3 operations that do not have streaming responses.

1.152.0 (2024-06-05)
------------------

Expand Down
43 changes: 27 additions & 16 deletions gems/aws-sdk-s3/lib/aws-sdk-s3/plugins/http_200_errors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,40 @@ class Handler < Seahorse::Client::Handler

def call(context)
@handler.call(context).on(200) do |response|
if error = check_for_error(context)
context.http_response.status_code = 500
response.data = nil
response.error = error
end
return response if streaming_output?(context.operation.output)

error = check_for_error(context)
return response unless error

context.http_response.status_code = 500
response.data = nil
response.error = error
end
end

private

def streaming_output?(output)
if (payload = output[:payload_member]) # checking ref and shape
payload['streaming'] || payload.shape['streaming'] ||
payload.eventstream
else
false
end
end

def members_in_body?(output)
output.shape.members.any? { |_, k| k.location.nil? }
end

def check_for_error(context)
xml = context.http_response.body_contents
if xml.match(/<Error>/)
if xml.match(/\?>\s*<Error>/)
error_code = xml.match(/<Code>(.+?)<\/Code>/)[1]
error_message = xml.match(/<Message>(.+?)<\/Message>/)[1]
S3::Errors.error_class(error_code).new(context, error_message)
elsif !xml.match(/<\w/) # Must have the start of an XML Tag
elsif members_in_body?(context.operation.output) && !xml.match(/<\w/)
# Must have a body member and have the start of an XML Tag
# Other incomplete xml bodies will result in XML ParsingError
Seahorse::Client::NetworkingError.new(
S3::Errors
Expand All @@ -40,15 +59,7 @@ def check_for_error(context)
end
end

handler(
Handler,
step: :sign,
operations: [
:complete_multipart_upload,
:copy_object,
:upload_part_copy,
]
)
handler(Handler, step: :sign)
end
end
end
Expand Down
168 changes: 88 additions & 80 deletions gems/aws-sdk-s3/spec/client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,16 @@ module S3
'rw0nS41rawnLDzkf+PKXmmt/uEi4bzvNMr72o=',
'x-amz-request-id' => 'BE9C18E622969B17'
},
body: ''
)
body: <<-XML)
<?xml version="1.0" encoding="UTF-8"?>
<ListAllMyBucketsResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\">
<Buckets>
<Bucket>
<Name>aws-sdk-ruby</Name>
</Bucket>
</Buckets>
</ListAllMyBucketsResult>
XML
Seahorse::Client::Response.new(context: context)
end
resp = s3.list_buckets
Expand Down Expand Up @@ -423,14 +431,14 @@ module S3
status_code: 409,
headers: {},
body: <<-XML.strip
<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>BucketNotEmpty</Code>
<Message>The bucket you tried to delete is not empty</Message>
<BucketName>aws-sdk</BucketName>
<RequestId>740BE6AB575EACED</RequestId>
<HostId>MQVg1RMI+d93Hps1E8qpIuDb9Gd2TzkDhm0wE40981DjxSHP1UfLBB7qOAlwAqJB</HostId>
</Error>
<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>BucketNotEmpty</Code>
<Message>The bucket you tried to delete is not empty</Message>
<BucketName>aws-sdk</BucketName>
<RequestId>740BE6AB575EACED</RequestId>
<HostId>MQVg1RMI+d93Hps1E8qpIuDb9Gd2TzkDhm0wE40981DjxSHP1UfLBB7qOAlwAqJB</HostId>
</Error>
XML
)
Seahorse::Client::Response.new(context: context)
Expand All @@ -452,8 +460,8 @@ module S3
status_code: 200,
headers: {},
body: <<-XML.strip
<?xml version="1.0" encoding="UTF-8"?>
<LocationConstraint xmlns="http://s3.amazonaws.com/doc/2006-03-01/">EU</LocationConstraint>
<?xml version="1.0" encoding="UTF-8"?>
<LocationConstraint xmlns="http://s3.amazonaws.com/doc/2006-03-01/">EU</LocationConstraint>
XML
)
Seahorse::Client::Response.new(context: context)
Expand All @@ -469,8 +477,8 @@ module S3
status_code: 200,
headers: {},
body: <<-XML.strip
<?xml version="1.0" encoding="UTF-8"?>
<LocationConstraint xmlns="http://s3.amazonaws.com/doc/2006-03-01/"/>
<?xml version="1.0" encoding="UTF-8"?>
<LocationConstraint xmlns="http://s3.amazonaws.com/doc/2006-03-01/"/>
XML
)
Seahorse::Client::Response.new(context: context)
Expand Down Expand Up @@ -504,19 +512,19 @@ module S3
status_code: 200,
headers: {},
body: <<-XML.strip)
<?xml version="1.0" encoding="UTF-8"?>
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Prefix>a%26</Prefix>
<Delimiter>b%26</Delimiter>
<Marker>c%26</Marker>
<NextMarker>d%26</NextMarker>
<Contents>
<Key>e%26</Key>
</Contents>
<CommonPrefixes>
<Prefix>f%26</Prefix>
</CommonPrefixes>
</ListBucketResult>
<?xml version="1.0" encoding="UTF-8"?>
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Prefix>a%26</Prefix>
<Delimiter>b%26</Delimiter>
<Marker>c%26</Marker>
<NextMarker>d%26</NextMarker>
<Contents>
<Key>e%26</Key>
</Contents>
<CommonPrefixes>
<Prefix>f%26</Prefix>
</CommonPrefixes>
</ListBucketResult>
XML
Seahorse::Client::Response.new(context: context)
end
Expand All @@ -541,12 +549,12 @@ module S3
status_code: 200,
headers: {},
body: <<-XML.strip)
<?xml version="1.0" encoding="UTF-8"?>
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Contents>
<Key>a%26</Key>
</Contents>
</ListBucketResult>
<?xml version="1.0" encoding="UTF-8"?>
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Contents>
<Key>a%26</Key>
</Contents>
</ListBucketResult>
XML
Seahorse::Client::Response.new(context: context)
end
Expand All @@ -562,22 +570,22 @@ module S3
status_code: 200,
headers: {},
body: <<-XML.strip)
<?xml version="1.0" encoding="UTF-8"?>
<ListVersionsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01">
<Prefix>a%26</Prefix>
<Delimiter>b%26</Delimiter>
<KeyMarker>c%26</KeyMarker>
<NextKeyMarker>d%26</NextKeyMarker>
<Version>
<Key>e%26</Key>
</Version>
<DeleteMarker>
<Key>f%26</Key>
</DeleteMarker>
<CommonPrefixes>
<Prefix>g%26</Prefix>
</CommonPrefixes>
</ListVersionsResult>
<?xml version="1.0" encoding="UTF-8"?>
<ListVersionsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01">
<Prefix>a%26</Prefix>
<Delimiter>b%26</Delimiter>
<KeyMarker>c%26</KeyMarker>
<NextKeyMarker>d%26</NextKeyMarker>
<Version>
<Key>e%26</Key>
</Version>
<DeleteMarker>
<Key>f%26</Key>
</DeleteMarker>
<CommonPrefixes>
<Prefix>g%26</Prefix>
</CommonPrefixes>
</ListVersionsResult>
XML
Seahorse::Client::Response.new(context: context)
end
Expand All @@ -602,19 +610,19 @@ module S3
status_code: 200,
headers: {},
body: <<-XML.strip)
<?xml version="1.0" encoding="UTF-8"?>
<ListVersionsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01">
<Prefix>a%26</Prefix>
<Delimiter>b%26</Delimiter>
<KeyMarker>c%26</KeyMarker>
<NextKeyMarker>d%26</NextKeyMarker>
<Upload>
<Key>e%26</Key>
</Upload>
<CommonPrefixes>
<Prefix>f%26</Prefix>
</CommonPrefixes>
</ListVersionsResult>
<?xml version="1.0" encoding="UTF-8"?>
<ListVersionsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01">
<Prefix>a%26</Prefix>
<Delimiter>b%26</Delimiter>
<KeyMarker>c%26</KeyMarker>
<NextKeyMarker>d%26</NextKeyMarker>
<Upload>
<Key>e%26</Key>
</Upload>
<CommonPrefixes>
<Prefix>f%26</Prefix>
</CommonPrefixes>
</ListVersionsResult>
XML
Seahorse::Client::Response.new(context: context)
end
Expand Down Expand Up @@ -686,17 +694,17 @@ module S3
status_code: 200,
headers: {},
body: <<-XML)
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Contents>
<Key>prefix+suffix</Key>
</Contents>
<Contents>
<Key>prefix%2Bsuffix</Key>
</Contents>
<Contents>
<Key>prefix%20suffix</Key>
</Contents>
</ListBucketResult>
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Contents>
<Key>prefix+suffix</Key>
</Contents>
<Contents>
<Key>prefix%2Bsuffix</Key>
</Contents>
<Contents>
<Key>prefix%20suffix</Key>
</Contents>
</ListBucketResult>
XML
Seahorse::Client::Response.new(context: context)
end
Expand Down Expand Up @@ -781,13 +789,13 @@ module S3
client.handle(step: :send) do |context|
context.http_response.signal_headers(200, {})
context.http_response.signal_data(<<-XML.strip)
<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>InternalError</Code>
<Message>We encountered an internal error. Please try again.</Message>
<RequestId>656c76696e6727732072657175657374</RequestId>
<HostId>Uuag1LuByRx9e6j5Onimru9pO4ZVKnJ2Qz7/C1NPcfTWAtRPfTaOFg==</HostId>
</Error>
<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>InternalError</Code>
<Message>We encountered an internal error. Please try again.</Message>
<RequestId>656c76696e6727732072657175657374</RequestId>
<HostId>Uuag1LuByRx9e6j5Onimru9pO4ZVKnJ2Qz7/C1NPcfTWAtRPfTaOFg==</HostId>
</Error>
XML
context.http_response.signal_done
Seahorse::Client::Response.new(context: context)
Expand Down