aws-sdk-core 3.131.1 → 3.168.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +244 -0
  3. data/VERSION +1 -1
  4. data/lib/aws-sdk-core/arn.rb +13 -0
  5. data/lib/aws-sdk-core/binary/encode_handler.rb +12 -1
  6. data/lib/aws-sdk-core/endpoints/condition.rb +36 -0
  7. data/lib/aws-sdk-core/endpoints/endpoint.rb +17 -0
  8. data/lib/aws-sdk-core/endpoints/endpoint_rule.rb +71 -0
  9. data/lib/aws-sdk-core/endpoints/error_rule.rb +37 -0
  10. data/lib/aws-sdk-core/endpoints/function.rb +75 -0
  11. data/lib/aws-sdk-core/endpoints/matchers.rb +127 -0
  12. data/lib/aws-sdk-core/endpoints/reference.rb +26 -0
  13. data/lib/aws-sdk-core/endpoints/rule.rb +20 -0
  14. data/lib/aws-sdk-core/endpoints/rule_set.rb +47 -0
  15. data/lib/aws-sdk-core/endpoints/rules_provider.rb +32 -0
  16. data/lib/aws-sdk-core/endpoints/templater.rb +52 -0
  17. data/lib/aws-sdk-core/endpoints/tree_rule.rb +40 -0
  18. data/lib/aws-sdk-core/endpoints/url.rb +59 -0
  19. data/lib/aws-sdk-core/endpoints.rb +74 -0
  20. data/lib/aws-sdk-core/errors.rb +13 -0
  21. data/lib/aws-sdk-core/json/error_handler.rb +10 -1
  22. data/lib/aws-sdk-core/pageable_response.rb +7 -0
  23. data/lib/aws-sdk-core/plugins/bearer_authorization.rb +67 -0
  24. data/lib/aws-sdk-core/plugins/credentials_configuration.rb +24 -0
  25. data/lib/aws-sdk-core/plugins/endpoint_discovery.rb +6 -2
  26. data/lib/aws-sdk-core/plugins/jsonvalue_converter.rb +34 -6
  27. data/lib/aws-sdk-core/plugins/recursion_detection.rb +14 -3
  28. data/lib/aws-sdk-core/plugins/regional_endpoint.rb +5 -0
  29. data/lib/aws-sdk-core/plugins/sign.rb +190 -0
  30. data/lib/aws-sdk-core/plugins/signature_v2.rb +1 -0
  31. data/lib/aws-sdk-core/plugins/signature_v4.rb +13 -7
  32. data/lib/aws-sdk-core/refreshing_token.rb +71 -0
  33. data/lib/aws-sdk-core/rest/handler.rb +1 -1
  34. data/lib/aws-sdk-core/rest/request/headers.rb +2 -6
  35. data/lib/aws-sdk-core/shared_config.rb +76 -5
  36. data/lib/aws-sdk-core/sso_credentials.rb +79 -44
  37. data/lib/aws-sdk-core/sso_token_provider.rb +135 -0
  38. data/lib/aws-sdk-core/static_token_provider.rb +14 -0
  39. data/lib/aws-sdk-core/structure.rb +6 -4
  40. data/lib/aws-sdk-core/token.rb +31 -0
  41. data/lib/aws-sdk-core/token_provider.rb +15 -0
  42. data/lib/aws-sdk-core/token_provider_chain.rb +51 -0
  43. data/lib/aws-sdk-core/xml/error_handler.rb +7 -0
  44. data/lib/aws-sdk-core.rb +14 -0
  45. data/lib/aws-sdk-sso/client.rb +51 -11
  46. data/lib/aws-sdk-sso/endpoint_parameters.rb +66 -0
  47. data/lib/aws-sdk-sso/endpoint_provider.rb +112 -0
  48. data/lib/aws-sdk-sso/endpoints.rb +71 -0
  49. data/lib/aws-sdk-sso/plugins/endpoints.rb +76 -0
  50. data/lib/aws-sdk-sso/types.rb +8 -8
  51. data/lib/aws-sdk-sso.rb +5 -1
  52. data/lib/aws-sdk-ssooidc/client.rb +606 -0
  53. data/lib/aws-sdk-ssooidc/client_api.rb +216 -0
  54. data/lib/aws-sdk-ssooidc/customizations.rb +1 -0
  55. data/lib/aws-sdk-ssooidc/endpoint_parameters.rb +66 -0
  56. data/lib/aws-sdk-ssooidc/endpoint_provider.rb +111 -0
  57. data/lib/aws-sdk-ssooidc/endpoints.rb +57 -0
  58. data/lib/aws-sdk-ssooidc/errors.rb +290 -0
  59. data/lib/aws-sdk-ssooidc/plugins/endpoints.rb +74 -0
  60. data/lib/aws-sdk-ssooidc/resource.rb +26 -0
  61. data/lib/aws-sdk-ssooidc/types.rb +534 -0
  62. data/lib/aws-sdk-ssooidc.rb +59 -0
  63. data/lib/aws-sdk-sts/client.rb +141 -124
  64. data/lib/aws-sdk-sts/endpoint_parameters.rb +78 -0
  65. data/lib/aws-sdk-sts/endpoint_provider.rb +229 -0
  66. data/lib/aws-sdk-sts/endpoints.rb +135 -0
  67. data/lib/aws-sdk-sts/plugins/endpoints.rb +84 -0
  68. data/lib/aws-sdk-sts/presigner.rb +13 -15
  69. data/lib/aws-sdk-sts/types.rb +79 -69
  70. data/lib/aws-sdk-sts.rb +5 -1
  71. data/lib/seahorse/client/async_base.rb +0 -1
  72. data/lib/seahorse/client/configuration.rb +2 -2
  73. data/lib/seahorse/client/h2/connection.rb +2 -5
  74. data/lib/seahorse/client/plugins/request_callback.rb +9 -9
  75. data/lib/seahorse/util.rb +4 -0
  76. metadata +47 -6
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module Endpoints
5
+ # @api private
6
+ class Rule
7
+ # Resolves a value that is a function, reference, or template string.
8
+ def resolve_value(value, parameters, assigns)
9
+ if value.is_a?(Hash) && value['fn']
10
+ Function.new(fn: value['fn'], argv: value['argv'])
11
+ .call(parameters, assigns)
12
+ elsif value.is_a?(Hash) && value['ref']
13
+ Reference.new(ref: value['ref']).resolve(parameters, assigns)
14
+ else
15
+ Templater.resolve(value, parameters, assigns)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module Endpoints
5
+ # @api private
6
+ class RuleSet
7
+ def initialize(version:, service_id:, parameters:, rules:)
8
+ @version = version
9
+ @service_id = service_id
10
+ @parameters = parameters
11
+ @rules = RuleSet.rules_from_json(rules || [])
12
+ end
13
+
14
+ attr_reader :version
15
+ attr_reader :service_id
16
+ attr_reader :parameters
17
+ attr_reader :rules
18
+
19
+ def self.rules_from_json(rules_json)
20
+ rules_json.each.with_object([]) do |rule, rules|
21
+ if rule['type'] == 'endpoint'
22
+ rules << EndpointRule.new(
23
+ conditions: rule['conditions'],
24
+ endpoint: rule['endpoint'],
25
+ documentation: rule['documentation']
26
+ )
27
+ elsif rule['type'] == 'error'
28
+ rules << ErrorRule.new(
29
+ conditions: rule['conditions'],
30
+ error: rule['error'],
31
+ documentation: rule['documentation']
32
+ )
33
+ elsif rule['type'] == 'tree'
34
+ rules << TreeRule.new(
35
+ conditions: rule['conditions'],
36
+ rules: rule['rules'],
37
+ documentation: rule['documentation']
38
+ )
39
+ else
40
+ # should not happen
41
+ raise "Unknown endpoint rule type: #{rule}"
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,32 @@
1
+ module Aws
2
+ module Endpoints
3
+ # @api private
4
+ class RulesProvider
5
+ def initialize(rule_set)
6
+ @rule_set = rule_set
7
+ end
8
+
9
+ def resolve_endpoint(parameters)
10
+ obj = resolve_rules(parameters)
11
+ case obj
12
+ when Endpoint
13
+ obj
14
+ when ArgumentError
15
+ raise obj
16
+ else
17
+ raise ArgumentError, 'No endpoint could be resolved'
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def resolve_rules(parameters)
24
+ @rule_set.rules.each do |rule|
25
+ output = rule.match(parameters)
26
+ return output if output
27
+ end
28
+ nil
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module Endpoints
5
+ # Does substitutions for templated endpoint strings
6
+ # @api private
7
+ module Templater
8
+ class << self
9
+ def resolve(string, parameters, assigns)
10
+ # scans for strings in curly brackets {}
11
+ string.scan(/\{.+?\}/).each do |capture|
12
+ value = capture[1..-2] # strips curly brackets
13
+ string = string.gsub(capture, replace(value, parameters, assigns))
14
+ end
15
+ string
16
+ end
17
+
18
+ private
19
+
20
+ # Replaces the captured value with values from parameters or assign
21
+ def replace(capture, parameters, assigns)
22
+ # Pound sigil is used for getAttr calls
23
+ indexes = capture.split('#')
24
+
25
+ # no sigil found, just do substitution
26
+ if indexes.size == 1
27
+ extract_value(capture, parameters, assigns)
28
+ # sigil was found, need to call getAttr
29
+ elsif indexes.size == 2
30
+ ref, property = indexes
31
+ param = extract_value(ref, parameters, assigns)
32
+ Matchers.attr(param, property)
33
+ else
34
+ raise "Invalid templatable value: #{capture}"
35
+ end
36
+ end
37
+
38
+ # Checks both parameters and assigns hash for the referenced value
39
+ def extract_value(key, parameters, assigns)
40
+ if assigns.key?(key)
41
+ assigns[key]
42
+ elsif parameters.class.singleton_class::PARAM_MAP.key?(key)
43
+ member_name = parameters.class.singleton_class::PARAM_MAP[key]
44
+ parameters[member_name]
45
+ else
46
+ raise "Templatable value not found: #{key}"
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module Endpoints
5
+ # @api private
6
+ class TreeRule
7
+ def initialize(type: 'tree', conditions:, rules:, documentation: nil)
8
+ @type = type
9
+ @conditions = Condition.from_json(conditions)
10
+ @rules = RuleSet.rules_from_json(rules)
11
+ @documentation = documentation
12
+ end
13
+
14
+ attr_reader :type
15
+ attr_reader :conditions
16
+ attr_reader :error
17
+ attr_reader :documentation
18
+
19
+ def match(parameters, assigned = {})
20
+ assigns = assigned.dup
21
+ matched = conditions.all? do |condition|
22
+ output = condition.match?(parameters, assigns)
23
+ assigns = assigns.merge(condition.assigned) if condition.assign
24
+ output
25
+ end
26
+ resolve_rules(parameters, assigns) if matched
27
+ end
28
+
29
+ private
30
+
31
+ def resolve_rules(parameters, assigns)
32
+ @rules.each do |rule|
33
+ output = rule.match(parameters, assigns)
34
+ return output if output
35
+ end
36
+ nil
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ipaddr'
4
+
5
+ module Aws
6
+ module Endpoints
7
+ # @api private
8
+ class URL
9
+ def initialize(url)
10
+ uri = URI(url)
11
+ @scheme = uri.scheme
12
+ # only support http and https schemes
13
+ raise ArgumentError unless %w[https http].include?(@scheme)
14
+
15
+ # do not support query
16
+ raise ArgumentError if uri.query
17
+
18
+ @authority = _authority(url, uri)
19
+ @path = uri.path
20
+ @normalized_path = uri.path + (uri.path[-1] == '/' ? '' : '/')
21
+ @is_ip = _is_ip(uri.host)
22
+ end
23
+
24
+ attr_reader :scheme
25
+ attr_reader :authority
26
+ attr_reader :path
27
+ attr_reader :normalized_path
28
+ attr_reader :is_ip
29
+
30
+ def as_json(_options = {})
31
+ {
32
+ 'scheme' => scheme,
33
+ 'authority' => authority,
34
+ 'path' => path,
35
+ 'normalizedPath' => normalized_path,
36
+ 'isIp' => is_ip
37
+ }
38
+ end
39
+
40
+ private
41
+
42
+ def _authority(url, uri)
43
+ # don't include port if it's default and not parsed originally
44
+ if uri.default_port == uri.port && !url.include?(":#{uri.port}")
45
+ uri.host
46
+ else
47
+ "#{uri.host}:#{uri.port}"
48
+ end
49
+ end
50
+
51
+ def _is_ip(authority)
52
+ IPAddr.new(authority)
53
+ true
54
+ rescue IPAddr::InvalidAddressError
55
+ false
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'endpoints/rule'
4
+ require_relative 'endpoints/condition'
5
+ require_relative 'endpoints/endpoint_rule'
6
+ require_relative 'endpoints/endpoint'
7
+ require_relative 'endpoints/error_rule'
8
+ require_relative 'endpoints/function'
9
+ require_relative 'endpoints/matchers'
10
+ require_relative 'endpoints/reference'
11
+ require_relative 'endpoints/rules_provider'
12
+ require_relative 'endpoints/rule_set'
13
+ require_relative 'endpoints/templater'
14
+ require_relative 'endpoints/tree_rule'
15
+ require_relative 'endpoints/url'
16
+
17
+ module Aws
18
+ # @api private
19
+ module Endpoints
20
+ class << self
21
+ def resolve_auth_scheme(context, endpoint)
22
+ if endpoint && (auth_schemes = endpoint.properties['authSchemes'])
23
+ auth_scheme = auth_schemes.find do |scheme|
24
+ Aws::Plugins::Sign::SUPPORTED_AUTH_TYPES.include?(scheme['name'])
25
+ end
26
+ raise 'No supported auth scheme for this endpoint.' unless auth_scheme
27
+
28
+ merge_signing_defaults(auth_scheme, context.config)
29
+ else
30
+ default_auth_scheme(context)
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def default_auth_scheme(context)
37
+ case default_api_authtype(context)
38
+ when 'v4', 'v4-unsigned-body'
39
+ auth_scheme = { 'name' => 'sigv4' }
40
+ merge_signing_defaults(auth_scheme, context.config)
41
+ when 's3', 's3v4'
42
+ auth_scheme = { 'name' => 'sigv4', 'disableDoubleEncoding' => true }
43
+ merge_signing_defaults(auth_scheme, context.config)
44
+ when 'bearer'
45
+ { 'name' => 'bearer' }
46
+ when 'none', nil
47
+ { 'name' => 'none' }
48
+ end
49
+ end
50
+
51
+ def merge_signing_defaults(auth_scheme, config)
52
+ if %w[sigv4 sigv4a].include?(auth_scheme['name'])
53
+ auth_scheme['signingName'] ||= sigv4_name(config)
54
+ if auth_scheme['name'] == 'sigv4a'
55
+ auth_scheme['signingRegionSet'] ||= ['*']
56
+ else
57
+ auth_scheme['signingRegion'] ||= config.region
58
+ end
59
+ end
60
+ auth_scheme
61
+ end
62
+
63
+ def default_api_authtype(context)
64
+ context.config.api.operation(context.operation_name)['authtype'] ||
65
+ context.config.api.metadata['signatureVersion']
66
+ end
67
+
68
+ def sigv4_name(config)
69
+ config.api.metadata['signingName'] ||
70
+ config.api.metadata['endpointPrefix']
71
+ end
72
+ end
73
+ end
74
+ end
@@ -210,6 +210,19 @@ module Aws
210
210
  # Raised when SSO Credentials are invalid
