aws-sdk-resources 2.11.632 → 3.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +5 -5
  2. data/lib/aws-sdk-resources.rb +1 -91
  3. metadata +14 -85
  4. data/lib/aws-sdk-resources/batch.rb +0 -143
  5. data/lib/aws-sdk-resources/builder.rb +0 -85
  6. data/lib/aws-sdk-resources/builder_sources.rb +0 -105
  7. data/lib/aws-sdk-resources/collection.rb +0 -107
  8. data/lib/aws-sdk-resources/definition.rb +0 -331
  9. data/lib/aws-sdk-resources/documenter.rb +0 -70
  10. data/lib/aws-sdk-resources/documenter/base_operation_documenter.rb +0 -279
  11. data/lib/aws-sdk-resources/documenter/data_operation_documenter.rb +0 -25
  12. data/lib/aws-sdk-resources/documenter/has_many_operation_documenter.rb +0 -69
  13. data/lib/aws-sdk-resources/documenter/has_operation_documenter.rb +0 -66
  14. data/lib/aws-sdk-resources/documenter/operation_documenter.rb +0 -20
  15. data/lib/aws-sdk-resources/documenter/resource_operation_documenter.rb +0 -53
  16. data/lib/aws-sdk-resources/documenter/waiter_operation_documenter.rb +0 -77
  17. data/lib/aws-sdk-resources/errors.rb +0 -15
  18. data/lib/aws-sdk-resources/operation_methods.rb +0 -83
  19. data/lib/aws-sdk-resources/operations.rb +0 -280
  20. data/lib/aws-sdk-resources/options.rb +0 -17
  21. data/lib/aws-sdk-resources/request.rb +0 -39
  22. data/lib/aws-sdk-resources/request_params.rb +0 -140
  23. data/lib/aws-sdk-resources/resource.rb +0 -243
  24. data/lib/aws-sdk-resources/services/ec2.rb +0 -21
  25. data/lib/aws-sdk-resources/services/ec2/instance.rb +0 -29
  26. data/lib/aws-sdk-resources/services/iam.rb +0 -19
  27. data/lib/aws-sdk-resources/services/s3.rb +0 -21
  28. data/lib/aws-sdk-resources/services/s3/bucket.rb +0 -131
  29. data/lib/aws-sdk-resources/services/s3/encryption.rb +0 -24
  30. data/lib/aws-sdk-resources/services/s3/encryption/client.rb +0 -386
  31. data/lib/aws-sdk-resources/services/s3/encryption/decrypt_handler.rb +0 -225
  32. data/lib/aws-sdk-resources/services/s3/encryption/default_cipher_provider.rb +0 -101
  33. data/lib/aws-sdk-resources/services/s3/encryption/default_key_provider.rb +0 -40
  34. data/lib/aws-sdk-resources/services/s3/encryption/encrypt_handler.rb +0 -61
  35. data/lib/aws-sdk-resources/services/s3/encryption/errors.rb +0 -15
  36. data/lib/aws-sdk-resources/services/s3/encryption/io_auth_decrypter.rb +0 -58
  37. data/lib/aws-sdk-resources/services/s3/encryption/io_decrypter.rb +0 -37
  38. data/lib/aws-sdk-resources/services/s3/encryption/io_encrypter.rb +0 -71
  39. data/lib/aws-sdk-resources/services/s3/encryption/key_provider.rb +0 -31
  40. data/lib/aws-sdk-resources/services/s3/encryption/kms_cipher_provider.rb +0 -104
  41. data/lib/aws-sdk-resources/services/s3/encryption/materials.rb +0 -60
  42. data/lib/aws-sdk-resources/services/s3/encryption/utils.rb +0 -104
  43. data/lib/aws-sdk-resources/services/s3/encryptionV2/client.rb +0 -561
  44. data/lib/aws-sdk-resources/services/s3/encryptionV2/decrypt_handler.rb +0 -214
  45. data/lib/aws-sdk-resources/services/s3/encryptionV2/default_cipher_provider.rb +0 -170
  46. data/lib/aws-sdk-resources/services/s3/encryptionV2/default_key_provider.rb +0 -40
  47. data/lib/aws-sdk-resources/services/s3/encryptionV2/encrypt_handler.rb +0 -69
  48. data/lib/aws-sdk-resources/services/s3/encryptionV2/errors.rb +0 -37
  49. data/lib/aws-sdk-resources/services/s3/encryptionV2/io_auth_decrypter.rb +0 -58
  50. data/lib/aws-sdk-resources/services/s3/encryptionV2/io_decrypter.rb +0 -37
  51. data/lib/aws-sdk-resources/services/s3/encryptionV2/io_encrypter.rb +0 -73
  52. data/lib/aws-sdk-resources/services/s3/encryptionV2/key_provider.rb +0 -31
  53. data/lib/aws-sdk-resources/services/s3/encryptionV2/kms_cipher_provider.rb +0 -169
  54. data/lib/aws-sdk-resources/services/s3/encryptionV2/materials.rb +0 -60
  55. data/lib/aws-sdk-resources/services/s3/encryptionV2/utils.rb +0 -103
  56. data/lib/aws-sdk-resources/services/s3/encryption_v2.rb +0 -24
  57. data/lib/aws-sdk-resources/services/s3/file_downloader.rb +0 -169
  58. data/lib/aws-sdk-resources/services/s3/file_part.rb +0 -75
  59. data/lib/aws-sdk-resources/services/s3/file_uploader.rb +0 -58
  60. data/lib/aws-sdk-resources/services/s3/multipart_file_uploader.rb +0 -187
  61. data/lib/aws-sdk-resources/services/s3/multipart_upload.rb +0 -42
  62. data/lib/aws-sdk-resources/services/s3/multipart_upload_error.rb +0 -16
  63. data/lib/aws-sdk-resources/services/s3/object.rb +0 -290
  64. data/lib/aws-sdk-resources/services/s3/object_copier.rb +0 -99
  65. data/lib/aws-sdk-resources/services/s3/object_multipart_copier.rb +0 -180
  66. data/lib/aws-sdk-resources/services/s3/object_summary.rb +0 -73
  67. data/lib/aws-sdk-resources/services/s3/presigned_post.rb +0 -651
  68. data/lib/aws-sdk-resources/services/sns.rb +0 -7
  69. data/lib/aws-sdk-resources/services/sns/message_verifier.rb +0 -171
  70. data/lib/aws-sdk-resources/services/sqs.rb +0 -7
  71. data/lib/aws-sdk-resources/services/sqs/queue_poller.rb +0 -521
  72. data/lib/aws-sdk-resources/source.rb +0 -39
