aws-sdk-core 3.191.5 → 3.193.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 +52 -0
  3. data/VERSION +1 -1
  4. data/lib/aws-sdk-core/binary/decode_handler.rb +0 -5
  5. data/lib/aws-sdk-core/binary/event_builder.rb +34 -37
  6. data/lib/aws-sdk-core/event_emitter.rb +0 -16
  7. data/lib/aws-sdk-core/json/builder.rb +8 -1
  8. data/lib/aws-sdk-core/json/error_handler.rb +10 -3
  9. data/lib/aws-sdk-core/json/parser.rb +4 -1
  10. data/lib/aws-sdk-core/param_validator.rb +4 -0
  11. data/lib/aws-sdk-core/plugins/invocation_id.rb +1 -11
  12. data/lib/aws-sdk-core/plugins/protocols/rest_json.rb +3 -16
  13. data/lib/aws-sdk-core/plugins/protocols/rest_xml.rb +1 -2
  14. data/lib/aws-sdk-core/plugins/request_compression.rb +1 -1
  15. data/lib/aws-sdk-core/plugins/sign.rb +8 -3
  16. data/lib/aws-sdk-core/query/param_builder.rb +2 -2
  17. data/lib/aws-sdk-core/rest/request/body.rb +32 -5
  18. data/lib/aws-sdk-core/rest/request/content_type.rb +60 -0
  19. data/lib/aws-sdk-core/rest/request/endpoint.rb +22 -4
  20. data/lib/aws-sdk-core/rest/request/headers.rb +15 -7
  21. data/lib/aws-sdk-core/rest/request/querystring_builder.rb +23 -11
  22. data/lib/aws-sdk-core/rest/response/body.rb +15 -1
  23. data/lib/aws-sdk-core/rest/response/header_list_parser.rb +79 -0
  24. data/lib/aws-sdk-core/rest/response/headers.rb +8 -3
  25. data/lib/aws-sdk-core/rest.rb +1 -0
  26. data/lib/aws-sdk-core/util.rb +39 -0
  27. data/lib/aws-sdk-core/xml/builder.rb +17 -9
  28. data/lib/aws-sdk-core/xml/error_handler.rb +24 -8
  29. data/lib/aws-sdk-core/xml/parser/frame.rb +4 -20
  30. data/lib/aws-sdk-core/xml/parser/stack.rb +2 -0
  31. data/lib/aws-sdk-sso/client.rb +70 -46
  32. data/lib/aws-sdk-sso.rb +1 -1
  33. data/lib/aws-sdk-ssooidc/client.rb +70 -46
  34. data/lib/aws-sdk-ssooidc.rb +1 -1
  35. data/lib/aws-sdk-sts/client.rb +70 -46
  36. data/lib/aws-sdk-sts/client_api.rb +8 -8
  37. data/lib/aws-sdk-sts.rb +1 -1
  38. data/lib/seahorse/client/async_base.rb +1 -1
  39. data/lib/seahorse/client/async_response.rb +19 -0
  40. data/lib/seahorse/client/base.rb +1 -0
  41. data/lib/seahorse/client/h2/handler.rb +1 -0
  42. data/lib/seahorse/client/plugin.rb +8 -0
  43. data/lib/seahorse/client/plugins/net_http.rb +48 -16
  44. data/lib/seahorse/model/shapes.rb +1 -1
  45. metadata +4 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f31347ca054989788f8b9db038b0060f7fa573f39ba5eb998745cf0798a7eb51
4
- data.tar.gz: 13a65ab239a98d78d1efdac6c1ec453582423b106cf12ecdc0fdeaff558802b0
3
+ metadata.gz: 695fd9bb743f174c2d95150bbd990e4918a7ed369f302e76f8da7d280fc3f67a
4
+ data.tar.gz: 1cde2df63d79f4a15723b62420c0e97b70e6cb42dff41e9116704c73a9793454
5
5
  SHA512:
