aws-sdk-s3 1.21.0 → 1.117.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +930 -0
  3. data/LICENSE.txt +202 -0
  4. data/VERSION +1 -0
  5. data/lib/aws-sdk-s3/bucket.rb +393 -75
  6. data/lib/aws-sdk-s3/bucket_acl.rb +57 -14
  7. data/lib/aws-sdk-s3/bucket_cors.rb +67 -13
  8. data/lib/aws-sdk-s3/bucket_lifecycle.rb +54 -15
  9. data/lib/aws-sdk-s3/bucket_lifecycle_configuration.rb +56 -15
  10. data/lib/aws-sdk-s3/bucket_logging.rb +52 -15
  11. data/lib/aws-sdk-s3/bucket_notification.rb +47 -17
  12. data/lib/aws-sdk-s3/bucket_policy.rb +51 -13
  13. data/lib/aws-sdk-s3/bucket_region_cache.rb +2 -0
  14. data/lib/aws-sdk-s3/bucket_request_payment.rb +51 -12
  15. data/lib/aws-sdk-s3/bucket_tagging.rb +59 -13
  16. data/lib/aws-sdk-s3/bucket_versioning.rb +118 -12
  17. data/lib/aws-sdk-s3/bucket_website.rb +66 -13
  18. data/lib/aws-sdk-s3/client.rb +11422 -2518
  19. data/lib/aws-sdk-s3/client_api.rb +1196 -155
  20. data/lib/aws-sdk-s3/customizations/bucket.rb +53 -36
  21. data/lib/aws-sdk-s3/customizations/multipart_upload.rb +2 -0
  22. data/lib/aws-sdk-s3/customizations/object.rb +200 -62
  23. data/lib/aws-sdk-s3/customizations/object_summary.rb +5 -0
  24. data/lib/aws-sdk-s3/customizations/types/list_object_versions_output.rb +2 -0
  25. data/lib/aws-sdk-s3/customizations.rb +4 -1
  26. data/lib/aws-sdk-s3/encryption/client.rb +23 -6
  27. data/lib/aws-sdk-s3/encryption/decrypt_handler.rb +71 -29
  28. data/lib/aws-sdk-s3/encryption/default_cipher_provider.rb +43 -5
  29. data/lib/aws-sdk-s3/encryption/default_key_provider.rb +2 -0
  30. data/lib/aws-sdk-s3/encryption/encrypt_handler.rb +13 -2
  31. data/lib/aws-sdk-s3/encryption/errors.rb +2 -0
  32. data/lib/aws-sdk-s3/encryption/io_auth_decrypter.rb +11 -3
  33. data/lib/aws-sdk-s3/encryption/io_decrypter.rb +11 -3
  34. data/lib/aws-sdk-s3/encryption/io_encrypter.rb +2 -0
  35. data/lib/aws-sdk-s3/encryption/key_provider.rb +2 -0
  36. data/lib/aws-sdk-s3/encryption/kms_cipher_provider.rb +34 -3
  37. data/lib/aws-sdk-s3/encryption/materials.rb +8 -6
  38. data/lib/aws-sdk-s3/encryption/utils.rb +25 -0
  39. data/lib/aws-sdk-s3/encryption.rb +4 -0
  40. data/lib/aws-sdk-s3/encryptionV2/client.rb +566 -0
  41. data/lib/aws-sdk-s3/encryptionV2/decrypt_handler.rb +222 -0
  42. data/lib/aws-sdk-s3/encryptionV2/default_cipher_provider.rb +170 -0
  43. data/lib/aws-sdk-s3/encryptionV2/default_key_provider.rb +40 -0
  44. data/lib/aws-sdk-s3/encryptionV2/encrypt_handler.rb +65 -0
  45. data/lib/aws-sdk-s3/encryptionV2/errors.rb +37 -0
  46. data/lib/aws-sdk-s3/encryptionV2/io_auth_decrypter.rb +58 -0
  47. data/lib/aws-sdk-s3/encryptionV2/io_decrypter.rb +37 -0
  48. data/lib/aws-sdk-s3/encryptionV2/io_encrypter.rb +73 -0
  49. data/lib/aws-sdk-s3/encryptionV2/key_provider.rb +31 -0
  50. data/lib/aws-sdk-s3/encryptionV2/kms_cipher_provider.rb +169 -0
  51. data/lib/aws-sdk-s3/encryptionV2/materials.rb +60 -0
  52. data/lib/aws-sdk-s3/encryptionV2/utils.rb +103 -0
  53. data/lib/aws-sdk-s3/encryption_v2.rb +23 -0
  54. data/lib/aws-sdk-s3/endpoint_parameters.rb +142 -0
  55. data/lib/aws-sdk-s3/endpoint_provider.rb +2020 -0
  56. data/lib/aws-sdk-s3/endpoints.rb +2149 -0
  57. data/lib/aws-sdk-s3/errors.rb +123 -1
  58. data/lib/aws-sdk-s3/event_streams.rb +20 -7
  59. data/lib/aws-sdk-s3/file_downloader.rb +17 -10
  60. data/lib/aws-sdk-s3/file_part.rb +11 -6
  61. data/lib/aws-sdk-s3/file_uploader.rb +33 -14
  62. data/lib/aws-sdk-s3/legacy_signer.rb +17 -25
  63. data/lib/aws-sdk-s3/multipart_file_uploader.rb +78 -19
  64. data/lib/aws-sdk-s3/multipart_stream_uploader.rb +54 -15
  65. data/lib/aws-sdk-s3/multipart_upload.rb +178 -28
  66. data/lib/aws-sdk-s3/multipart_upload_error.rb +2 -0
  67. data/lib/aws-sdk-s3/multipart_upload_part.rb +237 -44
  68. data/lib/aws-sdk-s3/object.rb +897 -154
  69. data/lib/aws-sdk-s3/object_acl.rb +81 -20
  70. data/lib/aws-sdk-s3/object_copier.rb +2 -0
  71. data/lib/aws-sdk-s3/object_multipart_copier.rb +2 -0
  72. data/lib/aws-sdk-s3/object_summary.rb +649 -139
  73. data/lib/aws-sdk-s3/object_version.rb +167 -65
  74. data/lib/aws-sdk-s3/plugins/accelerate.rb +17 -64
  75. data/lib/aws-sdk-s3/plugins/arn.rb +70 -0
  76. data/lib/aws-sdk-s3/plugins/bucket_dns.rb +7 -43
  77. data/lib/aws-sdk-s3/plugins/bucket_name_restrictions.rb +20 -3
  78. data/lib/aws-sdk-s3/plugins/dualstack.rb +7 -50
  79. data/lib/aws-sdk-s3/plugins/endpoints.rb +262 -0
  80. data/lib/aws-sdk-s3/plugins/expect_100_continue.rb +5 -4
  81. data/lib/aws-sdk-s3/plugins/get_bucket_location_fix.rb +3 -1
  82. data/lib/aws-sdk-s3/plugins/http_200_errors.rb +11 -3
  83. data/lib/aws-sdk-s3/plugins/iad_regional_endpoint.rb +44 -0
  84. data/lib/aws-sdk-s3/plugins/location_constraint.rb +2 -0
  85. data/lib/aws-sdk-s3/plugins/md5s.rb +34 -27
  86. data/lib/aws-sdk-s3/plugins/redirects.rb +2 -0
  87. data/lib/aws-sdk-s3/plugins/s3_host_id.rb +2 -0
  88. data/lib/aws-sdk-s3/plugins/s3_signer.rb +55 -92
  89. data/lib/aws-sdk-s3/plugins/skip_whole_multipart_get_checksums.rb +31 -0
  90. data/lib/aws-sdk-s3/plugins/sse_cpk.rb +3 -1
  91. data/lib/aws-sdk-s3/plugins/streaming_retry.rb +139 -0
  92. data/lib/aws-sdk-s3/plugins/url_encoded_keys.rb +2 -0
  93. data/lib/aws-sdk-s3/presigned_post.rb +108 -56
  94. data/lib/aws-sdk-s3/presigner.rb +169 -77
  95. data/lib/aws-sdk-s3/resource.rb +45 -5
  96. data/lib/aws-sdk-s3/types.rb +8564 -3891
  97. data/lib/aws-sdk-s3/waiters.rb +67 -1
  98. data/lib/aws-sdk-s3.rb +16 -6
  99. metadata +37 -13
