aws-sdk-core 3.171.0 → 3.186.0

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 (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +155 -0
  3. data/VERSION +1 -1
  4. data/lib/aws-defaults/default_configuration.rb +4 -4
  5. data/lib/aws-sdk-core/credential_provider.rb +3 -0
  6. data/lib/aws-sdk-core/endpoints/matchers.rb +13 -9
  7. data/lib/aws-sdk-core/endpoints.rb +5 -1
  8. data/lib/aws-sdk-core/errors.rb +1 -1
  9. data/lib/aws-sdk-core/ini_parser.rb +7 -0
  10. data/lib/aws-sdk-core/instance_profile_credentials.rb +52 -30
  11. data/lib/aws-sdk-core/json/error_handler.rb +15 -5
  12. data/lib/aws-sdk-core/json/parser.rb +1 -1
  13. data/lib/aws-sdk-core/log/formatter.rb +6 -0
  14. data/lib/aws-sdk-core/pageable_response.rb +3 -1
  15. data/lib/aws-sdk-core/param_validator.rb +2 -2
  16. data/lib/aws-sdk-core/plugins/checksum_algorithm.rb +1 -1
  17. data/lib/aws-sdk-core/plugins/regional_endpoint.rb +109 -33
  18. data/lib/aws-sdk-core/plugins/request_compression.rb +217 -0
  19. data/lib/aws-sdk-core/plugins/sign.rb +1 -0
  20. data/lib/aws-sdk-core/plugins/user_agent.rb +117 -14
  21. data/lib/aws-sdk-core/refreshing_credentials.rb +0 -6
  22. data/lib/aws-sdk-core/rest/request/querystring_builder.rb +43 -29
  23. data/lib/aws-sdk-core/shared_config.rb +47 -18
  24. data/lib/aws-sdk-core/sso_credentials.rb +1 -1
  25. data/lib/aws-sdk-core/stubbing/stub_data.rb +11 -0
  26. data/lib/aws-sdk-core/waiters/poller.rb +3 -1
  27. data/lib/aws-sdk-sso/client.rb +21 -1
  28. data/lib/aws-sdk-sso/endpoint_provider.rb +30 -24
  29. data/lib/aws-sdk-sso/endpoints.rb +1 -0
  30. data/lib/aws-sdk-sso.rb +1 -1
  31. data/lib/aws-sdk-ssooidc/client.rb +21 -1
  32. data/lib/aws-sdk-ssooidc/endpoint_provider.rb +30 -24
  33. data/lib/aws-sdk-ssooidc/endpoints.rb +1 -0
  34. data/lib/aws-sdk-ssooidc.rb +1 -1
  35. data/lib/aws-sdk-sts/client.rb +138 -112
  36. data/lib/aws-sdk-sts/client_api.rb +12 -1
  37. data/lib/aws-sdk-sts/endpoint_provider.rb +81 -78
  38. data/lib/aws-sdk-sts/endpoints.rb +1 -0
  39. data/lib/aws-sdk-sts/types.rb +35 -11
  40. data/lib/aws-sdk-sts.rb +1 -1
  41. data/lib/seahorse/client/configuration.rb +0 -4
  42. data/lib/seahorse/client/plugins/request_callback.rb +31 -0
  43. data/lib/seahorse/client/response.rb +6 -0
  44. data/lib/seahorse/model/operation.rb +3 -0
  45. metadata +3 -2
@@ -47,44 +47,21 @@ is set to `true`.
47
47
  # Legacy endpoints must continue to be generated at client time.
48
48
  option(:regional_endpoint, false)
49
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.
50
+ option(:ignore_configured_endpoint_urls,
51
+ doc_type: 'Boolean',
52
+ docstring: <<-DOCS) do |cfg|
53
+ Setting to true disables use of endpoint URLs provided via environment
54
+ variables and the shared configuration file.
55
+ DOCS
56
+ resolve_ignore_configured_endpoint_urls(cfg)
57
+ end
58
+
53
59
  option(:endpoint, doc_type: String, docstring: <<-DOCS) do |cfg|
54
60
  The client endpoint is normally constructed from the `:region`
55
61
  option. You should only configure an `:endpoint` when connecting
56
62
  to test or custom endpoints. This should be a valid HTTP(S) URI.
57
63
  DOCS
58
- endpoint_prefix = cfg.api.metadata['endpointPrefix']
59
- if cfg.region && endpoint_prefix
60
- if cfg.respond_to?(:sts_regional_endpoints)
61
- sts_regional = cfg.sts_regional_endpoints
62
- end
63
-
64
- # check region is a valid RFC host label
65
- unless Seahorse::Util.host_label?(cfg.region)
66
- raise Errors::InvalidRegionError
67
- end
68
-
69
- region = cfg.region
70
- new_region = region.gsub('fips-', '').gsub('-fips', '')
71
- if region != new_region
72
- warn("Legacy region #{region} was transformed to #{new_region}."\
73
- '`use_fips_endpoint` config was set to true.')
74
- cfg.override_config(:use_fips_endpoint, true)
75
- cfg.override_config(:region, new_region)
76
- end
77
-
78
- Aws::Partitions::EndpointProvider.resolve(
79
- cfg.region,
80
- endpoint_prefix,
81
- sts_regional,
82
- {
83
- dualstack: cfg.use_dualstack_endpoint,
84
- fips: cfg.use_fips_endpoint
85
- }
86
- )
87
- end
64
+ resolve_endpoint(cfg)
88
65
  end
89
66
 
90
67
  def after_initialize(client)
@@ -117,6 +94,105 @@ to test or custom endpoints. This should be a valid HTTP(S) URI.
117
94
  value ||= Aws.shared_config.use_fips_endpoint(profile: cfg.profile)
118
95
  Aws::Util.str_2_bool(value) || false
119
96
  end
97
+
98
+ def resolve_ignore_configured_endpoint_urls(cfg)
99
+ value = ENV['AWS_IGNORE_CONFIGURED_ENDPOINT_URLS']
100
+ value ||= Aws.shared_config.ignore_configured_endpoint_urls(profile: cfg.profile)
101
+ Aws::Util.str_2_bool(value&.downcase) || false
102
+ end
103
+
104
+ # NOTE: with Endpoints 2.0, some of this logic is deprecated
105
+ # but because new old service gems may depend on new core versions
106
+ # we must preserve that behavior.
107
+ # Additional behavior controls the setting of the custom SDK::Endpoint
108
+ # parameter.
109
+ # When the `regional_endpoint` config is set to true - this indicates to
110
+ # Endpoints2.0 that a custom endpoint has NOT been configured by the user.
111
+ def resolve_endpoint(cfg)
112
+ endpoint = resolve_custom_config_endpoint(cfg)
113
+ endpoint_prefix = cfg.api.metadata['endpointPrefix']
114
+
115
+ return endpoint unless endpoint.nil? && cfg.region && endpoint_prefix
116
+
117
+ validate_region!(cfg.region)
118
+ handle_legacy_pseudo_regions(cfg)
119
+
120
+ # set regional_endpoint flag - this indicates to Endpoints 2.0
121
+ # that a custom endpoint has NOT been configured by the user
122
+ cfg.override_config(:regional_endpoint, true)
123
+
124
+ resolve_legacy_endpoint(cfg)
125
+ end
126
+
127
+ # get a custom configured endpoint from ENV or configuration
128
+ def resolve_custom_config_endpoint(cfg)
129
+ return if cfg.ignore_configured_endpoint_urls
130
+
131
+
132
+ env_service_endpoint(cfg) || env_global_endpoint(cfg) || shared_config_endpoint(cfg)
133
+ end
134
+
135
+ def env_service_endpoint(cfg)
136
+ service_id = cfg.api.metadata['serviceId'] || cfg.api.metadata['endpointPrefix']
137
+ env_service_id = service_id.gsub(" ", "_").upcase
138
+ return unless endpoint = ENV["AWS_ENDPOINT_URL_#{env_service_id}"]
139
+
140
+ cfg.logger&.debug(
141
+ "Endpoint configured from ENV['AWS_ENDPOINT_URL_#{env_service_id}']: #{endpoint}\n")
142
+ endpoint
143
+ end
144
+
145
+ def env_global_endpoint(cfg)
146
+ return unless endpoint = ENV['AWS_ENDPOINT_URL']
147
+
148
+ cfg.logger&.debug(
149
+ "Endpoint configured from ENV['AWS_ENDPOINT_URL']: #{endpoint}\n")
150
+ endpoint
151
+ end
152
+
153
+ def shared_config_endpoint(cfg)
154
+ service_id = cfg.api.metadata['serviceId'] || cfg.api.metadata['endpointPrefix']
155
+ return unless endpoint = Aws.shared_config.configured_endpoint(profile: cfg.profile, service_id: service_id)
156
+
157
+ cfg.logger&.debug(
158
+ "Endpoint configured from shared config(profile: #{cfg.profile}): #{endpoint}\n")
159
+ endpoint
160
+ end
161
+
162
+ # check region is a valid RFC host label
163
+ def validate_region!(region)
164
+ unless Seahorse::Util.host_label?(region)
165
+ raise Errors::InvalidRegionError
166
+ end
167
+ end
168
+
169
+ def handle_legacy_pseudo_regions(cfg)
170
+ region = cfg.region
171
+ new_region = region.gsub('fips-', '').gsub('-fips', '')
172
+ if region != new_region
173
+ warn("Legacy region #{region} was transformed to #{new_region}."\
174
+ '`use_fips_endpoint` config was set to true.')
175
+ cfg.override_config(:use_fips_endpoint, true)
176
+ cfg.override_config(:region, new_region)
177
+ end
178
+ end
179
+ # set a default endpoint in config using legacy (endpoints.json) resolver
180
+ def resolve_legacy_endpoint(cfg)
181
+ endpoint_prefix = cfg.api.metadata['endpointPrefix']
182
+ if cfg.respond_to?(:sts_regional_endpoints)
183
+ sts_regional = cfg.sts_regional_endpoints
184
+ end
185
+
186
+ Aws::Partitions::EndpointProvider.resolve(
187
+ cfg.region,
188
+ endpoint_prefix,
189
+ sts_regional,
190
+ {
191
+ dualstack: cfg.use_dualstack_endpoint,
192
+ fips: cfg.use_fips_endpoint
193
+ }
194
+ )
195
+ end
120
196
  end
121
197
  end
122
198
  end
@@ -0,0 +1,217 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module Plugins
5
+ # @api private
6
+ class RequestCompression < Seahorse::Client::Plugin
7
+ DEFAULT_MIN_COMPRESSION_SIZE = 10_240
8
+ MIN_COMPRESSION_SIZE_LIMIT = 10_485_760
9
+ SUPPORTED_ENCODINGS = %w[gzip].freeze
10
+ CHUNK_SIZE = 1 * 1024 * 1024 # one MB
11
+
12
+ option(
13
+ :disable_request_compression,
14
+ default: false,
15
+ doc_type: 'Boolean',
16
+ docstring: <<-DOCS) do |cfg|
17
+ When set to 'true' the request body will not be compressed
18
+ for supported operations.
19
+ DOCS
20
+ resolve_disable_request_compression(cfg)
21
+ end
22
+
23
+ option(
24
+ :request_min_compression_size_bytes,
25
+ default: 10_240,
26
+ doc_type: 'Integer',
27
+ docstring: <<-DOCS) do |cfg|
28
+ The minimum size in bytes that triggers compression for request
29
+ bodies. The value must be non-negative integer value between 0
30
+ and 10485780 bytes inclusive.
31
+ DOCS
32
+ resolve_request_min_compression_size_bytes(cfg)
33
+ end
34
+
35
+ def after_initialize(client)
36
+ validate_disable_request_compression_input(client.config)
37
+ validate_request_min_compression_size_bytes_input(client.config)
38
+ end
39
+
40
+ def validate_disable_request_compression_input(cfg)
41
+ unless [true, false].include?(cfg.disable_request_compression)
42
+ raise ArgumentError,
43
+ 'Must provide either `true` or `false` for the '\
44
+ '`disable_request_compression` configuration option.'
45
+ end
46
+ end
47
+
48
+ def validate_request_min_compression_size_bytes_input(cfg)
49
+ value = Integer(cfg.request_min_compression_size_bytes)
50
+ unless value.between?(0, MIN_COMPRESSION_SIZE_LIMIT)
51
+ raise ArgumentError,
52
+ 'Must provide a non-negative integer value between '\
53
+ '`0` and `10485760` bytes inclusive for the '\
54
+ '`request_min_compression_size_bytes` configuration option.'
55
+ end
56
+ end
57
+
58
+ def add_handlers(handlers, _config)
59
+ # priority set to ensure compression happens BEFORE checksum
60
+ handlers.add(CompressionHandler, priority: 16, step: :build)
61
+ end
62
+
63
+ class << self
64
+ private
65
+
66
+ def resolve_disable_request_compression(cfg)
67
+ value = ENV['AWS_DISABLE_REQUEST_COMPRESSION'] ||
68
+ Aws.shared_config.disable_request_compression(profile: cfg.profile) ||
69
+ 'false'
70
+ Aws::Util.str_2_bool(value)
71
+ end
72
+
73
+ def resolve_request_min_compression_size_bytes(cfg)
74
+ value = ENV['AWS_REQUEST_MIN_COMPRESSION_SIZE_BYTES'] ||
75
+ Aws.shared_config.request_min_compression_size_bytes(profile: cfg.profile) ||
76
+ DEFAULT_MIN_COMPRESSION_SIZE.to_s
77
+ Integer(value)
78
+ end
79
+ end
80
+
81
+ # @api private
82
+ class CompressionHandler < Seahorse::Client::Handler
83
+ def call(context)
84
+ if should_compress?(context)
85
+ selected_encoding = request_encoding_selection(context)
86
+ if selected_encoding
87
+ if streaming?(context.operation.input)
88
+ process_streaming_compression(selected_encoding, context)
89
+ elsif context.http_request.body.size >= context.config.request_min_compression_size_bytes
90
+ process_compression(selected_encoding, context)
91
+ end
92
+ end
93
+ end
94
+ @handler.call(context)
95
+ end
96
+
97
+ private
98
+
99
+ def request_encoding_selection(context)
100
+ encoding_list = context.operation.request_compression['encodings']
101
+ encoding_list.find { |encoding| RequestCompression::SUPPORTED_ENCODINGS.include?(encoding) }
102
+ end
103
+
104
+ def update_content_encoding(encoding, context)
105
+ headers = context.http_request.headers
106
+ if headers['Content-Encoding']
107
+ headers['Content-Encoding'] += ',' + encoding
108
+ else
109
+ headers['Content-Encoding'] = encoding
110
+ end
111
+ end
112
+
113
+ def should_compress?(context)
114
+ context.operation.request_compression &&
115
+ !context.config.disable_request_compression
116
+ end
117
+
118
+ def streaming?(input)
119
+ if payload = input[:payload_member] # checking ref and shape
120
+ payload['streaming'] || payload.shape['streaming']
121
+ else
122
+ false
123
+ end
124
+ end
125
+
126
+ def process_compression(encoding, context)
127
+ case encoding
128
+ when 'gzip'
129
+ gzip_compress(context)
130
+ else
131
+ raise StandardError, "We currently do not support #{encoding} encoding"
132
+ end
133
+ update_content_encoding(encoding, context)
134
+ end
135
+
136
+ def gzip_compress(context)
137
+ compressed = StringIO.new
138
+ compressed.binmode
139
+ gzip_writer = Zlib::GzipWriter.new(compressed)
140
+ if context.http_request.body.respond_to?(:read)
141
+ update_in_chunks(gzip_writer, context.http_request.body)
142
+ else
143
+ gzip_writer.write(context.http_request.body)
144
+ end
145
+ gzip_writer.close
146
+ new_body = StringIO.new(compressed.string)
147
+ context.http_request.body = new_body
148
+ end
149
+
150
+ def update_in_chunks(compressor, io)
151
+ loop do
152
+ chunk = io.read(CHUNK_SIZE)
153
+ break unless chunk
154
+
155
+ compressor.write(chunk)
156
+ end
157
+ end
158
+
159
+ def process_streaming_compression(encoding, context)
160
+ case encoding
161
+ when 'gzip'
162
+ context.http_request.body = GzipIO.new(context.http_request.body)
163
+ else
164
+ raise StandardError, "We currently do not support #{encoding} encoding"
165
+ end
166
+ update_content_encoding(encoding, context)
167
+ end
168
+
169
+ # @api private
170
+ class GzipIO
171
+ def initialize(body)
172
+ @body = body
173
+ @buffer = ChunkBuffer.new
174
+ @gzip_writer = Zlib::GzipWriter.new(@buffer)
175
+ end
176
+
177
+ def read(length, buff = nil)
178
+ if @gzip_writer.closed?
179
+ # an empty string to signify an end as
180
+ # there will be nothing remaining to be read
181
+ StringIO.new('').read(length, buff)
182
+ return
183
+ end
184
+
185
+ chunk = @body.read(length)
186
+ if !chunk || chunk.empty?
187
+ # closing the writer will write one last chunk
188
+ # with a trailer (to be read from the @buffer)
189
+ @gzip_writer.close
190
+ else
191
+ # flush happens first to ensure that header fields
192
+ # are being sent over since write will override
193
+ @gzip_writer.flush
194
+ @gzip_writer.write(chunk)
195
+ end
196
+
197
+ StringIO.new(@buffer.last_chunk).read(length, buff)
198
+ end
199
+ end
200
+
201
+ # @api private
202
+ class ChunkBuffer
203
+ def initialize
204
+ @last_chunk = nil
205
+ end
206
+
207
+ attr_reader :last_chunk
208
+
209
+ def write(data)
210
+ @last_chunk = data
211
+ end
212
+ end
213
+ end
214
+
215
+ end
216
+ end
217
+ end
@@ -108,6 +108,7 @@ module Aws
108
108
  credentials_provider: config.credentials,
109
109
  signing_algorithm: scheme_name.to_sym,
110
110
  uri_escape_path: !!!auth_scheme['disableDoubleEncoding'],
111
+ normalize_path: !!!auth_scheme['disableNormalizePath'],
111
112
  unsigned_headers: %w[content-length user-agent x-amzn-trace-id]
112
113
  )
