From 7d635e54aad0957fce90dc4a12de9760b0f69a08 Mon Sep 17 00:00:00 2001 From: Matt Muller Date: Sat, 2 Nov 2024 12:35:08 -0400 Subject: [PATCH] User provided checksum tests --- .../plugins/checksum_algorithm.rb | 20 +---- .../aws/plugins/checksum_algorithm_spec.rb | 67 ++++++++++++++++- .../spec/aws/plugins/checksum_provided.json | 74 +++++++++++++++++++ 3 files changed, 143 insertions(+), 18 deletions(-) create mode 100644 gems/aws-sdk-core/spec/aws/plugins/checksum_provided.json diff --git a/gems/aws-sdk-core/lib/aws-sdk-core/plugins/checksum_algorithm.rb b/gems/aws-sdk-core/lib/aws-sdk-core/plugins/checksum_algorithm.rb index 334df6d5285..da012a806c1 100644 --- a/gems/aws-sdk-core/lib/aws-sdk-core/plugins/checksum_algorithm.rb +++ b/gems/aws-sdk-core/lib/aws-sdk-core/plugins/checksum_algorithm.rb @@ -164,9 +164,6 @@ def call(context) enable_request_validation_mode(context) end - # Default checksum member to CRC32 if not set - default_request_algorithm_member(context) - @handler.call(context) end @@ -178,13 +175,6 @@ def enable_request_validation_mode(context) input_member = context.operation.http_checksum['requestValidationModeMember'] context.params[input_member.to_sym] ||= 'ENABLED' if input_member end - - def default_request_algorithm_member(context) - return unless context.operation.http_checksum - - input_member = context.operation.http_checksum['requestAlgorithmMember'] - context.params[input_member.to_sym] ||= DEFAULT_CHECKSUM if input_member - end end class ChecksumHandler < Seahorse::Client::Handler @@ -256,7 +246,7 @@ def request_algorithm_selection(context) return unless context.operation.http_checksum input_member = context.operation.http_checksum['requestAlgorithmMember'] - context.params[input_member.to_sym]&.upcase if input_member + context.params[input_member.to_sym] ||= DEFAULT_CHECKSUM if input_member end def request_validation_mode(context) @@ -288,15 +278,13 @@ def checksum_provided_as_header?(headers) end def should_calculate_request_checksum?(context) - # requestAlgorithmMember must be present on the model - guaranteed - # a default from OptionHandler - request_algorithm_selection(context) && - !checksum_provided_as_header?(context.http_request.headers) && + !checksum_provided_as_header?(context.http_request.headers) && + request_algorithm_selection(context) && (checksum_required?(context) || checksum_optional?(context)) end def choose_request_algorithm!(context) - algorithm = request_algorithm_selection(context) + algorithm = request_algorithm_selection(context).upcase return algorithm if CLIENT_ALGORITHMS.include?(algorithm) if %w[CRC32C CRC64NVME].include?(algorithm) diff --git a/gems/aws-sdk-core/spec/aws/plugins/checksum_algorithm_spec.rb b/gems/aws-sdk-core/spec/aws/plugins/checksum_algorithm_spec.rb index c24ccadef88..b8d4f651631 100644 --- a/gems/aws-sdk-core/spec/aws/plugins/checksum_algorithm_spec.rb +++ b/gems/aws-sdk-core/spec/aws/plugins/checksum_algorithm_spec.rb @@ -44,10 +44,10 @@ module Plugins }, shapes: { 'Body' => { 'type' => 'blob' }, + 'String' => { 'type' => 'string' }, 'ChecksumAlgorithm' => { 'type' => 'string', - # SHA256 intentionally unmodeled for forwards compatibility test - 'enum' => ['CRC32', 'CRC32C', 'CRC64NVME', 'SHA1'] + 'enum' => ['CRC32', 'CRC32C', 'CRC64NVME', 'SHA1', 'SHA256'] }, 'SomeInput' => { 'type' => 'structure', @@ -58,6 +58,36 @@ module Plugins 'locationName' => 'x-amz-request-algorithm' }, 'ValidationMode' => { 'shape' => 'ValidationMode' }, + 'ChecksumCRC32' => { + 'shape' => 'String', + 'location' => 'header', + 'locationName' => 'x-amz-checksum-crc32' + }, + 'ChecksumCRC32C' => { + 'shape' => 'String', + 'location' => 'header', + 'locationName' => 'x-amz-checksum-crc32c' + }, + 'ChecksumCRC64NVME' => { + 'shape' => 'String', + 'location' => 'header', + 'locationName' => 'x-amz-checksum-crc64nvme' + }, + 'ChecksumSHA1' => { + 'shape' => 'String', + 'location' => 'header', + 'locationName' => 'x-amz-checksum-sha1' + }, + 'ChecksumSHA256' => { + 'shape' => 'String', + 'location' => 'header', + 'locationName' => 'x-amz-checksum-sha256' + }, + 'ChecksumFoo' => { + 'shape' => 'String', + 'location' => 'header', + 'locationName' => 'x-amz-checksum-foo' + }, 'Body' => { 'shape' => 'Body' } }, 'payload' => 'Body' @@ -308,6 +338,39 @@ module Plugins end end + context 'checksums are provided' do + file = File.expand_path('checksum_provided.json', __dir__) + test_cases = JSON.load_file(file) + + before do + algorithms = Aws::Plugins::ChecksumAlgorithm::CLIENT_ALGORITHMS.dup + algorithms << 'FOO' + algorithms.freeze + stub_const('Aws::Plugins::ChecksumAlgorithm::CLIENT_ALGORITHMS', algorithms) + end + + test_cases.each do |test_case| + it "passes test: #{test_case['documentation']}" do + algorithm = test_case['checksumAlgorithm'].upcase + unless ChecksumAlgorithm::CLIENT_ALGORITHMS.include?(algorithm) + skip "Algorithm #{algorithm} not supported" + end + + resp = client.http_checksum_operation( + "checksum_#{algorithm.downcase}".to_sym => test_case['checksumValue'], + body: test_case['requestPayload'] + ) + headers = resp.context.http_request.headers + test_case['expectHeaders'].each do |key, value| + expect(headers[key]).to eq(value) + end + test_case['expectNotPresentHeaders'].each do |key| + expect(headers[key]).to be_nil + end + end + end + end + context 'when checksums are not required' do let(:request_checksum_required) { false } diff --git a/gems/aws-sdk-core/spec/aws/plugins/checksum_provided.json b/gems/aws-sdk-core/spec/aws/plugins/checksum_provided.json new file mode 100644 index 00000000000..59c95ef1463 --- /dev/null +++ b/gems/aws-sdk-core/spec/aws/plugins/checksum_provided.json @@ -0,0 +1,74 @@ +[ + { + "documentation": "CRC32 checksum provided by user.", + "requestPayload": "Hello world", + "checksumAlgorithm": "Crc32", + "checksumValue": "i9aeUg==", + "expectHeaders": { + "x-amz-checksum-crc32": "i9aeUg==" + }, + "expectNotPresentHeaders": [ + "x-amz-request-algorithm" + ] + }, + { + "documentation": "CRC32C checksum provided by user.", + "requestPayload": "Hello world", + "checksumAlgorithm": "Crc32C", + "checksumValue": "crUfeA==", + "expectHeaders": { + "x-amz-checksum-crc32c": "crUfeA==" + }, + "expectNotPresentHeaders": [ + "x-amz-request-algorithm" + ] + }, + { + "documentation": "CRC64NVME checksum provided by user.", + "requestPayload": "Hello world", + "checksumAlgorithm": "Crc64Nvme", + "checksumValue": "OOJZ0D8xKts=", + "expectHeaders": { + "x-amz-checksum-crc64nvme": "OOJZ0D8xKts=" + }, + "expectNotPresentHeaders": [ + "x-amz-request-algorithm" + ] + }, + { + "documentation": "SHA1 checksum provided by user.", + "requestPayload": "Hello world", + "checksumAlgorithm": "Sha1", + "checksumValue": "e1AsOh9IyGCa4hLN+2Od7jlnP14=", + "expectHeaders": { + "x-amz-checksum-sha1": "e1AsOh9IyGCa4hLN+2Od7jlnP14=" + }, + "expectNotPresentHeaders": [ + "x-amz-request-algorithm" + ] + }, + { + "documentation": "SHA256 checksum provided by user.", + "requestPayload": "Hello world", + "checksumAlgorithm": "Sha256", + "checksumValue": "ZOyIygCyaOW6GjVnihtTFtIS9PNmskdyMlNKiuyjfzw=", + "expectHeaders": { + "x-amz-checksum-sha256": "ZOyIygCyaOW6GjVnihtTFtIS9PNmskdyMlNKiuyjfzw=" + }, + "expectNotPresentHeaders": [ + "x-amz-request-algorithm" + ] + }, + { + "documentation": "Unsupported checksum provided by user.", + "requestPayload": "Hello world", + "checksumAlgorithm": "Foo", + "checksumValue": "This-is-not-a-real-checksum", + "expectHeaders": { + "x-amz-checksum-foo": "This-is-not-a-real-checksum" + }, + "expectNotPresentHeaders": [ + "x-amz-request-algorithm" + ] + } +] \ No newline at end of file