@@ -1,25 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'aws-sigv4'
2
4
 
3
5
  module Aws
4
6
  module S3
5
7
  module Plugins
6
- # This plugin is an implementation detail and may be modified.
8
+ # This plugin used to have a V4 signer but it was removed in favor of
9
+ # generic Sign plugin that uses endpoint auth scheme.
10
+ #
7
11
  # @api private
8
12
  class S3Signer < Seahorse::Client::Plugin
9
-
10
13
  option(:signature_version, 'v4')
11
14
 
12
- option(:sigv4_signer) do |cfg|
13
- S3Signer.build_v4_signer(
14
- region: cfg.sigv4_region,
15
- credentials: cfg.credentials
16
- )
17
- end
18
-
19
- option(:sigv4_region) do |cfg|
20
- Aws::Partitions::EndpointProvider.signing_region(cfg.region, 's3')
21
- end
22
-
23
15
  def add_handlers(handlers, cfg)
24
16
  case cfg.signature_version
25
17
  when 'v4' then add_v4_handlers(handlers)
@@ -32,11 +24,11 @@ module Aws
32
24
 
33
25
  def add_v4_handlers(handlers)
34
26
  handlers.add(CachedBucketRegionHandler, step: :sign, priority: 60)
35
- handlers.add(V4Handler, step: :sign)
36
27
  handlers.add(BucketRegionErrorHandler, step: :sign, priority: 40)