113
114
  rescue Aws::Sigv4::Errors::MissingCredentialsError
@@ -4,7 +4,31 @@ module Aws
4
4
  module Plugins
5
5
  # @api private
6
6
  class UserAgent < Seahorse::Client::Plugin
7
+ # @api private
7
8
  option(:user_agent_suffix)
9
+ # @api private
10
+ option(:user_agent_frameworks, default: [])
11
+
12
+ option(
13
+ :sdk_ua_app_id,
14
+ doc_type: 'String',
15
+ docstring: <<-DOCS) do |cfg|
16
+ A unique and opaque application ID that is appended to the
17
+ User-Agent header as app/<sdk_ua_app_id>. It should have a
18
+ maximum length of 50.
19
+ DOCS
20
+ app_id = ENV['AWS_SDK_UA_APP_ID']
21
+ app_id ||= Aws.shared_config.sdk_ua_app_id(profile: cfg.profile)
22
+ app_id
23
+ end
24
+
25
+ def self.feature(feature, &block)
26
+ Thread.current[:aws_sdk_core_user_agent_feature] ||= []
27
+ Thread.current[:aws_sdk_core_user_agent_feature] << "ft/#{feature}"
28
+ block.call
29
+ ensure
30
+ Thread.current[:aws_sdk_core_user_agent_feature].pop
31
+ end
8
32
 