211
211
  class InvalidSSOCredentials < RuntimeError; end
212
212
 
213
+ # Raised when SSO Token is invalid
214
+ class InvalidSSOToken < RuntimeError; end
215
+
216
+ # Raised when a client is unable to sign a request because
217
+ # the bearer token is not configured or available
218
+ class MissingBearerTokenError < RuntimeError
219
+ def initialize(*args)
220
+ msg = 'unable to sign request without token set'
221
+ super(msg)
222
+ end
223
+ end
224
+
225
+
213
226
  # Raised when there is a circular reference in chained
214
227
  # source_profiles
215
228
  class SourceProfileCircularReferenceError < RuntimeError; end
@@ -26,7 +26,11 @@ module Aws
26
26
  end
27
27
 
28
28
  def error_code(json, context)
29
- code = json['__type']
29
+ code = if aws_query_error?(context)
30
+ context.http_response.headers['x-amzn-query-error'].split(';')[0]
31
+ else
32
+ json['__type']
33
+ end
30
34
  code ||= json['code']
31
35
  code ||= context.http_response.headers['x-amzn-errortype']
32
36
  if code
@@ -36,6 +40,11 @@ module Aws
36
40
  end
37
41
  end
38
42
 
43
+ def aws_query_error?(context)
44
+ context.config.api.metadata['awsQueryCompatible'] &&
45
+ context.http_response.headers['x-amzn-query-error']
46
+ end
47
+
39
48
  def error_message(code, json)