37
28
  end
38
29
 
39
30
  def add_legacy_handler(handlers)
31
+ # generic Sign plugin will be skipped if it sees sigv2
40
32
  handlers.add(LegacyHandler, step: :sign)
41
33
  end
42
34
 
@@ -47,40 +39,9 @@ module Aws
47
39
  end
48
40
  end
49
41
 
50
- class V4Handler < Seahorse::Client::Handler
51
-
52
- def call(context)
53
- Aws::Plugins::SignatureV4.apply_signature(
54
- context: context,
55
- signer: sigv4_signer(context)
56
- )
57
- @handler.call(context)
58
- end
59
-
60
- private
61
-
62
- def sigv4_signer(context)
63
- # If the client was configured with the wrong region,
64
- # we have to build a new signer.
65
- if
66
- context[:cached_sigv4_region] &&
67
- context[:cached_sigv4_region] != context.config.sigv4_signer.region
68
- then
69
- S3Signer.build_v4_signer(
70
- region: context[:cached_sigv4_region],
71
- credentials: context.config.credentials
72
- )
73
- else
74
- context.config.sigv4_signer
75
- end
76
- end
77
-
78
- end
79
-
80
42
  # This handler will update the http endpoint when the bucket region
81
43
  # is known/cached.
82
44
  class CachedBucketRegionHandler < Seahorse::Client::Handler
83
-
84
45
  def call(context)
85
46
  bucket = context.params[:bucket]
86
47
  check_for_cached_region(context, bucket) if bucket
@@ -92,19 +53,20 @@ module Aws
92
53
  def check_for_cached_region(context, bucket)
93
54
  cached_region = S3::BUCKET_REGIONS[bucket]
94
55
  if cached_region && cached_region != context.config.region
