aws-sdk-sqs 1.5.0 → 1.80.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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +505 -0
- data/LICENSE.txt +202 -0
- data/VERSION +1 -0
- data/lib/aws-sdk-sqs/client.rb +1435 -642
- data/lib/aws-sdk-sqs/client_api.rb +391 -46
- data/lib/aws-sdk-sqs/customizations.rb +2 -0
- data/lib/aws-sdk-sqs/endpoint_parameters.rb +66 -0
- data/lib/aws-sdk-sqs/endpoint_provider.rb +57 -0
- data/lib/aws-sdk-sqs/endpoints.rb +338 -0
- data/lib/aws-sdk-sqs/errors.rb +463 -1
- data/lib/aws-sdk-sqs/message.rb +40 -13
- data/lib/aws-sdk-sqs/plugins/endpoints.rb +116 -0
- data/lib/aws-sdk-sqs/plugins/md5s.rb +93 -42
- data/lib/aws-sdk-sqs/plugins/queue_urls.rb +26 -12
- data/lib/aws-sdk-sqs/queue.rb +324 -188
- data/lib/aws-sdk-sqs/queue_poller.rb +75 -37
- data/lib/aws-sdk-sqs/resource.rb +213 -97
- data/lib/aws-sdk-sqs/types.rb +1413 -645
- data/lib/aws-sdk-sqs.rb +16 -6
- data/sig/client.rbs +365 -0
- data/sig/errors.rbs +98 -0
- data/sig/message.rbs +73 -0
- data/sig/queue.rbs +164 -0
- data/sig/resource.rbs +106 -0
- data/sig/types.rbs +472 -0
- data/sig/waiters.rbs +13 -0
- metadata +33 -14
@@ -1,10 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'openssl'
|
2
4
|
|
3
5
|
module Aws
|
4
6
|
module SQS
|
5
7
|
module Plugins
|
6
8
|
class Md5s < Seahorse::Client::Plugin
|
7
|
-
|
8
9
|
# @api private
|
9
10
|
class Handler < Seahorse::Client::Handler
|
10
11
|
def call(context)
|
@@ -24,16 +25,17 @@ module Aws
|
|
24
25
|
'String' => 1,
|
25
26
|
'Binary' => 2,
|
26
27
|
'Number' => 1
|
27
|
-
}
|
28
|
+
}.freeze
|
28
29
|
|
29
|
-
DATA_TYPE = /\A(String|Binary|Number)(\..+)?\z
|
30
|
+
DATA_TYPE = /\A(String|Binary|Number)(\..+)?\z/.freeze
|
30
31
|
|
31
32
|
NORMALIZED_ENCODING = Encoding::UTF_8
|
32
33
|
|
33
34
|
def validate_send_message(context, response)
|
34
35
|
body = context.params[:message_body]
|
35
36
|
attributes = context.params[:message_attributes]
|
36
|
-
|
37
|
+
system_attributes = context.params[:message_system_attributes]
|
38
|
+
validate_single_message(body, attributes, system_attributes, response)
|
37
39
|
end
|
38
40
|
|
39
41
|
def validate_send_message_batch(context, response)
|
@@ -41,61 +43,87 @@ module Aws
|
|
41
43
|
id = entry[:id]
|
42
44
|
body = entry[:message_body]
|
43
45
|
attributes = entry[:message_attributes]
|
46
|
+
system_attributes = entry[:message_system_attributes]
|
44
47
|
message_response = response.successful.select { |r| r.id == id }[0]
|
45
48
|
unless message_response.nil?
|
46
|
-
validate_single_message(body, attributes, message_response)
|
49
|
+
validate_single_message(body, attributes, system_attributes, message_response)
|
47
50
|
end
|
48
51
|
end
|
49
52
|
end
|
50
53
|
|
51
|
-
def validate_single_message(body, attributes, response)
|
54
|
+
def validate_single_message(body, attributes, system_attributes, response)
|
52
55
|
validate_body(body, response)
|
53
|
-
|
56
|
+
unless attributes.nil? || attributes.empty?
|
57
|
+
validate_attributes(attributes, response)
|
58
|
+
end
|
59
|
+
unless system_attributes.nil? || system_attributes.empty?
|
60
|
+
validate_system_attributes(system_attributes, response)
|
61
|
+
end
|
54
62
|
end
|
55
63
|
|
56
64
|
def validate_body(body, response)
|
57
65
|
calculated_md5 = md5_of_message_body(body)
|
58
66
|
returned_md5 = response.md5_of_message_body
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
+
return unless calculated_md5 != returned_md5
|
68
|
+
|
69
|
+
error_message = mismatch_error_message(
|
70
|
+
'message body',
|
71
|
+
calculated_md5,
|
72
|
+
returned_md5,
|
73
|
+
response
|
74
|
+
)
|
75
|
+
raise Aws::Errors::ChecksumError, error_message
|
67
76
|
end
|
68
77
|
|
69
78
|
def validate_attributes(attributes, response)
|
70
79
|
calculated_md5 = md5_of_message_attributes(attributes)
|
71
80
|
returned_md5 = response.md5_of_message_attributes
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
81
|
+
return unless returned_md5 != calculated_md5
|
82
|
+
|
83
|
+
error_message = mismatch_error_message(
|
84
|
+
'message attributes',
|
85
|
+
calculated_md5,
|
86
|
+
returned_md5,
|
87
|
+
response
|
88
|
+
)
|
89
|
+
raise Aws::Errors::ChecksumError, error_message
|
90
|
+
end
|
91
|
+
|
92
|
+
def validate_system_attributes(system_attributes, response)
|
93
|
+
calculated_md5 = md5_of_message_system_attributes(system_attributes)
|
94
|
+
returned_md5 = response.md5_of_message_system_attributes
|
95
|
+
return unless returned_md5 != calculated_md5
|
96
|
+
|
97
|
+
error_message = mismatch_error_message(
|
98
|
+
'message system attributes',
|
99
|
+
calculated_md5,
|
100
|
+
returned_md5,
|
101
|
+
response
|
102
|
+
)
|
103
|
+
raise Aws::Errors::ChecksumError, error_message
|
80
104
|
end
|
81
105
|
|
82
106
|
def md5_of_message_body(message_body)
|
83
107
|
OpenSSL::Digest::MD5.hexdigest(message_body)
|
84
108
|
end
|
85
109
|
|
110
|
+
# MD5 of Message Attributes and System Attributes are effectively
|
111
|
+
# the same calculation. However, keeping these as two methods because
|
112
|
+
# they are modeled as two different shapes.
|
113
|
+
###
|
86
114
|
def md5_of_message_attributes(message_attributes)
|
87
|
-
encoded = {
|
115
|
+
encoded = {}
|
88
116
|
message_attributes.each do |name, attribute|
|
89
117
|
name = name.to_s
|
90
118
|
encoded[name] = String.new
|
91
119
|
data_type_without_label = DATA_TYPE.match(attribute[:data_type])[1]
|
92
120
|
encoded[name] << encode_length_and_bytes(name) <<
|
93
|
-
|
94
|
-
|
121
|
+
encode_length_and_bytes(attribute[:data_type]) <<
|
122
|
+
[TRANSPORT_TYPE_ENCODINGS[data_type_without_label]].pack('C')
|
95
123
|
|
96
|
-
if attribute[:string_value]
|
124
|
+
if !attribute[:string_value].nil?
|
97
125
|
encoded[name] << encode_length_and_string(attribute[:string_value])
|
98
|
-
elsif attribute[:binary_value]
|
126
|
+
elsif !attribute[:binary_value].nil?
|
99
127
|
encoded[name] << encode_length_and_bytes(attribute[:binary_value])
|
100
128
|
end
|
101
129
|
end
|
@@ -106,6 +134,30 @@ module Aws
|
|
106
134
|
OpenSSL::Digest::MD5.hexdigest(buffer)
|
107
135
|
end
|
108
136
|
|
137
|
+
def md5_of_message_system_attributes(message_system_attributes)
|
138
|
+
encoded = {}
|
139
|
+
message_system_attributes.each do |name, attribute|
|
140
|
+
name = name.to_s
|
141
|
+
encoded[name] = String.new
|
142
|
+
data_type_without_label = DATA_TYPE.match(attribute[:data_type])[1]
|
143
|
+
encoded[name] << encode_length_and_bytes(name) <<
|
144
|
+
encode_length_and_bytes(attribute[:data_type]) <<
|
145
|
+
[TRANSPORT_TYPE_ENCODINGS[data_type_without_label]].pack('C')
|
146
|
+
|
147
|
+
if !attribute[:string_value].nil?
|
148
|
+
encoded[name] << encode_length_and_string(attribute[:string_value])
|
149
|
+
elsif !attribute[:binary_value].nil?
|
150
|
+
encoded[name] << encode_length_and_bytes(attribute[:binary_value])
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
buffer = encoded.keys.sort.reduce(String.new) do |string, name|
|
155
|
+
string << encoded[name]
|
156
|
+
end
|
157
|
+
OpenSSL::Digest::MD5.hexdigest(buffer)
|
158
|
+
end
|
159
|
+
###
|
160
|
+
|
109
161
|
def encode_length_and_string(string)
|
110
162
|
string = String.new(string)
|
111
163
|
string.encode!(NORMALIZED_ENCODING)
|
@@ -113,18 +165,16 @@ module Aws
|
|
113
165
|
end
|
114
166
|
|
115
167
|
def encode_length_and_bytes(bytes)
|
116
|
-
[bytes.bytesize, bytes].pack('L>a*'
|
168
|
+
[bytes.bytesize, bytes].pack('L>a*')
|
117
169
|
end
|
118
170
|
|
119
171
|
def mismatch_error_message(section, local_md5, returned_md5, response)
|
120
|
-
m =
|
121
|
-
|
122
|
-
|
172
|
+
m = 'MD5 returned by SQS does not match '\
|
173
|
+
'the calculation on the original request. ('
|
123
174
|
if response.respond_to?(:id) && !response.id.nil?
|
124
|
-
m
|
175
|
+
m = "#{m}Message ID: #{response.id}, "
|
125
176
|
end
|
126
|
-
|
127
|
-
m << "MD5 calculated by the #{section}: " <<
|
177
|
+
"#{m}MD5 calculated by the #{section}: "\
|
128
178
|
"'#{local_md5}', MD5 checksum returned: '#{returned_md5}')"
|
129
179
|
end
|
130
180
|
end
|
@@ -152,13 +202,14 @@ not match.
|
|
152
202
|
end
|
153
203
|
|
154
204
|
def add_handlers(handlers, config)
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
205
|
+
return unless config.verify_checksums
|
206
|
+
|
207
|
+
handlers.add(
|
208
|
+
Handler,
|
209
|
+
priority: 10,
|
210
|
+
step: :validate,
|
211
|
+
operations: %i[send_message send_message_batch]
|
212
|
+
)
|
162
213
|
end
|
163
214
|
end
|
164
215
|
end
|
@@ -1,13 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Aws
|
2
4
|
module SQS
|
3
5
|
module Plugins
|
4
6
|
# @api private
|
5
7
|
class QueueUrls < Seahorse::Client::Plugin
|
6
|
-
|
8
|
+
# Extract region from a provided queue_url
|
7
9
|
class Handler < Seahorse::Client::Handler
|
8
|
-
|
9
10
|
def call(context)
|
10
|
-
if queue_url = context.params[:queue_url]
|
11
|
+
if (queue_url = context.params[:queue_url])
|
11
12
|
update_endpoint(context, queue_url)
|
12
13
|
update_region(context, queue_url)
|
13
14
|
end
|
@@ -19,18 +20,31 @@ module Aws
|
|
19
20
|
end
|
20
21
|
|
21
22
|
# If the region in the queue url is not the configured
|
22
|
-
# region, then we will modify
|
23
|
-
# a sigv4 signer for the proper region.
|
23
|
+
# region, then we will modify signing to use it
|
24
24
|
def update_region(context, queue_url)
|
25
|
-
if queue_region = queue_url
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
25
|
+
if (queue_region = parse_region(queue_url)) &&
|
26
|
+
queue_region != context.config.region
|
27
|
+
context[:auth_scheme]['signingRegion'] = queue_region
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
# take the first component after the SQS service component
|
34
|
+
# Will return us-east-1 for:
|
35
|
+
# https://sqs.us-east-1.amazonaws.com/1234567890/demo
|
36
|
+
# https://vpce-x-y.sqs.us-east-1.vpce.amazonaws.com/1234567890/demo
|
37
|
+
# Will not return for:
|
38
|
+
# https://localstack-sqs.example.dev/queue/example
|
39
|
+
def parse_region(url)
|
40
|
+
parts = URI.parse(url).host.split('.')
|
41
|
+
parts.each_with_index do |part, index|
|
42
|
+
if part == 'sqs'
|
43
|
+
# assume region is the part right after the 'sqs' part
|
44
|
+
return parts[index + 1]
|
32
45
|
end
|
33
46
|
end
|
47
|
+
nil # no region found
|
34
48
|
end
|
35
49
|
|
36
50
|
end
|