6
- metadata.gz: a05ebb66eaf439c1699513967b6eb425cda973793fb3b201bd187e9037f83d61d620aa2751247877d879592f04cd58ba290d7a1210e3d8ff3d8a8052176319ae
7
- data.tar.gz: 4f95ef37c87fb18e4a5a95c160c7399eb27490aa5bcfe6aaf665bb033ff624056bac8201c22f36c629397d9502cf135a71ae590591cb41cd8424e43c7d3fef16
6
+ metadata.gz: f468ab811c2a74ab4dd844258ba6f8b5e515771c4409cd03018c5fd1a33b11cf50f03d43ea2efb5201fdf8cf4ffee83fc1cc7bec6016206a05e6b05b5dbdd160
7
+ data.tar.gz: 44a637e590341dec00e23586c0c0d8881ad863aa94b73ddd75686fa08f2491e2c1d15fc8d409896cddee00e7eef0c585a98bf689249a9ae5839131f38e6d2ac9
data/CHANGELOG.md CHANGED
@@ -1,6 +1,58 @@
1
1
  Unreleased Changes
2
2
  ------------------
3
3
 
4
+ 3.193.0 (2024-04-25)
5
+ ------------------
6
+
7
+ * Feature - Updated Aws::STS::Client with the latest API changes.
8
+
9
+ * Feature - Updated Aws::SSOOIDC::Client with the latest API changes.
10
+
11
+ * Feature - Updated Aws::SSO::Client with the latest API changes.
12
+
13
+ * Issue - Update event stream documentation.
14
+ * Issue - Move `InvocationId` plugin to all clients.
15
+ * Issue - Handle event streaming content-sha256 header in the signer plugin.
16
+ * Issue - Add the event stream content type to initial requests.
17
+ * Issue - Fix `standard` and `adaptive` retry mode for event streams.
18
+ * Issue - Add `authority` to http2 headers.
19
+ * Issue - Do not treat single members in event stream structures as implicit payloads.
20
+ * Issue - Do not wait for initial response headers to start sending input events.
21
+
22
+ 3.192.1 (2024-04-18)
23
+ ------------------
24
+
25
+ * Issue - Drop key/value pair if value is `nil` when deserializing json maps.
26
+
27
+ 3.192.0 (2024-04-16)
28
+ ------------------
29
+
30
+ * Feature - Updated Aws::STS::Client with the latest API changes.
31
+
32
+ * Feature - Update serializing/deserializing for all protocols to align with Smithy protocol-tests.
33
+ * Issue - Allow `nil` values in lists and maps.
34
+ * Issue - Populate headers for XML and JSON error responses.
35
+ * Issue - Support fractional seconds when parsing `DateTime` timestamps.
36
+ * Issue - Correctly serialize flattened lists for Query protocol.
37
+ * Issue - Correctly serialize payload name in Rest-XML requests.
38
+ * Issue - Fix an issue where Rest-XML requests do not have a default `Content-Type` header applied.
39
+ * Issue - Apply appropriate `Content-Type` header for payloads in Rest services.
40
+ * Issue - Correctly serialize URI label bindings in Rest requests.
41
+ * Issue - Correctly serialize and parse header bindings in Rest services.
42
+ * Issue - Ensure that null and empty headers are not sent in Rest requests.
43
+ * Issue - Ensure keys in query maps do not override modeled keys in Rest requests.
44
+ * Issue - Ensure empty blob payloads are omitted in Rest requests.
45
+ * Issue - Support parsing of `NaN`, `Infinity` and `-Infinity` float values.
46
+ * Issue - Apply appropriate `xmlName` for flattened lists and maps in Rest-XML services.
47
+ * Issue - Handle serializing of different formats of `xmlNamespace` on shapes.
48
+ * Issue - Fix deserializing of an empty blob to produce an empty string.
49
+ * Issue - Fix deserializing an empty self-closed blob to produce an empty string.
50
+ * Issue - Support parsing of different formats of error data in Rest-XML services.
51
+
52
+ 3.191.6 (2024-04-02)
53
+ ------------------
54
+ * Issue - Performance optimization: ensure presence and order of instance variables in `PluginOptions` (#3002).
55
+
4
56
  3.191.5 (2024-03-26)
5
57
  ------------------
6
58
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.191.5
1
+ 3.193.0
@@ -33,11 +33,6 @@ module Aws
33
33
  context.operation.errors,
34
34
  context.http_response.body,
35
35
  output_handler)
36
- if input_emitter = context[:input_event_emitter]
37
- # #emit will be blocked until 200 success
38
- # see Aws::EventEmitter#emit
39
- input_emitter.signal_queue << "ready"
40
- end
41
36
  end
42
37
 
43
38
  context.http_response.on_success(200) do
@@ -42,41 +42,39 @@ module Aws
42
42
  end