40
49
  if code == 'RequestEntityTooLarge'
41
50
  'Request body must be less than 1 MB'
@@ -146,6 +146,13 @@ module Aws
146
146
  data.to_h
147
147
  end
148
148
 
149
+ def as_json(_options = {})
150
+ data.to_h(data, as_json: true)
151
+ end
152
+
153
+ def to_json(options = {})
154
+ as_json.to_json(options)
155
+ end
149
156
  end
150
157
 
151
158
  # The actual decorator module implementation. It is in a distinct module
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ # @api private
5
+ module Plugins
6
+ # @api private
7
+ class BearerAuthorization < Seahorse::Client::Plugin
8
+
9
+ option(:token_provider,
10
+ required: false,
11
+ doc_type: 'Aws::TokenProvider',
12
+ docstring: <<-DOCS
13
+ A Bearer Token Provider. This can be an instance of any one of the
14
+ following classes:
15
+
16
+ * `Aws::StaticTokenProvider` - Used for configuring static, non-refreshing
17
+ tokens.
18
+
19
+ * `Aws::SSOTokenProvider` - Used for loading tokens from AWS SSO using an
20
+ access token generated from `aws login`.
21
+
22
+ When `:token_provider` is not configured directly, the `Aws::TokenProviderChain`
23
+ will be used to search for tokens configured for your profile in shared configuration files.
24
+ DOCS
25
+ ) do |config|
26
+ if config.stub_responses
27
+ StaticTokenProvider.new('token')
28
+ else
29
+ TokenProviderChain.new(config).resolve
30
+ end
31
+ end
32
+
33
+
34
+ def add_handlers(handlers, cfg)
35
+ bearer_operations =
36
+ if cfg.api.metadata['signatureVersion'] == 'bearer'
37
+ # select operations where authtype is either not set or is bearer
38
+ cfg.api.operation_names.select do |o|
39
+ !cfg.api.operation(o)['authtype'] || cfg.api.operation(o)['authtype'] == 'bearer'
40
+ end
41
+ else # service is not bearer auth
42
+ # select only operations where authtype is explicitly bearer
43
+ cfg.api.operation_names.select do |o|
44
+ cfg.api.operation(o)['authtype'] == 'bearer'
45
+ end
46
+ end
47
+ handlers.add(Handler, step: :sign, operations: bearer_operations)
48
+ end
49
+
50
+ class Handler < Seahorse::Client::Handler
51
+ def call(context)
52
+ if context.http_request.endpoint.scheme != 'https'
53
+ raise ArgumentError, 'Unable to use bearer authorization on non https endpoint.'
54
+ end
55
+
56
+ token_provider = context.config.token_provider
57
+ if token_provider && token_provider.set?
58
+ context.http_request.headers['Authorization'] = "Bearer #{token_provider.token.token}"
59
+ else
60
+ raise Errors::MissingBearerTokenError
61
+ end
62
+ @handler.call(context)
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -76,6 +76,30 @@ locations will be searched for credentials:
76
76
 