95
- context.http_request.endpoint.host = S3Signer.new_hostname(context, cached_region)
96
- context[:cached_sigv4_region] = cached_region
56
+ context.http_request.endpoint.host = S3Signer.new_hostname(
57
+ context, cached_region
58
+ )
59
+ context[:sigv4_region] = cached_region # Sign plugin will use this
97
60
  end
98
61
  end
99
-
100
62
  end
101
63
 
102
64
  # This handler detects when a request fails because of a mismatched bucket
103
65
  # region. It follows up by making a request to determine the correct
104
66
  # region, then finally a version 4 signed request against the correct
105
- # regional endpoint.
67
+ # regional endpoint. This is intended for s3's global endpoint which
68
+ # will return 400 if the bucket is not in region.
106
69
  class BucketRegionErrorHandler < Seahorse::Client::Handler
107
-
108
70
  def call(context)
109
71
  response = @handler.call(context)
110
72
  handle_region_errors(response)
@@ -113,7 +75,10 @@ module Aws
113
75
  private
114
76
 
115
77
  def handle_region_errors(response)
116
- if wrong_sigv4_region?(response) && !fips_region?(response)
78
+ if wrong_sigv4_region?(response) &&
79
+ !fips_region?(response) &&
80
+ !custom_endpoint?(response) &&
81
+ !expired_credentials?(response)
117
82
  get_region_and_retry(response.context)
118
83
  else
119
84
  response
@@ -134,32 +99,47 @@ module Aws
134
99
  end
135
100
 
136
101
  def fips_region?(resp)
137
- resp.context.http_request.endpoint.host.include?('fips')
102
+ resp.context.http_request.endpoint.host.include?('s3-fips.')
103
+ end
104
+
105
+ def expired_credentials?(resp)
106
+ resp.context.http_response.body_contents.match(/<Code>ExpiredToken<\/Code>/)
107
+ end
108
+
109
+ def custom_endpoint?(resp)
110
+ region = resp.context.config.region
111
+ partition = Aws::Endpoints::Matchers.aws_partition(region)
112
+ endpoint = resp.context.http_request.endpoint
113
+
114
+ !endpoint.hostname.include?(partition['dnsSuffix']) &&
115
+ !endpoint.hostname.include?(partition['dualStackDnsSuffix'])
138
116
  end
139
117
 
140
118
  def wrong_sigv4_region?(resp)
141
119
  resp.context.http_response.status_code == 400 &&
142
- (
143
- resp.context.http_response.headers['x-amz-bucket-region'] ||
144
- resp.context.http_response.body_contents.match(/<Region>.+?<\/Region>/)
145
- )
120
+ (resp.context.http_response.headers['x-amz-bucket-region'] ||
121
+ resp.context.http_response.body_contents.match(/<Region>.+?<\/Region>/))
146
122
  end
147
123
 
148
124
  def resign_with_new_region(context, actual_region)
149
125
  context.http_response.body.truncate(0)