43
43
  end
44
44
 
45
- # implict payload
46
- if !explicit_payload && !implicit_payload_members.empty?
47
- if implicit_payload_members.size > 1
48
- payload_shape = Shapes::StructureShape.new
49
- implicit_payload_members.each do |m_name, m_ref|
50
- payload_shape.add_member(m_name, m_ref)
51
- end
52
- payload_ref = Shapes::ShapeRef.new(shape: payload_shape)
53
-
54
- payload = build_payload_members(payload_ref, params)
55
- else
56
- m_name, m_ref = implicit_payload_members.first
57
- streaming, content_type = _content_type(m_ref.shape)
58
-
59
- es_headers[":content-type"] = Aws::EventStream::HeaderValue.new(
60
- type: "string", value: content_type)
61
- payload = _build_payload(streaming, m_ref, params[m_name])
62
- end
63
- end
64
-
65
-
45
+ # handle header members for all cases
66
46
  event_ref.shape.members.each do |member_name, member_ref|
67
47
  if member_ref.eventheader && params[member_name]
68
48
  header_value = params[member_name]
69
49
  es_headers[member_ref.shape.name] = Aws::EventStream::HeaderValue.new(
70
- type: _header_value_type(member_ref.shape, header_value),
50
+ type: header_value_type(member_ref.shape, header_value),
71
51
  value: header_value
72
52
  )
73
- elsif member_ref.eventpayload && params[member_name]
74
- # explicit payload
75
- streaming, content_type = _content_type(member_ref.shape)
53
+ end
54
+ end
55
+
56
+ # implict payload
57
+ if !explicit_payload && !implicit_payload_members.empty?
58
+ payload_shape = StructureShape.new
59
+ implicit_payload_members.each do |m_name, m_ref|
60
+ payload_shape.add_member(m_name, m_ref)
61
+ end
62
+ payload_ref = ShapeRef.new(shape: payload_shape)
76
63
 
77
- es_headers[":content-type"] = Aws::EventStream::HeaderValue.new(
78
- type: "string", value: content_type)
79
- payload = _build_payload(streaming, member_ref, params[member_name])
64
+ payload = build_payload_members(payload_ref, params)
65
+ .force_encoding(Encoding::BINARY)
66
+
67
+
68
+ es_headers[":content-type"] = Aws::EventStream::HeaderValue.new(
69
+ type: "string", value: content_type(payload_ref.shape))
70
+ else
71
+ # explicit payload, serialize just the payload member
72
+ event_ref.shape.members.each do |member_name, member_ref|
73
+ if member_ref.eventpayload && params[member_name]
74
+ es_headers[":content-type"] = Aws::EventStream::HeaderValue.new(
75
+ type: "string", value: content_type(member_ref.shape))
76
+ payload = params[member_name]
77
+ end
80
78
  end
81
79
  end
82
80
 
@@ -86,15 +84,15 @@ module Aws
86
84
  )
87
85
  end
88
86
 
89
- def _content_type(shape)
87
+ def content_type(shape)
90
88
  case shape
91
- when BlobShape then [true, "application/octet-stream"]
92
- when StringShape then [true, "text/plain"]
89
+ when BlobShape then "application/octet-stream"
90
+ when StringShape then "text/plain"
93
91
  when StructureShape then
94
92
  if @serializer_class.name.include?('Xml')
95
- [false, "text/xml"]
93
+ "text/xml"
96
94
  elsif @serializer_class.name.include?('Json')
97
- [false, "application/json"]
95
+ "application/json"
98
96
  end
99
97
  else