77
77
  option(:instance_profile_credentials_timeout, 1)
78
78
 
79
+ option(:token_provider,
80
+ required: false,
81
+ doc_type: 'Aws::TokenProvider',
82
+ docstring: <<-DOCS
83
+ A Bearer Token Provider. This can be an instance of any one of the
84
+ following classes:
85
+
86
+ * `Aws::StaticTokenProvider` - Used for configuring static, non-refreshing
87
+ tokens.
88
+
89
+ * `Aws::SSOTokenProvider` - Used for loading tokens from AWS SSO using an
90
+ access token generated from `aws login`.
91
+
92
+ When `:token_provider` is not configured directly, the `Aws::TokenProviderChain`
93
+ will be used to search for tokens configured for your profile in shared configuration files.
94
+ DOCS
95
+ ) do |config|
96
+ if config.stub_responses
97
+ StaticTokenProvider.new('token')
98
+ else
99
+ TokenProviderChain.new(config).resolve
100
+ end
101
+ end
102
+
79
103
  end
80
104
  end
81
105
  end
@@ -72,7 +72,11 @@ the background every 60 secs (default). Defaults to `false`.
72
72
  context,
73
73
  Aws::Util.str_2_bool(discovery_cfg["required"])
74
74
  )
75
- context.http_request.endpoint = _valid_uri(endpoint.address) if endpoint
75
+ if endpoint
76
+ context.http_request.endpoint = _valid_uri(endpoint.address)
77
+ # Skips dynamic endpoint usage, use this endpoint instead
78
+ context[:discovered_endpoint] = true
79
+ end
76
80
  if endpoint || context.config.endpoint_discovery
