Skip to content

Commit

Permalink
Update sign and transfer encoding to handle unsigned payload
Browse files Browse the repository at this point in the history
  • Loading branch information
mullermp committed Oct 6, 2023
1 parent 16a3f74 commit c6180ab
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 12 deletions.
9 changes: 7 additions & 2 deletions gems/aws-sdk-core/lib/aws-sdk-core/plugins/sign.rb
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,17 @@ def sign_event(*args)
private

def apply_authtype(context, req)
if context.operation['authtype'].eql?('v4-unsigned-body') &&
req.endpoint.scheme.eql?('https')
if unsigned_payload?(context)
req.headers['X-Amz-Content-Sha256'] ||= 'UNSIGNED-PAYLOAD'
end
end

def unsigned_payload?(context)
(context.operation['unsignedPayload'] ||
context.operation['authtype'] == 'v4-unsigned-body') &&
context.http_request.endpoint.scheme == 'https'
end

def reset_signature(req)
# in case this request is being re-signed
req.headers.delete('Authorization')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def call(context)
if requires_length?(context.operation.input)
# if size of the IO is not available but required
raise Aws::Errors::MissingContentLength.new
elsif context.operation['authtype'] == "v4-unsigned-body"
elsif unsigned_payload?(context.operation)
context.http_request.headers['Transfer-Encoding'] = 'chunked'
end
end
Expand All @@ -43,6 +43,10 @@ def requires_length?(ref)
payload.shape["requiresLength"]
end

def unsigned_payload?(operation)
operation['unsignedPayload'] ||
operation['authtype'] == "v4-unsigned-body"
end
end

handler(Handler, step: :sign)
Expand Down
41 changes: 32 additions & 9 deletions gems/aws-sdk-core/spec/aws/plugins/sign_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,16 @@ module Plugins
'name' => 'Operation',
'http' => { 'method' => 'POST', 'requestUri' => '/' },
},
'LegacyAuthStreamingOperation' => {
'name' => 'Operation',
'http' => { 'method' => 'POST', 'requestUri' => '/legacy_streaming' },
'authtype' => 'v4-unsigned-body'
},
'StreamingOperation' => {
'name' => 'Operation',
'http' => { 'method' => 'POST', 'requestUri' => '/streaming' },
'authtype' => 'v4-unsigned-body'
'auth' => ['smithy.api#sigv4'],
'unsignedPayload' => true
},
},
endpoint_rules: {
Expand All @@ -24,7 +30,7 @@ module Plugins
).const_get(:Client)

let(:region) { 'us-west-2' }
let(:auth_scheme) { {'name' => 'none'} }
let(:auth_scheme) { { 'name' => 'none' } }
let(:endpoint) { 'https://svc.amazonaws.com' }
let(:client_options) do
{
Expand Down Expand Up @@ -97,23 +103,40 @@ module Plugins
}.to raise_error(Errors::MissingCredentialsError)
end

describe 'authtype trait' do
it "uses unsigned payload for operations with 'v4-unsigned-payload' for 'authtype'" do
it 'signs payload for operations' do
resp = client.operation
req = resp.context.http_request
expect(req.headers['x-amz-content-sha256']).not_to eq('UNSIGNED-PAYLOAD')
end

describe 'unsigned payload trait' do
it "uses unsigned payload for operations with 'unsignedPayload'" do
resp = client.streaming_operation
req = resp.context.http_request
expect(req.headers['x-amz-content-sha256']).to eq('UNSIGNED-PAYLOAD')
end

it "signs payload for operations without 'v4-unsigned-payload' for 'authtype'" do
resp = client.operation
context 'http endpoint' do
let(:endpoint) { 'http://insecure.com' }
it "signs payload for HTTP request even when 'unsignedPayload' is set" do
resp = client.streaming_operation
req = resp.context.http_request
expect(req.headers['x-amz-content-sha256']).not_to eq('UNSIGNED-PAYLOAD')
end
end
end

describe 'authtype trait' do
it "uses unsigned payload for operations with 'v4-unsigned-payload' for 'authtype'" do
resp = client.legacy_auth_streaming_operation
req = resp.context.http_request
expect(req.headers['x-amz-content-sha256']).not_to eq('UNSIGNED-PAYLOAD')
expect(req.headers['x-amz-content-sha256']).to eq('UNSIGNED-PAYLOAD')
end

context 'http endpoint' do
let(:endpoint) { 'http://insecure.com' }
it "signs payload for HTTP request even when 'v4-unsigned-payload' is set" do
resp = client.streaming_operation
resp = client.legacy_auth_streaming_operation
req = resp.context.http_request
expect(req.headers['x-amz-content-sha256']).not_to eq('UNSIGNED-PAYLOAD')
end
Expand Down Expand Up @@ -192,7 +215,7 @@ module Plugins

it "uses unsigned payload for operations with 'v4-unsigned-payload' for 'authtype'" do
expect_auth(auth_scheme)
resp = client.streaming_operation
resp = client.legacy_auth_streaming_operation
req = resp.context.http_request
expect(req.headers['x-amz-content-sha256']).to eq('UNSIGNED-PAYLOAD')
end
Expand Down

0 comments on commit c6180ab

Please sign in to comment.