100
98
  raise Aws::Errors::EventStreamBuilderError.new(
@@ -102,7 +100,7 @@ module Aws
102
100
  end
103
101
  end
104
102
 
105
- def _header_value_type(shape, value)
103
+ def header_value_type(shape, value)
106
104
  case shape
107
105
  when StringShape then "string"
108
106
  when IntegerShape then "integer"
@@ -115,10 +113,9 @@ module Aws
115
113
  end
116
114
  end
117
115
 
118
- def _build_payload(streaming, ref, value)
119
- streaming ? value : @serializer_class.new(ref).serialize(value)
116
+ def build_payload_members(payload_ref, params)
117
+ @serializer_class.new(payload_ref).serialize(params)
120
118
  end
121
-
122
119
  end
123
120
  end
124
121
  end
@@ -6,7 +6,6 @@ module Aws
6
6
  def initialize
7
7
  @listeners = {}
8
8
  @validate_event = true
9
- @status = :sleep
10
9
  @signal_queue = Queue.new
11
10
  end
12
11
 
@@ -40,25 +39,10 @@ module Aws
40
39
  Aws::ParamValidator.validate!(
41
40
  @encoder.rules.shape.member(type), params)
42
41
  end
43
- _ready_for_events?
44
42
  @stream.data(
45
43
  @encoder.encode(type, params),
46
44
  end_stream: type == :end_stream
47
45
  )
48
46
  end
49
-
50
- private
51
-
52
- def _ready_for_events?
53
- return true if @status == :ready
54
-
55
- # blocked until once initial 200 response is received
56
- # signal will be available in @signal_queue
57
- # and this check will no longer be blocked
58
- @signal_queue.pop
59
- @status = :ready
60
- true
61
- end
62
-
63
47
  end
64
48
  end
@@ -8,7 +8,7 @@ module Aws
8
8
 
9
9
  include Seahorse::Model::Shapes
10
10
 
11
- def initialize(rules)
11
+ def initialize(rules, _options = {})
12
12
  @rules = rules
13
13
  end
14
14
 
@@ -20,6 +20,8 @@ module Aws
20
20
  private
21
21
 
22
22
  def structure(ref, values)
23
+ return nil if values.nil?
24
+
23
25
  shape = ref.shape
24
26
  values.each_pair.with_object({}) do |(key, value), data|
25
27
  if shape.member?(key) && !value.nil?
@@ -31,11 +33,15 @@ module Aws
31
33
  end
32
34
 
33
35
  def list(ref, values)
36
+ return nil if values.nil?
37
+
34
38
  member_ref = ref.shape.member
35
39
  values.collect { |value| format(member_ref, value) }
36
40
  end
37
41
 
38
42
  def map(ref, values)
43
+ return nil if values.nil?
44
+
39
45
  value_ref = ref.shape.value
40
46
  values.each.with_object({}) do |(key, value), data|
41
47
  data[key] = format(value_ref, value)
@@ -49,6 +55,7 @@ module Aws
49
55
  when MapShape then map(ref, value)
50
56
  when TimestampShape then timestamp(ref, value)
51
57
  when BlobShape then encode(value)
58
+ when FloatShape then Util.serialize_number(value)
52
59
  else value
53
60
  end
54
61
  end
@@ -71,14 +71,21 @@ module Aws
71
71
  # some type(code) might contains invalid characters
72
72
  # such as ':' (efs) etc
73
73
  match = rule.shape.name == code.gsub(/[^^a-zA-Z0-9]/, '')
74
- if match && rule.shape.members.any?
75
- data = Parser.new(rule).parse(context.http_response.body_contents)
76
- end
74
+ next unless match && rule.shape.members.any?
75
+
76
+ data = Parser.new(rule).parse(context.http_response.body_contents)
77
+ # errors support HTTP bindings
78
+ apply_error_headers(rule, context, data)
77
79
  end
78
80
  end
79
81
  data
80
82
  end
81
83
 
84
+ def apply_error_headers(rule, context, data)
85
+ headers = Aws::Rest::Response::Headers.new(rule)
86
+ headers.apply(context.http_response, data)
87
+ end
88
+
82
89
  end
83
90
  end
84
91
  end
@@ -69,6 +69,8 @@ module Aws
69
69
  def map(ref, values, target = nil)
70
70
  target = {} if target.nil?
71
71
  values.each do |key, value|
72
+ next if value.nil?
73
+
72
74
  target[key] = parse_ref(ref.shape.value, value)
73
75
  end
74
76
  target
@@ -85,6 +87,7 @@ module Aws
85
87
  when TimestampShape then time(value)
86
88
  when BlobShape then Base64.decode64(value)
87
89
  when BooleanShape then value.to_s == 'true'
90
+ when FloatShape then Util.deserialize_number(value)
88
91
  else value
89
92
  end
90
93
  end
@@ -93,7 +96,7 @@ module Aws
93
96
  # @param [String, Integer] value
94
97
  # @return [Time]
95
98
  def time(value)
96
- value.is_a?(Numeric) ? Time.at(value) : Time.parse(value)
99
+ value.is_a?(Numeric) ? Time.at(value) : Aws::Util.deserialize_time(value)
97
100
  end
98
101
 
99
102
  def flattened_list?(shape)
@@ -107,6 +107,8 @@ module Aws
107
107
  # validate members
108
108
  member_ref = ref.shape.member
109
109
  values.each.with_index do |value, index|
110
+ next unless value
111
+
110
112
  shape(member_ref, value, errors, context + "[#{index}]")
111
113
  end
112
114
  end
@@ -122,6 +124,8 @@ module Aws
122
124
 
123
125
  values.each do |key, value|
124
126
  shape(key_ref, key, errors, "#{context} #{key.inspect} key")
127
+ next unless value
128
+
125
129
  shape(value_ref, value, errors, context + "[#{key.inspect}]")
126
130
  end
127
131
  end
@@ -12,18 +12,8 @@ module Aws
12
12
  class Handler < Seahorse::Client::Handler
13
13
 
14
14
  def call(context)
15
- apply_invocation_id(context)
16
- @handler.call(context)
17
- end
18
-
19
- private
20
-
21
- def apply_invocation_id(context)
22
15
  context.http_request.headers['amz-sdk-invocation-id'] = SecureRandom.uuid
23
- if context[:input_event_emitter]
24
- # only used for eventstreaming at input
25
- context.http_request.headers['x-amz-content-sha256'] = 'STREAMING-AWS4-HMAC-SHA256-EVENTS'
26
- end
16
+ @handler.call(context)
27
17
  end
28
18
 
29
19
  end
@@ -4,23 +4,10 @@ module Aws
4
4
  module Plugins
5
5
  module Protocols
6
6
  class RestJson < Seahorse::Client::Plugin
7
-
8
- class ContentTypeHandler < Seahorse::Client::Handler
9
- def call(context)
10
- body = context.http_request.body
11
- # Rest::Handler will set a default JSON body, so size can be checked
12
- # if this handler is run after serialization.
13
- if !body.respond_to?(:size) ||
14
- (body.respond_to?(:size) && body.size > 0)
15
- context.http_request.headers['Content-Type'] ||=
16
- 'application/json'
17
- end
18
- @handler.call(context)
19
- end
20
- end
21
-
22
7
  handler(Rest::Handler)
23
- handler(ContentTypeHandler, priority: 30)
8
+ # Rest::Handler will set a default JSON body, so size can be checked
9
+ # if this handler is run after serialization.
10
+ handler(Rest::ContentTypeHandler, priority: 30)
24
11
  handler(Json::ErrorHandler, step: :sign)
25
12
  end
26
13
 
@@ -4,10 +4,9 @@ module Aws
4
4
  module Plugins
5
5
  module Protocols
6
6
  class RestXml < Seahorse::Client::Plugin
7
-
8
7
  handler(Rest::Handler)
8
+ handler(Rest::ContentTypeHandler)
9
9
  handler(Xml::ErrorHandler, step: :sign)
10
-
11
10
  end
12
11
  end
13
12
  end
@@ -104,7 +104,7 @@ and 10485780 bytes inclusive.
104
104
  def update_content_encoding(encoding, context)
105
105
  headers = context.http_request.headers
106
106
  if headers['Content-Encoding']
107
- headers['Content-Encoding'] += ',' + encoding
107
+ headers['Content-Encoding'] += ", #{encoding}"
108
108
  else
109
109
  headers['Content-Encoding'] = encoding
110
110
  end
@@ -159,9 +159,14 @@ module Aws
159
159
  private
160
160
 
161
161
  def apply_authtype(context, req)
162
- if context.operation['authtype'].eql?('v4-unsigned-body') &&
163
- req.endpoint.scheme.eql?('https')
164
- req.headers['X-Amz-Content-Sha256'] ||= 'UNSIGNED-PAYLOAD'
162
+ # only used for eventstreaming at input
163
+ if context[:input_event_emitter]
164
+ req.headers['X-Amz-Content-Sha256'] = 'STREAMING-AWS4-HMAC-SHA256-EVENTS'
165
+ else
166
+ if context.operation['authtype'].eql?('v4-unsigned-body') &&
167
+ req.endpoint.scheme.eql?('https')
168
+ req.headers['X-Amz-Content-Sha256'] ||= 'UNSIGNED-PAYLOAD'
169
+ end
165
170
  end
166
171
  end
167
172
 
@@ -36,7 +36,7 @@ module Aws
36
36
  return
37
37
  end
38
38
  if flat?(ref)
39
- if name = query_name(member_ref)
39
+ if (name = query_name(ref))
40
40
  parts = prefix.split('.')
41
41
  parts.pop
42
42
  parts.push(name)
@@ -82,7 +82,7 @@ module Aws
82
82
  end
83
83
 
84
84
  def flat?(ref)
85
- ref.shape.flattened
85
+ ref[:flattened] || ref.shape.flattened
86
86
  end
87
87
 
88
88
  def timestamp(ref, value)
@@ -18,10 +18,13 @@ module Aws
18
18
  # @param [Hash] params
19
19
  def apply(http_req, params)
20
20
  body = build_body(params)
21
+
21
22
  # for rest-json, ensure we send at least an empty object
22
23
  # don't send an empty object for streaming? case.
23
- if body.nil? && @serializer_class == Json::Builder &&
24
- modeled_body? && !streaming?
24
+ if body.nil? &&
25
+ json_builder? &&
26
+ modeled_body? &&
27
+ !streaming?
25
28
  body = '{}'
26
29
  end
27
30
  http_req.body = body
@@ -45,13 +48,29 @@ module Aws
45
48
  params[@rules[:payload]]
46
49
  elsif @rules[:payload]
47
50
  params = params[@rules[:payload]]
48
- serialize(@rules[:payload_member], params) if params
51
+ if params
52
+ if xml_builder? &&
53
+ @rules.shape.member?(@rules[:payload_member].location_name)
54
+ # serializing payload member name for rest-xml is as follows:
55
+ # 1. Use the member locationName if the member value doesn't match the member's name (default)
56
+ # 2. Use the value of the locationName on the member's target if present
57
+ # 3. Use the shape name of the member's target
58
+ serialize(@rules[:payload_member], params, location_name: payload_location_name)
59
+ else
60
+ serialize(@rules[:payload_member], params)
61
+ end
62
+ end
49
63
  else
50
64
  params = body_params(params)
51
65
  serialize(@rules, params) unless params.empty?
52
66
  end
53
67
  end
54
68
 
69
+ def payload_location_name
70
+ @rules[:payload_member].shape['locationName'] ||
71
+ @rules[:payload_member].shape.name
72
+ end
73
+
55
74
  def streaming?
56
75
  @rules[:payload] && (
57
76
  BlobShape === @rules[:payload_member].shape ||
@@ -59,8 +78,16 @@ module Aws
59
78
  )
60
79
  end
61
80
 
62
- def serialize(rules, params)
63
- @serializer_class.new(rules).serialize(params)
81
+ def xml_builder?
82
+ @serializer_class == Xml::Builder
83
+ end
84
+
85
+ def json_builder?
86
+ @serializer_class == Json::Builder
87
+ end
88
+
89
+ def serialize(rules, params, location_name: nil)
90
+ @serializer_class.new(rules, location_name: location_name).serialize(params)
64
91
  end
65
92
 
66
93
  def body_params(params)
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module Rest
5
+ # NOTE: headers could be already populated if specified on input shape
6
+ class ContentTypeHandler < Seahorse::Client::Handler
7
+ def call(context)
8
+ if eventstream?(context)
9
+ context.http_request.headers['Content-Type'] ||=
10
+ 'application/vnd.amazon.eventstream'
11
+ elsif (payload = context.operation.input[:payload_member])
12
+ case payload.shape
13
+ when Seahorse::Model::Shapes::BlobShape
14
+ context.http_request.headers['Content-Type'] ||=
15
+ 'application/octet-stream'
16
+ when Seahorse::Model::Shapes::StringShape
17
+ context.http_request.headers['Content-Type'] ||=
18
+ 'text/plain'
19
+ else
20
+ apply_default_content_type(context)
21
+ end
22
+ elsif (body = context.http_request.body) &&
23
+ (!body.respond_to?(:size) || non_empty_body?(body))
24
+ apply_default_content_type(context)
25
+ end
26
+
27
+ @handler.call(context)
28
+ end
29
+
30
+ private
31
+
32
+ def non_empty_body?(body)
33
+ body.respond_to?(:size) && body.size.positive?
34
+ end
35
+
36
+ def eventstream?(context)
37
+ context.operation.input.shape.members.each do |_, ref|
38
+ return ref if ref.eventstream
39
+ end
40
+ false
41
+ end
42
+
43
+ # content-type defaults as noted here:
44
+ # rest-json: https://smithy.io/2.0/aws/protocols/aws-restxml-protocol.html#content-type
45
+ # rest-xml: https://smithy.io/2.0/aws/protocols/aws-restxml-protocol.html#content-type
46
+ def apply_default_content_type(context)
47
+ protocol = context.config.api.metadata['protocol']
48
+ case protocol
49
+ when 'rest-json'
50
+ context.http_request.headers['Content-Type'] ||=
51
+ 'application/json'
52
+ when 'rest-xml'
53
+ context.http_request.headers['Content-Type'] ||=
54
+ 'application/xml'
55
+ else raise "Unsupported protocol #{protocol}"
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -30,7 +30,7 @@ module Aws
30
30
  private
31
31
 
32
32
  def apply_path_params(uri, params)
33
- path = uri.path.sub(/\/$/, '') + @path_pattern.split('?')[0]
33
+ path = uri.path.sub(%r{/$}, '') + @path_pattern.split('?')[0]
34
34
  uri.path = path.gsub(/{.+?}/) do |placeholder|
35
35
  param_value_for_placeholder(placeholder, params)
36
36
  end
@@ -38,22 +38,40 @@ module Aws
38
38
 
39
39
  def param_value_for_placeholder(placeholder, params)
40
40
  name = param_name(placeholder)
41
- value = params[name].to_s
41
+ param_shape = @rules.shape.member(name).shape
42
+ value =
43
+ case param_shape
44
+ when Seahorse::Model::Shapes::TimestampShape
45
+ timestamp(param_shape, params[name]).to_s
46
+ else
47
+ params[name].to_s
48
+ end
49
+
42
50
  raise ArgumentError, ":#{name} must not be blank" if value.empty?
43
51
 
44
52
  if placeholder.include?('+')
45
- value.gsub(/[^\/]+/) { |v| escape(v) }
53
+ value.gsub(%r{[^/]+}) { |v| escape(v) }
46
54
  else
47
55
  escape(value)
48
56
  end
49
57
  end
50
58
 
51
59
  def param_name(placeholder)
52
- location_name = placeholder.gsub(/[{}+]/,'')
60
+ location_name = placeholder.gsub(/[{}+]/, '')
53
61
  param_name, _ = @rules.shape.member_by_location_name(location_name)
54
62
  param_name
55
63
  end
56
64
 
65
+ def timestamp(ref, value)
66
+ case ref['timestampFormat']
67
+ when 'unixTimestamp' then value.to_i
68
+ when 'rfc822' then value.utc.httpdate
69
+ else
70
+ # serializing as RFC 3399 date-time is the default
71
+ value.utc.iso8601
72
+ end
73
+ end
74
+
57
75
  def apply_querystring_params(uri, params)
58
76
  # collect params that are supposed to be part of the query string
59
77
  parts = @rules.shape.members.inject([]) do |prts, (member_name, member_ref)|
@@ -20,7 +20,8 @@ module Aws
20
20
  def apply(http_req, params)
21
21
  @rules.shape.members.each do |name, ref|
22
22
  value = params[name]
23
- next if value.nil?
23
+ next if value.nil? || ((ref.shape).is_a?(StringShape) && value.empty?)
24
+
24
25
  case ref.location
25
26
  when 'header' then apply_header_value(http_req.headers, ref, value)
26
27
  when 'headers' then apply_header_map(http_req.headers, ref, value)
@@ -49,12 +50,19 @@ module Aws
49
50
  end
50
51
  end
51
52
 
52
- def list(headers, ref, value)
53
- return if !value || value.empty?
54
- headers[ref.location_name] = value
55
- .compact
56
- .map { |s| Seahorse::Util.escape_header_list_string(s.to_s) }
57
- .join(',')
53
+ def list(headers, ref, values)
54
+ return if !values || values.empty?
55
+
56
+ member_ref = ref.shape.member
57
+ values = values.collect do |value|
58
+ case member_ref.shape
59
+ when TimestampShape
60
+ timestamp(member_ref, value).to_s
61
+ else
62
+ Seahorse::Util.escape_header_list_string(value.to_s)
63
+ end
64
+ end
65
+ headers[ref.location_name] = values.compact.join(', ')
58
66
  end
59
67
 
60
68
  def apply_header_map(headers, ref, values)