77
81
  _apply_endpoint_discovery_user_agent(context)
78
82
  end
@@ -100,7 +104,7 @@ the background every 60 secs (default). Defaults to `false`.
100
104
  end
101
105
 
102
106
  def _discover_endpoint(ctx, required)
103
- cache = ctx.config.endpoint_cache
107
+ cache = ctx.config.endpoint_cache
104
108
  key = cache.extract_key(ctx)
105
109
 
106
110
  if required
@@ -11,15 +11,43 @@ module Aws
11
11
 
12
12
  def call(context)
13
13
  context.operation.input.shape.members.each do |m, ref|
14
- if ref['jsonvalue']
15
- param_value = context.params[m]
16
- unless param_value.respond_to?(:to_json)
17
- raise ArgumentError, "The value of params[#{m}] is not JSON serializable."
14
+ convert_jsonvalue(m, ref, context.params, 'params')
15
+ end
16
+ @handler.call(context)
17
+ end
18
+
19
+ def convert_jsonvalue(m, ref, params, context)
20
+ return if params.nil? || !params.key?(m)
21
+
22
+ if ref['jsonvalue']
23
+ params[m] = serialize_jsonvalue(params[m], "#{context}[#{m}]")
24
+ else
25
+ case ref.shape
26
+ when Seahorse::Model::Shapes::StructureShape
27
+ ref.shape.members.each do |member_m, ref|
28
+ convert_jsonvalue(member_m, ref, params[m], "#{context}[#{m}]")
29
+ end
30
+ when Seahorse::Model::Shapes::ListShape
31
+ if ref.shape.member['jsonvalue']
32
+ params[m] = params[m].each_with_index.map do |v, i|
33
+ serialize_jsonvalue(v, "#{context}[#{m}][#{i}]")
34
+ end
35
+ end
36
+ when Seahorse::Model::Shapes::MapShape
37
+ if ref.shape.value['jsonvalue']
38
+ params[m].each do |k, v|
39
+ params[m][k] = serialize_jsonvalue(v, "#{context}[#{m}][#{k}]")
40
+ end
18
41
  end
