aws-sdk-core 3.191.5 → 3.193.0

Sign up to get free protection for your applications and to get access to all the features.
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)