9
33
  # @api private
10
34
  class Handler < Seahorse::Client::Handler
@@ -14,33 +38,112 @@ module Aws
14
38
  end
15
39
 
16
40
  def set_user_agent(context)
17
- ua = "aws-sdk-ruby3/#{CORE_GEM_VERSION}"
41
+ context.http_request.headers['User-Agent'] = UserAgent.new(context).to_s
42
+ end
43
+
44
+ class UserAgent
45
+ def initialize(context)
46
+ @context = context
47
+ end
48
+
49
+ def to_s
50
+ ua = "aws-sdk-ruby3/#{CORE_GEM_VERSION}"
51
+ ua += ' ua/2.0'
52
+ ua += " #{api_metadata}" if api_metadata
53
+ ua += " #{os_metadata}"
54
+ ua += " #{language_metadata}"
55
+ ua += " #{env_metadata}" if env_metadata
56
+ ua += " #{config_metadata}" if config_metadata
57
+ ua += " #{app_id}" if app_id
58
+ ua += " #{feature_metadata}" if feature_metadata
59
+ ua += " #{framework_metadata}" if framework_metadata
60
+ if @context.config.user_agent_suffix
61
+ ua += " #{@context.config.user_agent_suffix}"
62
+ end
63
+ ua.strip
64
+ end
65
+
66
+ private
18
67
 