19
- context.params[m] = param_value.to_json
20
42
  end
21
43
  end
22
- @handler.call(context)
44
+ end
45
+
46
+ def serialize_jsonvalue(v, context)
47
+ unless v.respond_to?(:to_json)
48
+ raise ArgumentError, "The value of #{context} is not JSON serializable."
49
+ end
50
+ v.to_json
23
51
  end
24
52
 
25
53
  end
@@ -9,14 +9,25 @@ module Aws
9
9
  class Handler < Seahorse::Client::Handler
10
10
  def call(context)
11
11
 
12
- unless context.http_request.headers.key?('x-amz-trace-id')
12
+ unless context.http_request.headers.key?('x-amzn-trace-id')
13
13
  if ENV['AWS_LAMBDA_FUNCTION_NAME'] &&
14
- (trace_id = ENV['_X_AMZ_TRACE_ID'])
15
- context.http_request.headers['x-amz-trace-id'] = trace_id
14
+ (trace_id = validate_header(ENV['_X_AMZN_TRACE_ID']))
15
+ context.http_request.headers['x-amzn-trace-id'] = trace_id
16
16
  end
17
17
  end
18
18
  @handler.call(context)
19
19
  end
20
+
21
+ private
22
+ def validate_header(header_value)
23
+ return unless header_value
24
+
25
+ if (header_value.chars & (0..31).map(&:chr)).any?
26
+ raise ArgumentError, 'Invalid _X_AMZN_TRACE_ID value: '\
27
+ 'contains ASCII control characters'
28
+ end
29
+ header_value
30
+ end
20
31
  end
21
32
 
22
33
  # should be at the end of build so that
@@ -43,8 +43,13 @@ is set to `true`.
43
43
  resolve_use_fips_endpoint(cfg)
44
44
  end
45
45
 
46
+ # This option signals whether :endpoint was provided or not.
47
+ # Legacy endpoints must continue to be generated at client time.
46
48
  option(:regional_endpoint, false)
47
49
 
50
+ # NOTE: All of the defaults block code is effectively deprecated.
51
+ # Because old services can depend on this new core version, we must
52
+ # retain it.
48
53
  option(:endpoint, doc_type: String, docstring: <<-DOCS) do |cfg|
49
54
  The client endpoint is normally constructed from the `:region`
50
55
  option. You should only configure an `:endpoint` when connecting