From e6332f34bca5712452d64c49cd6c85142ec3e432 Mon Sep 17 00:00:00 2001 From: Joshua Napoli Date: Sat, 9 Apr 2011 17:09:05 -0400 Subject: [PATCH 1/5] correction for item and attribute counters in encode_batch_attributes --- lib/fog/aws/simpledb.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/fog/aws/simpledb.rb b/lib/fog/aws/simpledb.rb index eea986d73..8c72b9ecd 100644 --- a/lib/fog/aws/simpledb.rb +++ b/lib/fog/aws/simpledb.rb @@ -124,8 +124,8 @@ module Fog item_index = 0 for item_key in items.keys encoded_attributes["Item.#{item_index}.ItemName"] = item_key.to_s + attribute_index = 0 for attribute_key in items[item_key].keys - attribute_index = 0 for value in Array(items[item_key][attribute_key]) encoded_attributes["Item.#{item_index}.Attribute.#{attribute_index}.Name"] = attribute_key.to_s if replace_attributes[item_key].include?(attribute_key) @@ -134,8 +134,8 @@ module Fog encoded_attributes["Item.#{item_index}.Attribute.#{attribute_index}.Value"] = sdb_encode(value) attribute_index += 1 end - item_index += 1 end + item_index += 1 end end encoded_attributes From 9f25c5c6a32d07753626c5b874dc67450d81ddfb Mon Sep 17 00:00:00 2001 From: Joshua Napoli Date: Sat, 9 Apr 2011 20:16:42 -0400 Subject: [PATCH 2/5] Fix a problem with the encoding of the tilde character. AWS needs tilde to be unescaped, or else the signature fails. CGI.escape escapes tilde; don't use it. --- lib/fog/providers/aws.rb | 6 +++++- tests/aws/signed_params_tests.rb | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 tests/aws/signed_params_tests.rb diff --git a/lib/fog/providers/aws.rb b/lib/fog/providers/aws.rb index 9e8733e09..6ce4acb0b 100644 --- a/lib/fog/providers/aws.rb +++ b/lib/fog/providers/aws.rb @@ -41,6 +41,10 @@ module Fog params end + def self.escape(string) + string.gsub( /([^a-zA-Z0-9_.-~]+)/n ) { |match| '%' + match.unpack( 'H2' * match.size ).join( '%' ).upcase } + end + def self.signed_params(params, options = {}) params.merge!({ 'AWSAccessKeyId' => options[:aws_access_key_id], @@ -53,7 +57,7 @@ module Fog body = '' for key in params.keys.sort unless (value = params[key]).nil? - body << "#{key}=#{CGI.escape(value.to_s).gsub(/\+/, '%20')}&" + body << "#{key}=#{escape(value.to_s)}&" end end string_to_sign = "POST\n#{options[:host]}:#{options[:port]}\n#{options[:path]}\n" << body.chop diff --git a/tests/aws/signed_params_tests.rb b/tests/aws/signed_params_tests.rb new file mode 100644 index 000000000..11a36f132 --- /dev/null +++ b/tests/aws/signed_params_tests.rb @@ -0,0 +1,3 @@ +Shindo.tests('AWS | signed_params', ['aws']) do + returns( Fog::AWS.escape( "'Stop!' said Fred~" ) ) { "%27Stop%21%27%20said%20Fred~" } +end From f7b457a7826e83ccd7cf064f1b95876e35fabb9a Mon Sep 17 00:00:00 2001 From: Joshua Napoli Date: Sat, 9 Apr 2011 20:36:00 -0400 Subject: [PATCH 3/5] Correction to the regular expression for unreserved characters. --- lib/fog/providers/aws.rb | 2 +- tests/aws/signed_params_tests.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/fog/providers/aws.rb b/lib/fog/providers/aws.rb index 6ce4acb0b..72e87be72 100644 --- a/lib/fog/providers/aws.rb +++ b/lib/fog/providers/aws.rb @@ -42,7 +42,7 @@ module Fog end def self.escape(string) - string.gsub( /([^a-zA-Z0-9_.-~]+)/n ) { |match| '%' + match.unpack( 'H2' * match.size ).join( '%' ).upcase } + string.gsub( /([^-a-zA-Z0-9_.~]+)/n ) { |match| '%' + match.unpack( 'H2' * match.size ).join( '%' ).upcase } end def self.signed_params(params, options = {}) diff --git a/tests/aws/signed_params_tests.rb b/tests/aws/signed_params_tests.rb index 11a36f132..24ffec3d0 100644 --- a/tests/aws/signed_params_tests.rb +++ b/tests/aws/signed_params_tests.rb @@ -1,3 +1,3 @@ Shindo.tests('AWS | signed_params', ['aws']) do - returns( Fog::AWS.escape( "'Stop!' said Fred~" ) ) { "%27Stop%21%27%20said%20Fred~" } + returns( Fog::AWS.escape( "'Stop!' said Fred_-~." ) ) { "%27Stop%21%27%20said%20Fred_-~." } end From 4e49d70de67a1fc3d1a4d25fa5f3f12d8d82c80f Mon Sep 17 00:00:00 2001 From: Joshua Napoli Date: Mon, 11 Apr 2011 19:01:29 -0400 Subject: [PATCH 4/5] Test encode_batch_attributes with two attributes in one item to demonstrate an error in encode_batch_attributes. An unmocked test run will show a "400 Bad Request" response from SimpleDB. --- tests/aws/requests/simpledb/attributes_tests.rb | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/aws/requests/simpledb/attributes_tests.rb b/tests/aws/requests/simpledb/attributes_tests.rb index e111de92a..b1e95445a 100644 --- a/tests/aws/requests/simpledb/attributes_tests.rb +++ b/tests/aws/requests/simpledb/attributes_tests.rb @@ -6,11 +6,12 @@ Shindo.tests('AWS::SimpleDB | attributes requests', ['aws']) do tests('success') do - tests("#batch_put_attributes('#{@domain_name}', { 'a' => { 'b' => 'c' }, 'x' => { 'y' => 'z' } }).body").formats(AWS::SimpleDB::Formats::BASIC) do - AWS[:sdb].batch_put_attributes(@domain_name, { 'a' => { 'b' => 'c' }, 'x' => { 'y' => 'z' } }).body + tests("#batch_put_attributes('#{@domain_name}', { 'a' => { 'b' => 'c', 'd' => 'e' }, 'x' => { 'y' => 'z' } }).body").formats(AWS::SimpleDB::Formats::BASIC) do + puts "-----batch_put_attributes-----" + AWS[:sdb].batch_put_attributes(@domain_name, { 'a' => { 'b' => 'c', 'd' => 'e' }, 'x' => { 'y' => 'z' } }).body end - tests("#get_attributes('#{@domain_name}', 'a').body['Attributes']").returns({'b' => ['c']}) do + tests("#get_attributes('#{@domain_name}', 'a').body['Attributes']").returns({'b' => ['c'], 'd' => ['e']}) do attributes = {} Fog.wait_for { attributes = AWS[:sdb].get_attributes(@domain_name, 'a').body['Attributes'] @@ -23,7 +24,7 @@ Shindo.tests('AWS::SimpleDB | attributes requests', ['aws']) do AWS[:sdb].get_attributes(@domain_name, 'notanattribute') end - tests("#select('select * from #{@domain_name}').body['Items']").returns({ 'a' => { 'b' => ['c'] }, 'x' => { 'y' => ['z'] } }) do + tests("#select('select * from #{@domain_name}').body['Items']").returns({'a' => { 'b' => ['c'], 'd' => ['e']}, 'x' => { 'y' => ['z'] } }) do pending if Fog.mocking? AWS[:sdb].select("select * from #{@domain_name}").body['Items'] end From 182ae90b5c2ec1ed5ff67d7a253b2ab4339641d1 Mon Sep 17 00:00:00 2001 From: Joshua Napoli Date: Mon, 11 Apr 2011 19:07:37 -0400 Subject: [PATCH 5/5] Remove stray debug output. --- tests/aws/requests/simpledb/attributes_tests.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/aws/requests/simpledb/attributes_tests.rb b/tests/aws/requests/simpledb/attributes_tests.rb index b1e95445a..f536b55de 100644 --- a/tests/aws/requests/simpledb/attributes_tests.rb +++ b/tests/aws/requests/simpledb/attributes_tests.rb @@ -7,7 +7,6 @@ Shindo.tests('AWS::SimpleDB | attributes requests', ['aws']) do tests('success') do tests("#batch_put_attributes('#{@domain_name}', { 'a' => { 'b' => 'c', 'd' => 'e' }, 'x' => { 'y' => 'z' } }).body").formats(AWS::SimpleDB::Formats::BASIC) do - puts "-----batch_put_attributes-----" AWS[:sdb].batch_put_attributes(@domain_name, { 'a' => { 'b' => 'c', 'd' => 'e' }, 'x' => { 'y' => 'z' } }).body end