diff --git a/gems/aws-sdk-core/CHANGELOG.md b/gems/aws-sdk-core/CHANGELOG.md index 71da2daa54d..d7f9ecc60c6 100644 --- a/gems/aws-sdk-core/CHANGELOG.md +++ b/gems/aws-sdk-core/CHANGELOG.md @@ -1,9 +1,9 @@ Unreleased Changes ------------------ -* Feature - Always calculate checksums for operations that support or require it. Supported config options are `WHEN_SUPPORTED` and `WHEN_REQUIRED`. The default value is `WHEN_SUPPORTED`. This option is configured in code with `:request_checksum_calculation`, in the shared config file as `request_checksum_calculation`, and in the ENV as `ENV['AWS_REQUEST_CHECKSUM_CALCULATION']`. +* Feature - Always calculate request checksums for operations that support or require it. Supported config options are `WHEN_SUPPORTED` and `WHEN_REQUIRED`. The default value is `WHEN_SUPPORTED`. This option is configured in code with `:request_checksum_calculation`, in the shared config file as `request_checksum_calculation`, and in the ENV as `ENV['AWS_REQUEST_CHECKSUM_CALCULATION']`. -* Feature - Always validate checksums for operations that support or require it. Supported config options are `WHEN_SUPPORTED` and `WHEN_REQUIRED`. The default value is `WHEN_SUPPORTED`. This option is configured in code with `:response_checksum_calculation`, in the shared config file as `response_checksum_calculation`, and in the ENV as `ENV['AWS_RESPONSE_CHECKSUM_CALCULATION']`. +* Feature - Always validate response checksums for operations that support or require it. Supported config options are `WHEN_SUPPORTED` and `WHEN_REQUIRED`. The default value is `WHEN_SUPPORTED`. This option is configured in code with `:response_checksum_calculation`, in the shared config file as `response_checksum_calculation`, and in the ENV as `ENV['AWS_RESPONSE_CHECKSUM_CALCULATION']`. 3.201.5 (2024-08-15) ------------------ 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 a9406badefe..4997e9189b8 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 @@ -157,17 +157,13 @@ def add_handlers(handlers, _config) class OptionHandler < Seahorse::Client::Handler def call(context) - # Enable validation on the service in all cases + # Set validation mode to enabled when supported. if context.config.response_checksum_calculation == 'WHEN_SUPPORTED' enable_request_validation_mode(context) end # Default checksum member to CRC32 if not set default_request_algorithm_member(context) - # Not modeled with httpChecksum - if context.operation_name == :create_multipart_upload - context.params[:checksum_algorithm] ||= DEFAULT_CHECKSUM - end @handler.call(context) end @@ -178,21 +174,20 @@ def enable_request_validation_mode(context) return unless context.operation.http_checksum input_member = context.operation.http_checksum['requestValidationModeMember'] - context.params[input_member.to_sym] = 'ENABLED' if input_member + 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] ||= 'CRC32' if input_member + context.params[input_member.to_sym] ||= DEFAULT_CHECKSUM if input_member end end class ChecksumHandler < Seahorse::Client::Handler def call(context) - context[:http_checksum] ||= {} - + algorithm = nil if should_calculate_request_checksum?(context) algorithm = choose_request_algorithm!(context) request_algorithm = { @@ -201,6 +196,7 @@ def call(context) name: "x-amz-checksum-#{algorithm.downcase}" } + context[:http_checksum] ||= {} context[:http_checksum][:request_algorithm] = request_algorithm calculate_request_checksum(context, request_algorithm) end @@ -209,11 +205,56 @@ def call(context) add_verify_response_checksum_handlers(context) end - @handler.call(context) + with_request_config_metric(context.config) do + with_response_config_metric(context.config) do + with_request_checksum_metrics(algorithm) do + @handler.call(context) + end + end + end end private + def with_request_config_metric(config, &block) + case config.request_checksum_calculation + when 'WHEN_SUPPORTED' + Aws::Plugins::UserAgent.metric('FLEXIBLE_CHECKSUMS_REQ_WHEN_SUPPORTED', &block) + when 'WHEN_REQUIRED' + Aws::Plugins::UserAgent.metric('FLEXIBLE_CHECKSUMS_REQ_WHEN_REQUIRED', &block) + else + block.call + end + end + + def with_response_config_metric(config, &block) + case config.response_checksum_calculation + when 'WHEN_SUPPORTED' + Aws::Plugins::UserAgent.metric('FLEXIBLE_CHECKSUMS_RES_WHEN_SUPPORTED', &block) + when 'WHEN_REQUIRED' + Aws::Plugins::UserAgent.metric('FLEXIBLE_CHECKSUMS_RES_WHEN_REQUIRED', &block) + else + block.call + end + end + + def with_request_checksum_metrics(algorithm, &block) + case algorithm + when 'CRC32' + Aws::Plugins::UserAgent.metric('FLEXIBLE_CHECKSUMS_REQ_CRC32', &block) + when 'CRC32C' + Aws::Plugins::UserAgent.metric('FLEXIBLE_CHECKSUMS_REQ_CRC32C', &block) + when 'CRC64NVME' + Aws::Plugins::UserAgent.metric('FLEXIBLE_CHECKSUMS_REQ_CRC64', &block) + when 'SHA1' + Aws::Plugins::UserAgent.metric('FLEXIBLE_CHECKSUMS_REQ_SHA1', &block) + when 'SHA256' + Aws::Plugins::UserAgent.metric('FLEXIBLE_CHECKSUMS_REQ_SHA256', &block) + else + block.call + end + end + def request_algorithm_selection(context) return unless context.operation.http_checksum diff --git a/gems/aws-sdk-core/lib/aws-sdk-core/plugins/user_agent.rb b/gems/aws-sdk-core/lib/aws-sdk-core/plugins/user_agent.rb index df7d94e1bd4..81db50643fa 100644 --- a/gems/aws-sdk-core/lib/aws-sdk-core/plugins/user_agent.rb +++ b/gems/aws-sdk-core/lib/aws-sdk-core/plugins/user_agent.rb @@ -17,7 +17,24 @@ class UserAgent < Seahorse::Client::Plugin "S3_CRYPTO_V2": "I", "S3_EXPRESS_BUCKET": "J", "S3_ACCESS_GRANTS": "K", - "GZIP_REQUEST_COMPRESSION": "L" + "GZIP_REQUEST_COMPRESSION": "L", + "PROTOCOL_RPC_V2_CBOR": "M", + "ENDPOINT_OVERRIDE": "N", + "ACCOUNT_ID_ENDPOINT": "O", + "ACCOUNT_ID_MODE_PREFERRED": "P", + "ACCOUNT_ID_MODE_DISABLED": "Q", + "ACCOUNT_ID_MODE_REQUIRED": "R", + "SIGV4A_SIGNING": "S", + "RESOLVED_ACCOUNT_ID": "T", + "FLEXIBLE_CHECKSUMS_REQ_CRC32" : "U", + "FLEXIBLE_CHECKSUMS_REQ_CRC32C" : "V", + "FLEXIBLE_CHECKSUMS_REQ_CRC64" : "W", + "FLEXIBLE_CHECKSUMS_REQ_SHA1" : "X", + "FLEXIBLE_CHECKSUMS_REQ_SHA256" : "Y", + "FLEXIBLE_CHECKSUMS_REQ_WHEN_SUPPORTED" : "Z", + "FLEXIBLE_CHECKSUMS_REQ_WHEN_REQUIRED" : "a", + "FLEXIBLE_CHECKSUMS_RES_WHEN_SUPPORTED" : "b", + "FLEXIBLE_CHECKSUMS_RES_WHEN_REQUIRED" : "c" } METRICS diff --git a/gems/aws-sdk-s3/lib/aws-sdk-s3/plugins/checksum_algorithm.rb b/gems/aws-sdk-s3/lib/aws-sdk-s3/plugins/checksum_algorithm.rb new file mode 100644 index 00000000000..15116c6e11e --- /dev/null +++ b/gems/aws-sdk-s3/lib/aws-sdk-s3/plugins/checksum_algorithm.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +module Aws + module S3 + module Plugins + # @api private + class ChecksumAlgorithm < Seahorse::Client::Plugin + + # S3 GetObject results for whole Multipart Objects contain a checksum + # that cannot be validated. These should be skipped by the + # ChecksumAlgorithm plugin. + class SkipWholeMultipartGetChecksumsHandler < Seahorse::Client::Handler + def call(context) + context[:http_checksum] ||= {} + context[:http_checksum][:skip_on_suffix] = true + + @handler.call(context) + end + end + + # create_multipart_upload is not modeled with httpChecksum. For + # multipart requests, we must set a default for the checksum algorithm + # for it to f unction. + class DefaultMultipartChecksumHandler < Seahorse::Client::Handler + def call(context) + default = Aws::Plugins::ChecksumAlgorithm::DEFAULT_CHECKSUM + context.params[:checksum_algorithm] ||= default + @handler.call(context) + end + end + + def add_handlers(handlers, _config) + handlers.add( + SkipWholeMultipartGetChecksumsHandler, + step: :initialize, + operations: [:get_object] + ) + + handlers.add( + DefaultMultipartChecksumHandler, + step: :initialize, + operations: [:create_multipart_upload] + ) + end + end + end + end +end diff --git a/gems/aws-sdk-s3/lib/aws-sdk-s3/plugins/skip_whole_multipart_get_checksums.rb b/gems/aws-sdk-s3/lib/aws-sdk-s3/plugins/skip_whole_multipart_get_checksums.rb deleted file mode 100644 index 4d274bcff42..00000000000 --- a/gems/aws-sdk-s3/lib/aws-sdk-s3/plugins/skip_whole_multipart_get_checksums.rb +++ /dev/null @@ -1,31 +0,0 @@ -# frozen_string_literal: true - -module Aws - module S3 - module Plugins - - # S3 GetObject results for whole Multipart Objects contain a checksum - # that cannot be validated. These should be skipped by the - # ChecksumAlgorithm plugin. - class SkipWholeMultipartGetChecksums < Seahorse::Client::Plugin - - class Handler < Seahorse::Client::Handler - - def call(context) - context[:http_checksum] ||= {} - context[:http_checksum][:skip_on_suffix] = true - - @handler.call(context) - end - - end - - handler( - Handler, - step: :initialize, - operations: [:get_object] - ) - end - end - end -end diff --git a/services.json b/services.json index 27ec3954203..a994fb928a6 100644 --- a/services.json +++ b/services.json @@ -1010,6 +1010,7 @@ "Aws::S3::Plugins::ARN", "Aws::S3::Plugins::BucketDns", "Aws::S3::Plugins::BucketNameRestrictions", + "Aws::S3::Plugins::ChecksumAlgorithm", "Aws::S3::Plugins::Dualstack", "Aws::S3::Plugins::Expect100Continue", "Aws::S3::Plugins::ExpressSessionAuth", @@ -1022,7 +1023,6 @@ "Aws::S3::Plugins::S3HostId", "Aws::S3::Plugins::S3Signer", "Aws::S3::Plugins::SseCpk", - "Aws::S3::Plugins::SkipWholeMultipartGetChecksums", "Aws::S3::Plugins::StreamingRetry", "Aws::S3::Plugins::UrlEncodedKeys" ]