19
- begin
20
- ua += " #{RUBY_ENGINE}/#{RUBY_VERSION}"
21
- rescue
22
- ua += " RUBY_ENGINE_NA/#{RUBY_VERSION}"
68
+ # Used to be gem_name/gem_version
69
+ def api_metadata
70
+ service_id = @context.config.api.metadata['serviceId']
71
+ return unless service_id
72
+
73
+ service_id = service_id.gsub(' ', '_').downcase
74
+ gem_version = @context[:gem_version]
75
+ "api/#{service_id}##{gem_version}"
76
+ end
77
+
78
+ # Used to be RUBY_PLATFORM
79
+ def os_metadata
80
+ os =
81
+ case RbConfig::CONFIG['host_os']
82
+ when /mac|darwin/
83
+ 'macos'
84
+ when /linux|cygwin/
85
+ 'linux'
86
+ when /mingw|mswin/
87
+ 'windows'
88
+ else
89
+ 'other'
90
+ end
91
+ metadata = "os/#{os}"
92
+ local_version = Gem::Platform.local.version
93
+ metadata += "##{local_version}" if local_version
94
+ metadata += " md/#{RbConfig::CONFIG['host_cpu']}"
95
+ metadata
23
96
  end
24
97
 
25
- ua += " #{RUBY_PLATFORM}"
98
+ # Used to be RUBY_ENGINE/RUBY_VERSION
99
+ def language_metadata
100
+ "lang/#{RUBY_ENGINE}##{RUBY_ENGINE_VERSION} md/#{RUBY_VERSION}"
101
+ end
102
+
103
+ def env_metadata
104
+ return unless (execution_env = ENV['AWS_EXECUTION_ENV'])
105
+
106
+ "exec-env/#{execution_env}"
107
+ end
26
108
 
