aws-sdk-s3 1.75.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 (91) hide show
  1. checksums.yaml +7 -0
  2. data/lib/aws-sdk-s3.rb +73 -0
  3. data/lib/aws-sdk-s3/bucket.rb +861 -0
  4. data/lib/aws-sdk-s3/bucket_acl.rb +277 -0
  5. data/lib/aws-sdk-s3/bucket_cors.rb +262 -0
  6. data/lib/aws-sdk-s3/bucket_lifecycle.rb +264 -0
  7. data/lib/aws-sdk-s3/bucket_lifecycle_configuration.rb +283 -0
  8. data/lib/aws-sdk-s3/bucket_logging.rb +251 -0
  9. data/lib/aws-sdk-s3/bucket_notification.rb +293 -0
  10. data/lib/aws-sdk-s3/bucket_policy.rb +242 -0
  11. data/lib/aws-sdk-s3/bucket_region_cache.rb +81 -0
  12. data/lib/aws-sdk-s3/bucket_request_payment.rb +236 -0
  13. data/lib/aws-sdk-s3/bucket_tagging.rb +251 -0
  14. data/lib/aws-sdk-s3/bucket_versioning.rb +312 -0
  15. data/lib/aws-sdk-s3/bucket_website.rb +292 -0
  16. data/lib/aws-sdk-s3/client.rb +11818 -0
  17. data/lib/aws-sdk-s3/client_api.rb +3014 -0
  18. data/lib/aws-sdk-s3/customizations.rb +34 -0
  19. data/lib/aws-sdk-s3/customizations/bucket.rb +162 -0
  20. data/lib/aws-sdk-s3/customizations/multipart_upload.rb +44 -0
  21. data/lib/aws-sdk-s3/customizations/object.rb +389 -0
  22. data/lib/aws-sdk-s3/customizations/object_summary.rb +85 -0
  23. data/lib/aws-sdk-s3/customizations/types/list_object_versions_output.rb +13 -0
  24. data/lib/aws-sdk-s3/encryption.rb +21 -0
  25. data/lib/aws-sdk-s3/encryption/client.rb +375 -0
  26. data/lib/aws-sdk-s3/encryption/decrypt_handler.rb +190 -0
  27. data/lib/aws-sdk-s3/encryption/default_cipher_provider.rb +65 -0
  28. data/lib/aws-sdk-s3/encryption/default_key_provider.rb +40 -0
  29. data/lib/aws-sdk-s3/encryption/encrypt_handler.rb +61 -0
  30. data/lib/aws-sdk-s3/encryption/errors.rb +15 -0
  31. data/lib/aws-sdk-s3/encryption/io_auth_decrypter.rb +58 -0
  32. data/lib/aws-sdk-s3/encryption/io_decrypter.rb +36 -0
  33. data/lib/aws-sdk-s3/encryption/io_encrypter.rb +71 -0
  34. data/lib/aws-sdk-s3/encryption/key_provider.rb +31 -0
  35. data/lib/aws-sdk-s3/encryption/kms_cipher_provider.rb +75 -0
  36. data/lib/aws-sdk-s3/encryption/materials.rb +60 -0
  37. data/lib/aws-sdk-s3/encryption/utils.rb +81 -0
  38. data/lib/aws-sdk-s3/encryptionV2/client.rb +388 -0
  39. data/lib/aws-sdk-s3/encryptionV2/decrypt_handler.rb +198 -0
  40. data/lib/aws-sdk-s3/encryptionV2/default_cipher_provider.rb +103 -0
  41. data/lib/aws-sdk-s3/encryptionV2/default_key_provider.rb +38 -0
  42. data/lib/aws-sdk-s3/encryptionV2/encrypt_handler.rb +66 -0
  43. data/lib/aws-sdk-s3/encryptionV2/errors.rb +13 -0
  44. data/lib/aws-sdk-s3/encryptionV2/io_auth_decrypter.rb +56 -0
  45. data/lib/aws-sdk-s3/encryptionV2/io_decrypter.rb +35 -0
  46. data/lib/aws-sdk-s3/encryptionV2/io_encrypter.rb +71 -0
  47. data/lib/aws-sdk-s3/encryptionV2/key_provider.rb +29 -0
  48. data/lib/aws-sdk-s3/encryptionV2/kms_cipher_provider.rb +99 -0
  49. data/lib/aws-sdk-s3/encryptionV2/materials.rb +58 -0
  50. data/lib/aws-sdk-s3/encryptionV2/utils.rb +116 -0
  51. data/lib/aws-sdk-s3/encryption_v2.rb +20 -0
  52. data/lib/aws-sdk-s3/errors.rb +115 -0
  53. data/lib/aws-sdk-s3/event_streams.rb +69 -0
  54. data/lib/aws-sdk-s3/file_downloader.rb +142 -0
  55. data/lib/aws-sdk-s3/file_part.rb +78 -0
  56. data/lib/aws-sdk-s3/file_uploader.rb +70 -0
  57. data/lib/aws-sdk-s3/legacy_signer.rb +189 -0
  58. data/lib/aws-sdk-s3/multipart_file_uploader.rb +227 -0
  59. data/lib/aws-sdk-s3/multipart_stream_uploader.rb +173 -0
  60. data/lib/aws-sdk-s3/multipart_upload.rb +401 -0
  61. data/lib/aws-sdk-s3/multipart_upload_error.rb +18 -0
  62. data/lib/aws-sdk-s3/multipart_upload_part.rb +423 -0
  63. data/lib/aws-sdk-s3/object.rb +1422 -0
  64. data/lib/aws-sdk-s3/object_acl.rb +333 -0
  65. data/lib/aws-sdk-s3/object_copier.rb +101 -0
  66. data/lib/aws-sdk-s3/object_multipart_copier.rb +182 -0
  67. data/lib/aws-sdk-s3/object_summary.rb +1181 -0
  68. data/lib/aws-sdk-s3/object_version.rb +550 -0
  69. data/lib/aws-sdk-s3/plugins/accelerate.rb +87 -0
  70. data/lib/aws-sdk-s3/plugins/bucket_arn.rb +212 -0
  71. data/lib/aws-sdk-s3/plugins/bucket_dns.rb +91 -0
  72. data/lib/aws-sdk-s3/plugins/bucket_name_restrictions.rb +45 -0
  73. data/lib/aws-sdk-s3/plugins/dualstack.rb +74 -0
  74. data/lib/aws-sdk-s3/plugins/expect_100_continue.rb +28 -0
  75. data/lib/aws-sdk-s3/plugins/get_bucket_location_fix.rb +25 -0
  76. data/lib/aws-sdk-s3/plugins/http_200_errors.rb +55 -0
  77. data/lib/aws-sdk-s3/plugins/iad_regional_endpoint.rb +62 -0
  78. data/lib/aws-sdk-s3/plugins/location_constraint.rb +35 -0
  79. data/lib/aws-sdk-s3/plugins/md5s.rb +84 -0
  80. data/lib/aws-sdk-s3/plugins/redirects.rb +45 -0
  81. data/lib/aws-sdk-s3/plugins/s3_host_id.rb +30 -0
  82. data/lib/aws-sdk-s3/plugins/s3_signer.rb +222 -0
  83. data/lib/aws-sdk-s3/plugins/sse_cpk.rb +70 -0
  84. data/lib/aws-sdk-s3/plugins/streaming_retry.rb +118 -0
  85. data/lib/aws-sdk-s3/plugins/url_encoded_keys.rb +97 -0
  86. data/lib/aws-sdk-s3/presigned_post.rb +686 -0
  87. data/lib/aws-sdk-s3/presigner.rb +253 -0
  88. data/lib/aws-sdk-s3/resource.rb +117 -0
  89. data/lib/aws-sdk-s3/types.rb +13154 -0
  90. data/lib/aws-sdk-s3/waiters.rb +243 -0
  91. metadata +184 -0
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module S3
5
+ module Plugins
6
+ class Expect100Continue < Seahorse::Client::Plugin
7
+
8
+ def add_handlers(handlers, config)
9
+ if config.http_continue_timeout && config.http_continue_timeout > 0
10
+ handlers.add(Handler)
11
+ end
12
+ end
13
+
14
+ # @api private
15
+ class Handler < Seahorse::Client::Handler
16
+
17
+ def call(context)
18
+ if context.http_request.body && context.http_request.body.size > 0
19
+ context.http_request.headers['expect'] = '100-continue'
20
+ end
21
+ @handler.call(context)
22
+ end
23
+
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module S3
5
+ module Plugins
6
+ class GetBucketLocationFix < Seahorse::Client::Plugin
7
+
8
+ class Handler < Seahorse::Client::Handler
9
+
10
+ def call(context)
11
+ @handler.call(context).on(200) do |response|
12
+ response.data = S3::Types::GetBucketLocationOutput.new
13
+ xml = context.http_response.body_contents
14
+ matches = xml.match(/>(.+?)<\/LocationConstraint>/)
15
+ response.data[:location_constraint] = matches ? matches[1] : ''
16
+ end
17
+ end
18
+ end
19
+
20
+ handler(Handler, priority: 60, operations: [:get_bucket_location])
21
+
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module S3
5
+ module Plugins
6
+
7
+ # A handful of Amazon S3 operations will respond with a 200 status
8
+ # code but will send an error in the response body. This plugin
9
+ # injects a handler that will parse 200 response bodies for potential
10
+ # errors, allowing them to be retried.
11
+ # @api private
12
+ class Http200Errors < Seahorse::Client::Plugin
13
+
14
+ class Handler < Seahorse::Client::Handler
15
+
16
+ def call(context)
17
+ @handler.call(context).on(200) do |response|
18
+ if error = check_for_error(context)
19
+ context.http_response.status_code = 500
20
+ response.data = nil
21
+ response.error = error
22
+ end
23
+ end
24
+ end
25
+
26
+ def check_for_error(context)
27
+ xml = context.http_response.body_contents
28
+ if xml.match(/<Error>/)
29
+ error_code = xml.match(/<Code>(.+?)<\/Code>/)[1]
30
+ error_message = xml.match(/<Message>(.+?)<\/Message>/)[1]
31
+ S3::Errors.error_class(error_code).new(context, error_message)
32
+ elsif !xml.match(/<\w/) # Must have the start of an XML Tag
33
+ # Other incomplete xml bodies will result in XML ParsingError
34
+ Seahorse::Client::NetworkingError.new(
35
+ S3::Errors
36
+ .error_class('InternalError')
37
+ .new(context, 'Empty or incomplete response body')
38
+ )
39
+ end
40
+ end
41
+ end
42
+
43
+ handler(
44
+ Handler,
45
+ step: :sign,
46
+ operations: [
47
+ :complete_multipart_upload,
48
+ :copy_object,
49
+ :upload_part_copy,
50
+ ]
51
+ )
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module S3
5
+ module Plugins
6
+
7
+ class IADRegionalEndpoint < Seahorse::Client::Plugin
8
+
9
+ option(:s3_us_east_1_regional_endpoint,
10
+ default: 'legacy',
11
+ doc_type: String,
12
+ docstring: <<-DOCS) do |cfg|
13
+ Passing in `regional` to enable regional endpoint for S3's `us-east-1`
14
+ region. Defaults to `legacy` mode using global endpoint.
15
+ DOCS
16
+ resolve_iad_regional_endpoint(cfg)
17
+ end
18
+
19
+ def add_handlers(handlers, config)
20
+ if config.region == 'us-east-1'
21
+ handlers.add(Handler)
22
+ end
23
+ end
24
+
25
+ # @api private
26
+ class Handler < Seahorse::Client::Handler
27
+
28
+ def call(context)
29
+ # keep legacy global endpoint pattern by default
30
+ if context.config.s3_us_east_1_regional_endpoint == 'legacy'
31
+ context.http_request.endpoint.host = IADRegionalEndpoint.legacy_host(
32
+ context.http_request.endpoint.host)
33
+ end
34
+ @handler.call(context)
35
+ end
36
+
37
+ end
38
+
39
+ def self.legacy_host(host)
40
+ host.sub(".us-east-1", '')
41
+ end
42
+
43
+ private
44
+
45
+ def self.resolve_iad_regional_endpoint(cfg)
46
+ mode = ENV['AWS_S3_US_EAST_1_REGIONAL_ENDPOINT'] ||
47
+ Aws.shared_config.s3_us_east_1_regional_endpoint(profile: cfg.profile) ||
48
+ 'legacy'
49
+ mode = mode.downcase
50
+ unless %w(legacy regional).include?(mode)
51
+ raise ArgumentError, "expected :s3_us_east_1_regional_endpoint or"\
52
+ " ENV['AWS_S3_US_EAST_1_REGIONAL_ENDPOINT'] to be `legacy` or"\
53
+ " `regional`."
54
+ end
55
+ mode
56
+ end
57
+
58
+ end
59
+
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module S3
5
+ module Plugins
6
+
7
+ # When making calls to {S3::Client#create_bucket} outside the
8
+ # "classic" region, the bucket location constraint must be specified.
9
+ # This plugin auto populates the constraint to the configured region.
10
+ class LocationConstraint < Seahorse::Client::Plugin
11
+
12
+ class Handler < Seahorse::Client::Handler
13
+
14
+ def call(context)
15
+ unless context.config.region == 'us-east-1'
16
+ populate_location_constraint(context.params, context.config.region)
17
+ end
18
+ @handler.call(context)
19
+ end
20
+
21
+ private
22
+
23
+ def populate_location_constraint(params, region)
24
+ params[:create_bucket_configuration] ||= {}
25
+ params[:create_bucket_configuration][:location_constraint] ||= region
26
+ end
27
+
28
+ end
29
+
30
+ handler(Handler, step: :initialize, operations: [:create_bucket])
31
+
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'openssl'
4
+
5
+ module Aws
6
+ module S3
7
+ module Plugins
8
+ # @api private
9
+ # This plugin is effectively deprecated in favor of modeled
10
+ # httpChecksumRequired traits.
11
+ class Md5s < Seahorse::Client::Plugin
12
+ # These operations allow Content MD5 but are not required by
13
+ # httpChecksumRequired. This list should not grow.
14
+ OPTIONAL_OPERATIONS = [
15
+ :put_object,
16
+ :upload_part
17
+ ]
18
+
19
+ # @api private
20
+ class Handler < Seahorse::Client::Handler
21
+
22
+ CHUNK_SIZE = 1 * 1024 * 1024 # one MB
23
+
24
+ def call(context)
25
+ body = context.http_request.body
26
+ if body.size > 0
27
+ context.http_request.headers['Content-Md5'] ||= md5(body)
28
+ end
29
+ @handler.call(context)
30
+ end
31
+
32
+ private
33
+
34
+ # @param [File, Tempfile, IO#read, String] value
35
+ # @return [String<MD5>]
36
+ def md5(value)
37
+ if (File === value || Tempfile === value) && !value.path.nil? && File.exist?(value.path)
38
+ OpenSSL::Digest::MD5.file(value).base64digest
39
+ elsif value.respond_to?(:read)
40
+ md5 = OpenSSL::Digest::MD5.new
41
+ update_in_chunks(md5, value)
42
+ md5.base64digest
43
+ else
44
+ OpenSSL::Digest::MD5.digest(value).base64digest
45
+ end
46
+ end
47
+
48
+ def update_in_chunks(digest, io)
49
+ loop do
50
+ chunk = io.read(CHUNK_SIZE)
51
+ break unless chunk
52
+ digest.update(chunk)
53
+ end
54
+ io.rewind
55
+ end
56
+
57
+ end
58
+
59
+ option(:compute_checksums,
60
+ default: true,
61
+ doc_type: 'Boolean',
62
+ docstring: <<-DOCS)
63
+ When `true` a MD5 checksum will be computed and sent in the Content Md5
64
+ header for :put_object and :upload_part. When `false`, MD5 checksums
65
+ will not be computed for these operations. Checksums are still computed
66
+ for operations requiring them. Checksum errors returned by Amazon S3 are
67
+ automatically retried up to `:retry_limit` times.
68
+ DOCS
69
+
70
+ def add_handlers(handlers, config)
71
+ if config.compute_checksums
72
+ # priority set low to ensure md5 is computed AFTER the request is
73
+ # built but before it is signed
74
+ handlers.add(
75
+ Handler,
76
+ priority: 10, step: :build, operations: OPTIONAL_OPERATIONS
77
+ )
78
+ end
79
+ end
80
+
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module S3
5
+ module Plugins
6
+ class Redirects < Seahorse::Client::Plugin
7
+
8
+ option(:follow_redirects,
9
+ default: true,
10
+ doc_type: 'Boolean',
11
+ docstring: <<-DOCS)
12
+ When `true`, this client will follow 307 redirects returned
13
+ by Amazon S3.
14
+ DOCS
15
+
16
+ # @api private
17
+ class Handler < Seahorse::Client::Handler
18
+
19
+ def call(context)
20
+ response = @handler.call(context)
21
+ if context.http_response.status_code == 307
22
+ endpoint = context.http_response.headers['location']
23
+ unless context.http_request.endpoint.host.include?('fips')
24
+ context.http_request.endpoint = endpoint
25
+ end
26
+ context.http_response.body.truncate(0)
27
+ @handler.call(context)
28
+ else
29
+ response
30
+ end
31
+ end
32
+
33
+ end
34
+
35
+ def add_handlers(handlers, config)
36
+ if config.follow_redirects
37
+ # we want to re-trigger request signing
38
+ handlers.add(Handler, step: :sign, priority: 90)
39
+ end
40
+ end
41
+
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module S3
5
+ module Plugins
6
+
7
+ # Support S3 host id, more information, see:
8
+ # http://docs.aws.amazon.com/AmazonS3/latest/dev/troubleshooting.html#sdk-request-ids
9
+ #
10
+ # This plugin adds :host_id for s3 responses when available
11
+ # @api private
12
+ class S3HostId < Seahorse::Client::Plugin
13
+
14
+ class Handler < Seahorse::Client::Handler
15
+
16
+ def call(context)
17
+ response = @handler.call(context)
18
+ h = context.http_response.headers
19
+ context[:s3_host_id] = h['x-amz-id-2']
20
+ response
21
+ end
22
+
23
+ end
24
+
25
+ handler(Handler, step: :sign)
26
+
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,222 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'aws-sigv4'
4
+
5
+ module Aws
6
+ module S3
7
+ module Plugins
8
+ # This plugin is an implementation detail and may be modified.
9
+ # @api private
10
+ class S3Signer < Seahorse::Client::Plugin
11
+ option(:signature_version, 'v4')
12
+
13
+ option(:sigv4_signer) do |cfg|
14
+ S3Signer.build_v4_signer(
15
+ region: cfg.sigv4_region,
16
+ credentials: cfg.credentials
17
+ )
18
+ end
19
+
20
+ option(:sigv4_region) do |cfg|
21
+ raise Aws::Errors::MissingRegionError if cfg.region.nil?
22
+
23
+ Aws::Partitions::EndpointProvider.signing_region(cfg.region, 's3')
24
+ end
25
+
26
+ def add_handlers(handlers, cfg)
27
+ case cfg.signature_version
28
+ when 'v4' then add_v4_handlers(handlers)
29
+ when 's3' then add_legacy_handler(handlers)
30
+ else
31
+ msg = "unsupported signature version `#{cfg.signature_version}'"
32
+ raise ArgumentError, msg
33
+ end
34
+ end
35
+
36
+ def add_v4_handlers(handlers)
37
+ handlers.add(CachedBucketRegionHandler, step: :sign, priority: 60)
38
+ handlers.add(V4Handler, step: :sign)
39
+ handlers.add(BucketRegionErrorHandler, step: :sign, priority: 40)
40
+ end
41
+
42
+ def add_legacy_handler(handlers)
43
+ handlers.add(LegacyHandler, step: :sign)
44
+ end
45
+
46
+ class LegacyHandler < Seahorse::Client::Handler
47
+ def call(context)
48
+ LegacySigner.sign(context)
49
+ @handler.call(context)
50
+ end
51
+ end
52
+
53
+ class V4Handler < Seahorse::Client::Handler
54
+ def call(context)
55
+ Aws::Plugins::SignatureV4.apply_signature(
56
+ context: context,
57
+ signer: sigv4_signer(context)
58
+ )
59
+ @handler.call(context)
60
+ end
61
+
62
+ private
63
+
64
+ def sigv4_signer(context)
65
+ # If the client was configured with the wrong region,
66
+ # we have to build a new signer.
67
+ if context[:cached_sigv4_region] &&
68
+ context[:cached_sigv4_region] != context.config.sigv4_signer.region
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
+ end
78
+
79
+ # This handler will update the http endpoint when the bucket region
80
+ # is known/cached.
81
+ class CachedBucketRegionHandler < Seahorse::Client::Handler
82
+ def call(context)
83
+ bucket = context.params[:bucket]
84
+ check_for_cached_region(context, bucket) if bucket
85
+ @handler.call(context)
86
+ end
87
+
88
+ private
89
+
90
+ def check_for_cached_region(context, bucket)
91
+ cached_region = S3::BUCKET_REGIONS[bucket]
92
+ if cached_region && cached_region != context.config.region
93
+ context.http_request.endpoint.host = S3Signer.new_hostname(context, cached_region)
94
+ context[:cached_sigv4_region] = cached_region
95
+ end
96
+ end
97
+ end
98
+
99
+ # This handler detects when a request fails because of a mismatched bucket
100
+ # region. It follows up by making a request to determine the correct
101
+ # region, then finally a version 4 signed request against the correct
102
+ # regional endpoint.
103
+ class BucketRegionErrorHandler < Seahorse::Client::Handler
104
+ def call(context)
105
+ response = @handler.call(context)
106
+ handle_region_errors(response)
107
+ end
108
+
109
+ private
110
+
111
+ def handle_region_errors(response)
112
+ if wrong_sigv4_region?(response) &&
113
+ !fips_region?(response) &&
114
+ !custom_endpoint?(response)
115
+ get_region_and_retry(response.context)
116
+ else
117
+ response
118
+ end
119
+ end
120
+
121
+ def get_region_and_retry(context)
122
+ actual_region = context.http_response.headers['x-amz-bucket-region']
123
+ actual_region ||= region_from_body(context.http_response.body_contents)
124
+ update_bucket_cache(context, actual_region)
125
+ log_warning(context, actual_region)
126
+ resign_with_new_region(context, actual_region)
127
+ @handler.call(context)
128
+ end
129
+
130
+ def update_bucket_cache(context, actual_region)
131
+ S3::BUCKET_REGIONS[context.params[:bucket]] = actual_region
132
+ end
133
+
134
+ def fips_region?(resp)
135
+ resp.context.http_request.endpoint.host.include?('fips')
136
+ end
137
+
138
+ def custom_endpoint?(resp)
139
+ resolved_suffix = Aws::Partitions::EndpointProvider.dns_suffix_for(
140
+ resp.context.config.region
141
+ )
142
+ !resp.context.http_request.endpoint.hostname.include?(resolved_suffix)
143
+ end
144
+
145
+ def wrong_sigv4_region?(resp)
146
+ resp.context.http_response.status_code == 400 &&
147
+ (resp.context.http_response.headers['x-amz-bucket-region'] ||
148
+ resp.context.http_response.body_contents.match(/<Region>.+?<\/Region>/))
149
+ end
150
+
151
+ def resign_with_new_region(context, actual_region)
152
+ context.http_response.body.truncate(0)
153
+ context.http_request.endpoint.host = S3Signer.new_hostname(context, actual_region)
154
+ context.metadata[:redirect_region] = actual_region
155
+ Aws::Plugins::SignatureV4.apply_signature(
156
+ context: context,
157
+ signer: S3Signer.build_v4_signer(
158
+ region: actual_region,
159
+ credentials: context.config.credentials
160
+ )
161
+ )
162
+ end
163
+
164
+ def region_from_body(body)
165
+ region = body.match(/<Region>(.+?)<\/Region>/)[1]
166
+ if region.nil? || region == ''
167
+ raise "couldn't get region from body: #{body}"
168
+ else
169
+ region
170
+ end
171
+ end
172
+
173
+ def log_warning(context, actual_region)
174
+ msg = "S3 client configured for #{context.config.region.inspect} " \
175
+ "but the bucket #{context.params[:bucket].inspect} is in " \
176
+ "#{actual_region.inspect}; Please configure the proper region " \
177
+ "to avoid multiple unnecessary redirects and signing attempts\n"
178
+ if (logger = context.config.logger)
179
+ logger.warn(msg)
180
+ else
181
+ warn(msg)
182
+ end
183
+ end
184
+ end
185
+
186
+ class << self
187
+ # @option options [required, String] :region
188
+ # @option options [required, #credentials] :credentials
189
+ # @api private
190
+ def build_v4_signer(options = {})
191
+ Aws::Sigv4::Signer.new(
192
+ service: 's3',
193
+ region: options[:region],
194
+ credentials_provider: options[:credentials],
195
+ uri_escape_path: false,
196
+ unsigned_headers: ['content-length', 'x-amzn-trace-id']
197
+ )
198
+ end
199
+
200
+ def new_hostname(context, region)
201
+ # Check to see if the bucket is actually an ARN and resolve it
202
+ # Otherwise it will retry with the ARN as the bucket name.
203
+ resolved_bucket, resolved_region, arn = BucketARN.resolve_arn!(
204
+ context.params[:bucket],
205
+ region,
206
+ context.config.s3_use_arn_region
207
+ )
208
+ uri = URI.parse(
209
+ Aws::Partitions::EndpointProvider.resolve(resolved_region, 's3')
210
+ )
211
+
212
+ if arn
213
+ BucketARN.resolve_url!(uri, arn).host
214
+ else
215
+ resolved_bucket + '.' + uri.host
216
+ end
217
+ end
218
+ end
219
+ end
220
+ end
221
+ end
222
+ end