@@ -1,214 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'base64'
4
-
5
- module Aws
6
- module S3
7
- module EncryptionV2
8
- # @api private
9
- class DecryptHandler < Seahorse::Client::Handler
10
-
11
- V1_ENVELOPE_KEYS = %w(
12
- x-amz-key
13
- x-amz-iv
14
- x-amz-matdesc
15
- )
16
-
17
- V2_ENVELOPE_KEYS = %w(
18
- x-amz-key-v2
19
- x-amz-iv
20
- x-amz-cek-alg
21
- x-amz-wrap-alg
22
- x-amz-matdesc
23
- )
24
-
25
- V2_OPTIONAL_KEYS = %w(x-amz-tag-len)
26
-
27
- POSSIBLE_ENVELOPE_KEYS = (V1_ENVELOPE_KEYS +
28
- V2_ENVELOPE_KEYS + V2_OPTIONAL_KEYS).uniq
29
-
30
- POSSIBLE_WRAPPING_FORMATS = %w(
31
- AES/GCM
32
- kms
33
- kms+context
34
- RSA-OAEP-SHA1
35
- )
36
-
37
- POSSIBLE_ENCRYPTION_FORMATS = %w(
38
- AES/GCM/NoPadding
39
- AES/CBC/PKCS5Padding
40
- AES/CBC/PKCS7Padding
41
- )
42
-
43
- AUTH_REQUIRED_CEK_ALGS = %w(AES/GCM/NoPadding)
44
-
45
- def call(context)
46
- attach_http_event_listeners(context)
47
- apply_cse_user_agent(context)
48
- @handler.call(context)
49
- end
50
-
51
- private
52
-
53
- def attach_http_event_listeners(context)
54
-
55
- context.http_response.on_headers(200) do
56
- cipher, envelope = decryption_cipher(context)
57
- decrypter = body_contains_auth_tag?(envelope) ?
58
- authenticated_decrypter(context, cipher, envelope) :
59
- IODecrypter.new(cipher, context.http_response.body)
60
- context.http_response.body = decrypter
61
- end
62
-
63
- context.http_response.on_success(200) do
64
- decrypter = context.http_response.body
65
- decrypter.finalize
66
- decrypter.io.rewind if decrypter.io.respond_to?(:rewind)
67
- context.http_response.body = decrypter.io
68
- end
69
-
70
- context.http_response.on_error do
71
- if context.http_response.body.respond_to?(:io)
72
- context.http_response.body = context.http_response.body.io
73
- end
74
- end
75
- end
76
-
77
- def decryption_cipher(context)
78
- if (envelope = get_encryption_envelope(context))
79
- cipher = context[:encryption][:cipher_provider]
80
- .decryption_cipher(
81
- envelope,
82
- context[:encryption]
83
- )
84
- [cipher, envelope]
85
- else
86
- raise Errors::DecryptionError, "unable to locate encryption envelope"
87
- end
88
- end
89
-
90
- def get_encryption_envelope(context)
91
- if context[:encryption][:envelope_location] == :metadata
92
- envelope_from_metadata(context) || envelope_from_instr_file(context)
93
- else
94
- envelope_from_instr_file(context) || envelope_from_metadata(context)
95
- end
96
- end
97
-
98
- def envelope_from_metadata(context)
99
- possible_envelope = {}
100
- POSSIBLE_ENVELOPE_KEYS.each do |suffix|
101
- if value = context.http_response.headers["x-amz-meta-#{suffix}"]
102
- possible_envelope[suffix] = value
103
- end
104
- end
105
- extract_envelope(possible_envelope)
106
- end
107
-
108
- def envelope_from_instr_file(context)
109
- suffix = context[:encryption][:instruction_file_suffix]
110
- possible_envelope = Json.load(context.client.get_object(
111
- bucket: context.params[:bucket],
112
- key: context.params[:key] + suffix
113
- ).body.read)
114
- extract_envelope(possible_envelope)
115
- rescue S3::Errors::ServiceError, Json::ParseError
116
- nil
117
- end
118
-
119
- def extract_envelope(hash)
120
- return nil unless hash
121
- return v1_envelope(hash) if hash.key?('x-amz-key')
122
- return v2_envelope(hash) if hash.key?('x-amz-key-v2')
123
- if hash.keys.any? { |key| key.match(/^x-amz-key-(.+)$/) }
124
- msg = "unsupported envelope encryption version #{$1}"
125
- raise Errors::DecryptionError, msg
126
- end
127
- end
128
-
129
- def v1_envelope(envelope)
130
- envelope
131
- end
132
-
133
- def v2_envelope(envelope)
134
- unless POSSIBLE_ENCRYPTION_FORMATS.include? envelope['x-amz-cek-alg']
135
- alg = envelope['x-amz-cek-alg'].inspect
136
- msg = "unsupported content encrypting key (cek) format: #{alg}"
137
- raise Errors::DecryptionError, msg
138
- end
139
- unless POSSIBLE_WRAPPING_FORMATS.include? envelope['x-amz-wrap-alg']
140
- alg = envelope['x-amz-wrap-alg'].inspect
141
- msg = "unsupported key wrapping algorithm: #{alg}"
142
- raise Errors::DecryptionError, msg
143
- end
144
- unless (missing_keys = V2_ENVELOPE_KEYS - envelope.keys).empty?
145
- msg = "incomplete v2 encryption envelope:\n"
146
- msg += " missing: #{missing_keys.join(',')}\n"
147
- raise Errors::DecryptionError, msg
148
- end
149
- envelope
150
- end
151
-
152
- # This method fetches the tag from the end of the object by
153
- # making a GET Object w/range request. This auth tag is used
154
- # to initialize the cipher, and the decrypter truncates the
155
- # auth tag from the body when writing the final bytes.
156
- def authenticated_decrypter(context, cipher, envelope)
157
- if RUBY_VERSION.match(/1.9/)
158
- raise "authenticated decryption not supported by OpenSSL in Ruby version ~> 1.9"
159
- raise Aws::Errors::NonSupportedRubyVersionError, msg
160
- end
161
- http_resp = context.http_response
162
- content_length = http_resp.headers['content-length'].to_i
163
- auth_tag_length = auth_tag_length(envelope)
164
-
165
- auth_tag = context.client.get_object(
166
- bucket: context.params[:bucket],
167
- key: context.params[:key],
168
- range: "bytes=-#{auth_tag_length}"
169
- ).body.read
170
-
171
- cipher.auth_tag = auth_tag
172
- cipher.auth_data = ''
173
-
174
- # The encrypted object contains both the cipher text
175
- # plus a trailing auth tag.
176
- IOAuthDecrypter.new(
177
- io: http_resp.body,
178
- encrypted_content_length: content_length - auth_tag_length,
179
- cipher: cipher)
180
- end
181
-
182
- def body_contains_auth_tag?(envelope)
183
- AUTH_REQUIRED_CEK_ALGS.include?(envelope['x-amz-cek-alg'])
184
- end
185
-
186
- # Determine the auth tag length from the algorithm
187
- # Validate it against the value provided in the x-amz-tag-len
188
- # Return the tag length in bytes
189
- def auth_tag_length(envelope)
190
- tag_length =
191
- case envelope['x-amz-cek-alg']
192
- when 'AES/GCM/NoPadding' then AES_GCM_TAG_LEN_BYTES
193
- else
194
- raise ArgumentError, 'Unsupported cek-alg: ' \
195
- "#{envelope['x-amz-cek-alg']}"
196
- end
197
- if (tag_length * 8) != envelope['x-amz-tag-len'].to_i
198
- raise Errors::DecryptionError, 'x-amz-tag-len does not match expected'
199
- end
200
- tag_length
201
- end
202
-
203
- def apply_cse_user_agent(context)
204
- if context.config.user_agent_suffix.nil?
205
- context.config.user_agent_suffix = EC_USER_AGENT
206
- elsif !context.config.user_agent_suffix.include? EC_USER_AGENT
207
- context.config.user_agent_suffix += " #{EC_USER_AGENT}"
208
- end
209
- end
210
-
211
- end
212
- end
213
- end
214
- end
@@ -1,170 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'base64'
4
-
5
- module Aws
6
- module S3
7
- module EncryptionV2
8
- # @api private
9
- class DefaultCipherProvider
10
-
11
- def initialize(options = {})
12
- @key_provider = options[:key_provider]
13
- @key_wrap_schema = validate_key_wrap(
14
- options[:key_wrap_schema],
15
- @key_provider.encryption_materials.key
16
- )
17
- @content_encryption_schema = validate_cek(
18
- options[:content_encryption_schema]
19
- )
20
- end
21
-
22
- # @return [Array<Hash,Cipher>] Creates an returns a new encryption
23
- # envelope and encryption cipher.
24
- def encryption_cipher(options = {})
25
- validate_options(options)
26
- cipher = Utils.aes_encryption_cipher(:GCM)
27
- if @key_provider.encryption_materials.key.is_a? OpenSSL::PKey::RSA
28
- enc_key = encode64(
29
- encrypt_rsa(envelope_key(cipher), @content_encryption_schema)
30
- )
31
- else
32
- enc_key = encode64(
33
- encrypt_aes_gcm(envelope_key(cipher), @content_encryption_schema)
34
- )
35
- end
36
- envelope = {
37
- 'x-amz-key-v2' => enc_key,
38
- 'x-amz-cek-alg' => @content_encryption_schema,
39
- 'x-amz-tag-len' => (AES_GCM_TAG_LEN_BYTES * 8).to_s,
40
- 'x-amz-wrap-alg' => @key_wrap_schema,
41
- 'x-amz-iv' => encode64(envelope_iv(cipher)),
42
- 'x-amz-matdesc' => materials_description
43
- }
44
- cipher.auth_data = '' # auth_data must be set after key and iv
45
- [envelope, cipher]
46
- end
47
-
48
- # @return [Cipher] Given an encryption envelope, returns a
49
- # decryption cipher.
50
- def decryption_cipher(envelope, options = {})
51
- validate_options(options)
52
- master_key = @key_provider.key_for(envelope['x-amz-matdesc'])
53
- if envelope.key? 'x-amz-key'
54
- unless options[:security_profile] == :v2_and_legacy
55
- raise Errors::LegacyDecryptionError
56
- end
57
- # Support for decryption of legacy objects
58
- key = Utils.decrypt(master_key, decode64(envelope['x-amz-key']))
59
- iv = decode64(envelope['x-amz-iv'])
60
- Utils.aes_decryption_cipher(:CBC, key, iv)
61
- else
62
- if envelope['x-amz-cek-alg'] != 'AES/GCM/NoPadding'
63
- raise ArgumentError, 'Unsupported cek-alg: ' \
64
- "#{envelope['x-amz-cek-alg']}"
65
- end
66
- key =
67
- case envelope['x-amz-wrap-alg']
68
- when 'AES/GCM'
69
- if master_key.is_a? OpenSSL::PKey::RSA
70
- raise ArgumentError, 'Key mismatch - Client is configured' \
71
- ' with an RSA key and the x-amz-wrap-alg is AES/GCM.'
72
- end
73
- Utils.decrypt_aes_gcm(master_key,
74
- decode64(envelope['x-amz-key-v2']),
75
- envelope['x-amz-cek-alg'])
76
- when 'RSA-OAEP-SHA1'
77
- unless master_key.is_a? OpenSSL::PKey::RSA
78
- raise ArgumentError, 'Key mismatch - Client is configured' \
79
- ' with an AES key and the x-amz-wrap-alg is RSA-OAEP-SHA1.'
80
- end
81
- key, cek_alg = Utils.decrypt_rsa(master_key, decode64(envelope['x-amz-key-v2']))
82
- raise Errors::CEKAlgMismatchError unless cek_alg == envelope['x-amz-cek-alg']
83
- key
84
- when 'kms+context'
85
- raise ArgumentError, 'Key mismatch - Client is configured' \
86
- ' with a user provided key and the x-amz-wrap-alg is' \
87
- ' kms+context. Please configure the client with the' \
88
- ' required kms_key_id'
89
- else
90
- raise ArgumentError, 'Unsupported wrap-alg: ' \
91
- "#{envelope['x-amz-wrap-alg']}"
92
- end
93
- iv = decode64(envelope['x-amz-iv'])
94
- Utils.aes_decryption_cipher(:GCM, key, iv)
95
- end
96
- end
97
-
98
- private
99
-
100
- # Validate that the key_wrap_schema
101
- # is valid, supported and matches the provided key.
102
- # Returns the string version for the x-amz-key-wrap-alg
103
- def validate_key_wrap(key_wrap_schema, key)
104
- if key.is_a? OpenSSL::PKey::RSA
105
- unless key_wrap_schema == :rsa_oaep_sha1
106
- raise ArgumentError, ':key_wrap_schema must be set to :rsa_oaep_sha1 for RSA keys.'
107
- end
108
- else
109
- unless key_wrap_schema == :aes_gcm
110
- raise ArgumentError, ':key_wrap_schema must be set to :aes_gcm for AES keys.'
111
- end
112
- end
113
-
114
- case key_wrap_schema
115
- when :rsa_oaep_sha1 then 'RSA-OAEP-SHA1'
116
- when :aes_gcm then 'AES/GCM'
117
- when :kms_context
118
- raise ArgumentError, 'A kms_key_id is required when using :kms_context.'
119
- else
120
- raise ArgumentError, "Unsupported key_wrap_schema: #{key_wrap_schema}"
121
- end
122
- end
123
-
124
- def validate_cek(content_encryption_schema)
125
- case content_encryption_schema
126
- when :aes_gcm_no_padding
127
- "AES/GCM/NoPadding"
128
- else
129
- raise ArgumentError, "Unsupported content_encryption_schema: #{content_encryption_schema}"
130
- end
131
- end
132
-
133
- def envelope_key(cipher)
134
- cipher.key = cipher.random_key
135
- end
136
-
137
- def envelope_iv(cipher)
138
- cipher.iv = cipher.random_iv
139
- end
140
-
141
- def encrypt_aes_gcm(data, auth_data)
142
- Utils.encrypt_aes_gcm(@key_provider.encryption_materials.key, data, auth_data)
143
- end
144
-
145
- def encrypt_rsa(data, auth_data)
146
- Utils.encrypt_rsa(@key_provider.encryption_materials.key, data, auth_data)
147
- end
148
-
149
- def materials_description
150
- @key_provider.encryption_materials.description
151
- end
152
-
153
- def encode64(str)
154
- Base64.encode64(str).split("\n") * ''
155
- end
156
-
157
- def decode64(str)
158
- Base64.decode64(str)
159
- end
160
-
161
- def validate_options(options)
162
- if !options[:kms_encryption_context].nil?
163
- raise ArgumentError, 'Cannot provide :kms_encryption_context ' \
164
- 'with non KMS client.'
165
- end
166
- end
167
- end
168
- end
169
- end
170
- end
@@ -1,40 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Aws
4
- module S3
5
- module EncryptionV2
6
-
7
- # The default key provider is constructed with a single key
8
- # that is used for both encryption and decryption, ignoring
9
- # the possible per-object envelope encryption materials description.
10
- # @api private
11
- class DefaultKeyProvider
12
-
13
- include KeyProvider
14
-
15
- # @option options [required, OpenSSL::PKey::RSA, String] :encryption_key
16
- # The master key to use for encrypting objects.
17
- # @option options [String<JSON>] :materials_description ('{}')
18
- # A description of the encryption key.
19
- def initialize(options = {})
20
- @encryption_materials = Materials.new(
21
- key: options[:encryption_key],
22
- description: options[:materials_description] || '{}'
23
- )
24
- end
25
-
26
- # @return [Materials]
27
- def encryption_materials
28
- @encryption_materials
29
- end
30
-
31
- # @param [String<JSON>] materials_description
32
- # @return Returns the key given in the constructor.
33
- def key_for(materials_description)
34
- @encryption_materials.key
35
- end
36
-
37
- end
38
- end
39
- end
40
- end
@@ -1,69 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'base64'
4
-
5
- module Aws
6
- module S3
7
- module EncryptionV2
8
- # @api private
9
- class EncryptHandler < Seahorse::Client::Handler
10
-
11
- def call(context)
12
- if RUBY_VERSION.match(/1.9/)
13
- raise "authenticated encryption not supported by OpenSSL in Ruby version ~> 1.9"
14
- raise Aws::Errors::NonSupportedRubyVersionError, msg
15
- end
16
- envelope, cipher = context[:encryption][:cipher_provider]
17
- .encryption_cipher(
18
- kms_encryption_context: context[:encryption][:kms_encryption_context]
19
- )
20
- context[:encryption][:cipher] = cipher
21
- apply_encryption_envelope(context, envelope)
22
- apply_encryption_cipher(context, cipher)
23
- apply_cse_user_agent(context)
24
- @handler.call(context)
25
- end
26
-
27
- private
28
-
29
- def apply_encryption_envelope(context, envelope)
30
- if context[:encryption][:envelope_location] == :instruction_file
31
- suffix = context[:encryption][:instruction_file_suffix]
32
- context.client.put_object(
33
- bucket: context.params[:bucket],
34
- key: context.params[:key] + suffix,
35
- body: Json.dump(envelope)
36
- )
37
- else # :metadata
38
- context.params[:metadata] ||= {}
39
- context.params[:metadata].update(envelope)
40
- end
41
- end
42
-
43
- def apply_encryption_cipher(context, cipher)
44
- io = context.params[:body] || ''
45
- io = StringIO.new(io) if io.is_a? String
46
- context.params[:body] = IOEncrypter.new(cipher, io)
47
- context.params[:metadata] ||= {}
48
- context.params[:metadata]['x-amz-unencrypted-content-length'] = io.size
49
- if context.params.delete(:content_md5)
50
- raise ArgumentError, 'Setting content_md5 on client side '\
51
- 'encrypted objects is deprecated.'
52
- end
53
- context.http_response.on_headers do
54
- context.params[:body].close
55
- end
56
- end
57
-
58
- def apply_cse_user_agent(context)
59
- if context.config.user_agent_suffix.nil?
60
- context.config.user_agent_suffix = EC_USER_AGENT
61
- elsif !context.config.user_agent_suffix.include? EC_USER_AGENT
62
- context.config.user_agent_suffix += " #{EC_USER_AGENT}"
63
- end
64
- end
65
-
66
- end
67
- end
68
- end
69
- end