27
- if context[:gem_name] && context[:gem_version]
28
- ua += " #{context[:gem_name]}/#{context[:gem_version]}"
109
+ def config_metadata
110
+ "cfg/retry-mode##{@context.config.retry_mode}"
29
111
  end
30
112
 
31
- if (execution_env = ENV['AWS_EXECUTION_ENV'])
32
- ua += " exec-env/#{execution_env}"
113
+ def app_id
114
+ return unless (app_id = @context.config.sdk_ua_app_id)
115
+
116
+ # Sanitize and only allow these characters
117
+ app_id = app_id.gsub(/[^!#$%&'*+\-.^_`|~0-9A-Za-z]/, '-')
118
+ "app/#{app_id}"
33
119
  end
34
120
 
35
- if context.config.user_agent_suffix
36
- ua += " #{context.config.user_agent_suffix}"
121
+ def feature_metadata
122
+ return unless Thread.current[:aws_sdk_core_user_agent_feature]
123
+
124
+ Thread.current[:aws_sdk_core_user_agent_feature].join(' ')
37
125
  end
38
126
 
39
- context.http_request.headers['User-Agent'] = ua.strip
127
+ def framework_metadata
128
+ if (frameworks_cfg = @context.config.user_agent_frameworks).empty?
129
+ return
130
+ end
131
+
132
+ # Frameworks may be aws-record, aws-sdk-rails, etc.
133
+ regex = /gems\/(?<name>#{frameworks_cfg.join('|')})-(?<version>\d+\.\d+\.\d+)/.freeze
134
+ frameworks = {}
135
+ Kernel.caller.each do |line|
136
+ match = line.match(regex)
137
+ next unless match
138
+
139
+ frameworks[match[:name]] = match[:version]
140
+ end
141
+ frameworks.map { |n, v| "lib/#{n}##{v}" }.join(' ')
142
+ end
40
143
  end
41
144
  end
42
145
 
43
- handler(Handler)
146
+ handler(Handler, priority: 1)
44
147
  end
45
148
  end
46
149
  end
@@ -36,12 +36,6 @@ module Aws
36
36
  @credentials
37
37
  end
38
38
 
39
- # @return [Time,nil]
40
- def expiration
41
- refresh_if_near_expiration!
42
- @expiration
43
- end
44
-
45
39
  # Refresh credentials.
46
40
  # @return [void]
47
41
  def refresh!
@@ -4,9 +4,16 @@ module Aws
4
4
  module Rest
5
5
  module Request
6
6
  class QuerystringBuilder
7
-
8
7
  include Seahorse::Model::Shapes
9
8
 
9
+ SUPPORTED_TYPES = [
10
+ BooleanShape,
11
+ FloatShape,
12
+ IntegerShape,
13
+ StringShape,
14
+ TimestampShape
15
+ ].freeze
16
+
10
17
  # Provide shape references and param values:
11
18
  #
12
19
  # [
@@ -33,29 +40,12 @@ module Aws
33
40
  def build_part(shape_ref, param_value)
34
41
  case shape_ref.shape
35
42
  # supported scalar types
36
- when StringShape, BooleanShape, FloatShape, IntegerShape, StringShape
37
- param_name = shape_ref.location_name
38
- "#{param_name}=#{escape(param_value.to_s)}"
39
- when TimestampShape
40
- param_name = shape_ref.location_name
41
- "#{param_name}=#{escape(timestamp(shape_ref, param_value))}"
43
+ when *SUPPORTED_TYPES
44
+ "#{shape_ref.location_name}=#{query_value(shape_ref, param_value)}"
42
45
  when MapShape
43
- if StringShape === shape_ref.shape.value.shape
44
- query_map_of_string(param_value)
45
- elsif ListShape === shape_ref.shape.value.shape
46
- query_map_of_string_list(param_value)
47
- else
48
- msg = "only map of string and string list supported"
49
- raise NotImplementedError, msg
50
- end
46
+ generate_query_map(shape_ref, param_value)
51
47
  when ListShape
52
- if StringShape === shape_ref.shape.member.shape
53
- list_of_strings(shape_ref.location_name, param_value)
54
- else
55
- msg = "Only list of strings supported, got "\
56
- "#{shape_ref.shape.member.shape.class.name}"
57
- raise NotImplementedError, msg
58
- end
48
+ generate_query_list(shape_ref, param_value)
59
49
  else
60
50
  raise NotImplementedError
61
51
  end
@@ -71,6 +61,37 @@ module Aws
71
61
  end
72
62
  end
73
63
 
64
+ def query_value(ref, value)
65
+ case ref.shape
66
+ when TimestampShape
67
+ escape(timestamp(ref, value))
68
+ when *SUPPORTED_TYPES
69
+ escape(value.to_s)
70
+ else
71
+ raise NotImplementedError
72
+ end
73
+ end
74
+
75
+ def generate_query_list(ref, values)
76
+ member_ref = ref.shape.member
77
+ values.map do |value|
78
+ value = query_value(member_ref, value)
79
+ "#{ref.location_name}=#{value}"
80
+ end
81
+ end
82
+
83
+ def generate_query_map(ref, value)
84
+ case ref.shape.value.shape
85
+ when StringShape
86
+ query_map_of_string(value)
87
+ when ListShape
88
+ query_map_of_string_list(value)
89
+ else
90
+ msg = 'Only map of string and string list supported'
91
+ raise NotImplementedError, msg
92
+ end
93
+ end
94
+
74
95
  def query_map_of_string(hash)
75
96
  list = []
76
97
  hash.each_pair do |key, value|
@@ -89,16 +110,9 @@ module Aws
89
110
  list
90
111
  end
91
112
 
92
- def list_of_strings(name, values)
93
- values.map do |value|
94
- "#{name}=#{escape(value)}"
95
- end
96
- end
97
-
98
113
  def escape(string)
99
114
  Seahorse::Util.uri_escape(string)
100
115
  end
101
-
102
116
  end
103
117
  end
104
118
  end