From 64700555e3a3e32bcb200ec3ba7b2466f4965381 Mon Sep 17 00:00:00 2001 From: Frederick Cheung Date: Fri, 12 Jun 2015 21:01:24 +0100 Subject: [PATCH] Fix S3 signature v4 signing S3 implements signature v4 different from other services - it doesn't canonicalize the path --- lib/fog/aws/signaturev4.rb | 26 ++++++++++++++------------ tests/signaturev4_tests.rb | 7 +++++++ 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/lib/fog/aws/signaturev4.rb b/lib/fog/aws/signaturev4.rb index f516bf3ae..b2a8c67df 100644 --- a/lib/fog/aws/signaturev4.rb +++ b/lib/fog/aws/signaturev4.rb @@ -79,18 +79,20 @@ DATA protected def canonical_path(path) - #leading and trailing repeated slashes are collapsed, but not ones that appear elsewhere - path = path.gsub(%r{\A/+},'/').gsub(%r{/+\z},'/') - components = path.split('/',-1) - path = components.inject([]) do |acc, component| - case component - when '.' #canonicalize by removing . - when '..' then acc.pop#canonicalize by reducing .. - else - acc << component - end - acc - end.join('/') + unless @service == 's3' #S3 implements signature v4 different - paths are not canonialized + #leading and trailing repeated slashes are collapsed, but not ones that appear elsewhere + path = path.gsub(%r{\A/+},'/').gsub(%r{/+\z},'/') + components = path.split('/',-1) + path = components.inject([]) do |acc, component| + case component + when '.' #canonicalize by removing . + when '..' then acc.pop#canonicalize by reducing .. + else + acc << component + end + acc + end.join('/') + end path.empty? ? '/' : path end diff --git a/tests/signaturev4_tests.rb b/tests/signaturev4_tests.rb index c752435a3..af155cfbd 100644 --- a/tests/signaturev4_tests.rb +++ b/tests/signaturev4_tests.rb @@ -96,5 +96,12 @@ Shindo.tests('AWS | signaturev4', ['aws']) do end end + tests("s3 signer does not normalize path") do + signer=Fog::AWS::SignatureV4.new('AKIDEXAMPLE', 'wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY', 'us-east-1','s3') + returns(signer.sign({:query => {}, :headers => {'Host' => 'host.foo.com', 'Date' => 'Mon, 09 Sep 2011 23:36:00 GMT'}, :method => :get, :path => '//foo/../bar/./'}, @now)) do + 'AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/s3/aws4_request, SignedHeaders=date;host, Signature=72407ad06b8e5750360f42e8aad9f33a0be363bcfeecdcae0aea58c99709fb4a' + end + end + Fog::Time.now = ::Time.now end