From 62766c9a2ce4fae36f414f76bbb88c1758004840 Mon Sep 17 00:00:00 2001 From: Trevor Rowe Date: Fri, 15 May 2015 16:09:01 -0700 Subject: [PATCH] Resolved an issue/regression with s3 presigned URLs with x-amz-* headers. Fixes #816. --- CHANGELOG.md | 7 +++++++ aws-sdk-core/features/s3/presigned.feature | 10 ++++++++++ aws-sdk-core/features/s3/step_definitions.rb | 9 +++++++-- aws-sdk-core/lib/aws-sdk-core/signers/v4.rb | 7 +++++++ 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f548fbd61ed..4cb637561a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,13 @@ Unreleased Changes ------------------ +* Issue - Resolved a regression with presigned S3 urls where input parameters + that are normally sent as x-amz-* headers had to be serialized onto the + GET or PUT request. This restores the behavior where they are hoisted + onto the request uri as query string parameters. + + See [related GitHub issue #816](https://github.com/aws/aws-sdk-ruby/pull/816) + 2.0.43 (2015-05-14) ------------------ diff --git a/aws-sdk-core/features/s3/presigned.feature b/aws-sdk-core/features/s3/presigned.feature index a3d0ff9f17b..a3f1b09bdf2 100644 --- a/aws-sdk-core/features/s3/presigned.feature +++ b/aws-sdk-core/features/s3/presigned.feature @@ -20,6 +20,16 @@ Feature: S3 Presigned Operations Then I make an unauthenticated GET request for key "test" And the response should be "hello" + Scenario: Presigning a put object request with x-amz-* + When I create a presigned url for "put_object" with: + | key | test | + | acl | public-read | + | storage_class | REDUCED_REDUNDANCY | + And I send an HTTP put request for the presigned url with body "hello" + Then the object "test" should have a "REDUCED_REDUNDANCY" storage class + Then I make an unauthenticated GET request for key "test" + And the response should be "hello" + Scenario: Presigned PUT with content-type When I create a presigned url for "put_object" with: | key | test | diff --git a/aws-sdk-core/features/s3/step_definitions.rb b/aws-sdk-core/features/s3/step_definitions.rb index 76327beeaad..26971d410f8 100644 --- a/aws-sdk-core/features/s3/step_definitions.rb +++ b/aws-sdk-core/features/s3/step_definitions.rb @@ -206,7 +206,7 @@ def create_bucket(options = {}) When(/^I send an HTTP put request for the presigned url with body "(.*?)"$/) do |body| uri = URI(@url) http = Net::HTTP.new(uri.host) - req = Net::HTTP::Put.new(uri, 'x-amz-acl' => 'public-read') + req = Net::HTTP::Put.new(uri) req.body = body @resp = http.request(req) expect(@resp.code).to eq('200') @@ -240,7 +240,7 @@ def create_bucket(options = {}) When(/^I send an HTTP put request with the content type as "(.*?)"$/) do |content_type| uri = URI(@url) http = Net::HTTP.new(uri.host) - req = Net::HTTP::Put.new(uri, 'x-amz-acl' => 'public-read', 'content-type' => content_type) + req = Net::HTTP::Put.new(uri, 'content-type' => content_type) req.body = 'data' @resp = http.request(req) end @@ -248,3 +248,8 @@ def create_bucket(options = {}) When(/^the response should have a (\d+) status code$/) do |code| expect(@resp.code).to eq(code) end + +Then(/^the object "([^"]*)" should have a "([^"]*)" storage class$/) do |key, sc| + resp = @client.list_objects(bucket: @bucket_name, prefix: key, max_keys: 1) + expect(resp.contents.first.storage_class).to eq(sc) +end diff --git a/aws-sdk-core/lib/aws-sdk-core/signers/v4.rb b/aws-sdk-core/lib/aws-sdk-core/signers/v4.rb index 0da88043438..32f7d800dd8 100644 --- a/aws-sdk-core/lib/aws-sdk-core/signers/v4.rb +++ b/aws-sdk-core/lib/aws-sdk-core/signers/v4.rb @@ -55,6 +55,13 @@ def presigned_url(request, options = {}) request.headers.delete('User-Agent') params = Aws::Query::ParamList.new + + request.headers.keys.each do |key| + if key.match(/^x-amz/i) + params.set(key, request.headers.delete(key)) + end + end + params.set("X-Amz-Algorithm", "AWS4-HMAC-SHA256") params.set("X-Amz-Credential", credential(now)) params.set("X-Amz-Date", now)