150
- context.http_request.endpoint.host = S3Signer.new_hostname(context, actual_region)
151
- Aws::Plugins::SignatureV4.apply_signature(
152
- context: context,
153
- signer: S3Signer.build_v4_signer(
154
- region: actual_region,
155
- credentials: context.config.credentials
156
- )
126
+ context.http_request.endpoint.host = S3Signer.new_hostname(
127
+ context, actual_region
157
128
  )
129
+ context.metadata[:redirect_region] = actual_region
130
+
131
+ signer = Aws::Plugins::Sign.signer_for(
132
+ context[:auth_scheme],
133
+ context.config,
134
+ actual_region
135
+ )
136
+
137
+ signer.sign(context)
158
138
  end
159
139
 
160
140
  def region_from_body(body)
161
141
  region = body.match(/<Region>(.+?)<\/Region>/)[1]
162
- if region.nil? || region == ""
142
+ if region.nil? || region == ''
163
143
  raise "couldn't get region from body: #{body}"
164
144
  else
165
145
  region
@@ -167,44 +147,27 @@ module Aws
167
147
  end
168
148
 
169
149
  def log_warning(context, actual_region)
170
- msg = "S3 client configured for #{context.config.region.inspect} " +
171
- "but the bucket #{context.params[:bucket].inspect} is in " +
172
- "#{actual_region.inspect}; Please configure the proper region " +
173
- "to avoid multiple unnecessary redirects and signing attempts\n"
174
- if logger = context.config.logger
150
+ msg = "S3 client configured for #{context.config.region.inspect} " \
151
+ "but the bucket #{context.params[:bucket].inspect} is in " \
152
+ "#{actual_region.inspect}; Please configure the proper region " \
153
+ "to avoid multiple unnecessary redirects and signing attempts\n"
154
+ if (logger = context.config.logger)
175
155
  logger.warn(msg)
176
156
  else
177
157
  warn(msg)
178
158
  end
179
159
  end
180
-
181
160
  end
182
161
 
183
162
  class << self
184
-
185
- # @option options [required, String] :region
186
- # @option options [required, #credentials] :credentials
187
- # @api private
188
- def build_v4_signer(options = {})
189
- Aws::Sigv4::Signer.new({
190
- service: 's3',
191
- region: options[:region],
192
- credentials_provider: options[:credentials],
193
- uri_escape_path: false,
194
- unsigned_headers: ['content-length', 'x-amzn-trace-id'],
195
- })
196
- end
197
-
198
163
  def new_hostname(context, region)
199
- bucket = context.params[:bucket]
200
- if region == 'us-east-1'
201
- "#{bucket}.s3.amazonaws.com"
202
- else
203
- endpoint = Aws::Partitions::EndpointProvider.resolve(region, 's3')
204
- bucket + '.' + URI.parse(endpoint).host
205
- end
164
+ endpoint_params = context[:endpoint_params].dup
165
+ endpoint_params.region = region
166
+ endpoint_params.endpoint = nil
167
+ endpoint =
168
+ context.config.endpoint_provider.resolve_endpoint(endpoint_params)
169
+ URI(endpoint.url).host
206
170
  end
207
-
208
171
  end
209
172
  end
210
173
  end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module S3
5
+ module Plugins
6
+
7
+ # S3 GetObject results for whole Multipart Objects contain a checksum
8
+ # that cannot be validated. These should be skipped by the
9
+ # ChecksumAlgorithm plugin.
10
+ class SkipWholeMultipartGetChecksums < Seahorse::Client::Plugin
11
+
12
+ class Handler < Seahorse::Client::Handler
13
+
14
+ def call(context)
15
+ context[:http_checksum] ||= {}
16
+ context[:http_checksum][:skip_on_suffix] = true
17
+
18
+ @handler.call(context)
19
+ end
20
+
21
+ end
22
+
23
+ handler(
24
+ Handler,
25
+ step: :initialize,
26
+ operations: [:get_object]
27
+ )
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'uri'
2
4
  require 'openssl'
3
5
 
@@ -18,7 +20,7 @@ This should only be disabled for local testing.
18
20
  class Handler < Seahorse::Client::Handler
19
21
 
20
22
  def call(context)
21
- compute_key_md5(context)
23
+ compute_key_md5(context) if context.params.is_a?(Hash)
22
24
  @handler.call(context)
23
25
  end
24
26
 
@@ -0,0 +1,139 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'forwardable'
4
+
5
+ module Aws
6
+ module S3
7
+ module Plugins
8
+
9
+ # A wrapper around BlockIO that adds no-ops for truncate and rewind
10
+ # @api private
11
+ class RetryableBlockIO
12
+ extend Forwardable
13
+ def_delegators :@block_io, :write, :read, :size
14
+
15
+ def initialize(block_io)
16
+ @block_io = block_io
17
+ end
18
+
19
+ def truncate(_integer); end
20
+
21
+ def rewind; end
22
+ end
23
+
24
+ # A wrapper around ManagedFile that adds no-ops for truncate and rewind
25
+ # @api private
26
+ class RetryableManagedFile
27
+ extend Forwardable
28
+ def_delegators :@file, :write, :read, :size, :open?, :close
29
+
30
+ def initialize(managed_file)
31
+ @file = managed_file
32
+ end
33
+
34
+ def truncate(_integer); end
35
+
36
+ def rewind; end
37
+ end
38
+
39
+ class NonRetryableStreamingError < StandardError
40
+
41
+ def initialize(error)
42
+ super('Unable to retry request - retry could result in processing duplicated chunks.')
43
+ set_backtrace(error.backtrace)
44
+ @original_error = error
45
+ end
46
+
47
+ attr_reader :original_error
48
+ end
49
+
50
+ # This handler works with the ResponseTarget plugin to provide smart
51
+ # retries of S3 streaming operations that support the range parameter
52
+ # (currently only: get_object). When a 200 OK with a TruncatedBodyError
53
+ # is received this handler will add a range header that excludes the
54
+ # data that has already been processed (written to file or sent to
55
+ # the target Proc).
56
+ # It is important to not write data to the custom target in the case of
57
+ # a non-success response. We do not want to write an XML error
58
+ # message to someone's file or pass it to a user's Proc.
59
+ # @api private
60
+ class StreamingRetry < Seahorse::Client::Plugin
61
+
62
+ class Handler < Seahorse::Client::Handler
63
+
64
+ def call(context)
65
+ target = context.params[:response_target] || context[:response_target]
66
+
67
+ # retry is only supported when range is NOT set on the initial request
68
+ if supported_target?(target) && !context.params[:range]
69
+ add_event_listeners(context, target)
70
+ end
71
+ @handler.call(context)
72
+ end
73
+
74
+ private
75
+
76
+ def add_event_listeners(context, target)
77
+ context.http_response.on_headers(200..299) do
78
+ case context.http_response.body
79
+ when Seahorse::Client::BlockIO then
80
+ context.http_response.body = RetryableBlockIO.new(context.http_response.body)
81
+ when Seahorse::Client::ManagedFile then
82
+ context.http_response.body = RetryableManagedFile.new(context.http_response.body)
83
+ end
84
+ end
85
+
86
+ context.http_response.on_headers(400..599) do
87
+ context.http_response.body = StringIO.new # something to write the error to
88
+ end
89
+
90
+ context.http_response.on_success(200..299) do
91
+ body = context.http_response.body
92
+ if body.is_a?(RetryableManagedFile) && body.open?
93
+ body.close
94
+ end
95
+ end
96
+
97
+ context.http_response.on_error do |error|
98
+ if retryable_body?(context)
99
+ if truncated_body?(error)
100
+ context.http_request.headers[:range] = "bytes=#{context.http_response.body.size}-"
101
+ else
102
+ case context.http_response.body
103
+ when RetryableManagedFile
104
+ # call rewind on the underlying file
105
+ context.http_response.body.instance_variable_get(:@file).rewind
106
+ else
107
+ raise NonRetryableStreamingError, error
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
113
+
114
+ def truncated_body?(error)
115
+ error.is_a?(Seahorse::Client::NetworkingError) &&
116
+ error.original_error.is_a?(
117
+ Seahorse::Client::NetHttp::Handler::TruncatedBodyError
118
+ )
119
+ end
120
+
121
+ def retryable_body?(context)
122
+ context.http_response.body.is_a?(RetryableBlockIO) ||
123
+ context.http_response.body.is_a?(RetryableManagedFile)
124
+ end
125
+
126
+ def supported_target?(target)
127
+ case target
128
+ when Proc, String, Pathname then true
129
+ else false
130
+ end
131
+ end
132
+ end
133
+
134
+ handler(Handler, step: :sign, operations: [:get_object], priority: 10)
135
+
136
+ end
137
+ end
138
+ end
139
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'uri'
2
4
  require 'cgi'
3
5