aws-sdk-s3 1.48.0 → 1.183.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 (134) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +1352 -0
  3. data/LICENSE.txt +202 -0
  4. data/VERSION +1 -0
  5. data/lib/aws-sdk-s3/access_grants_credentials.rb +57 -0
  6. data/lib/aws-sdk-s3/access_grants_credentials_provider.rb +250 -0
  7. data/lib/aws-sdk-s3/bucket.rb +1005 -106
  8. data/lib/aws-sdk-s3/bucket_acl.rb +65 -18
  9. data/lib/aws-sdk-s3/bucket_cors.rb +80 -18
  10. data/lib/aws-sdk-s3/bucket_lifecycle.rb +71 -20
  11. data/lib/aws-sdk-s3/bucket_lifecycle_configuration.rb +126 -21
  12. data/lib/aws-sdk-s3/bucket_logging.rb +68 -16
  13. data/lib/aws-sdk-s3/bucket_notification.rb +52 -20
  14. data/lib/aws-sdk-s3/bucket_policy.rb +108 -17
  15. data/lib/aws-sdk-s3/bucket_region_cache.rb +11 -5
  16. data/lib/aws-sdk-s3/bucket_request_payment.rb +60 -15
  17. data/lib/aws-sdk-s3/bucket_tagging.rb +71 -18
  18. data/lib/aws-sdk-s3/bucket_versioning.rb +133 -17
  19. data/lib/aws-sdk-s3/bucket_website.rb +78 -21
  20. data/lib/aws-sdk-s3/client.rb +14517 -941
  21. data/lib/aws-sdk-s3/client_api.rb +1296 -197
  22. data/lib/aws-sdk-s3/customizations/bucket.rb +56 -37
  23. data/lib/aws-sdk-s3/customizations/errors.rb +40 -0
  24. data/lib/aws-sdk-s3/customizations/multipart_upload.rb +2 -0
  25. data/lib/aws-sdk-s3/customizations/object.rb +288 -68
  26. data/lib/aws-sdk-s3/customizations/object_summary.rb +10 -0
  27. data/lib/aws-sdk-s3/customizations/object_version.rb +13 -0
  28. data/lib/aws-sdk-s3/customizations/types/list_object_versions_output.rb +2 -0
  29. data/lib/aws-sdk-s3/customizations/types/permanent_redirect.rb +26 -0
  30. data/lib/aws-sdk-s3/customizations.rb +27 -28
  31. data/lib/aws-sdk-s3/encryption/client.rb +28 -7
  32. data/lib/aws-sdk-s3/encryption/decrypt_handler.rb +71 -29
  33. data/lib/aws-sdk-s3/encryption/default_cipher_provider.rb +43 -5
  34. data/lib/aws-sdk-s3/encryption/default_key_provider.rb +2 -0
  35. data/lib/aws-sdk-s3/encryption/encrypt_handler.rb +13 -2
  36. data/lib/aws-sdk-s3/encryption/errors.rb +2 -0
  37. data/lib/aws-sdk-s3/encryption/io_auth_decrypter.rb +2 -0
  38. data/lib/aws-sdk-s3/encryption/io_decrypter.rb +11 -3
  39. data/lib/aws-sdk-s3/encryption/io_encrypter.rb +2 -0
  40. data/lib/aws-sdk-s3/encryption/key_provider.rb +2 -0
  41. data/lib/aws-sdk-s3/encryption/kms_cipher_provider.rb +46 -11
  42. data/lib/aws-sdk-s3/encryption/materials.rb +8 -6
  43. data/lib/aws-sdk-s3/encryption/utils.rb +25 -0
  44. data/lib/aws-sdk-s3/encryption.rb +4 -0
  45. data/lib/aws-sdk-s3/encryptionV2/client.rb +570 -0
  46. data/lib/aws-sdk-s3/encryptionV2/decrypt_handler.rb +223 -0
  47. data/lib/aws-sdk-s3/encryptionV2/default_cipher_provider.rb +170 -0
  48. data/lib/aws-sdk-s3/encryptionV2/default_key_provider.rb +40 -0
  49. data/lib/aws-sdk-s3/encryptionV2/encrypt_handler.rb +65 -0
  50. data/lib/aws-sdk-s3/encryptionV2/errors.rb +37 -0
  51. data/lib/aws-sdk-s3/encryptionV2/io_auth_decrypter.rb +58 -0
  52. data/lib/aws-sdk-s3/encryptionV2/io_decrypter.rb +37 -0
  53. data/lib/aws-sdk-s3/encryptionV2/io_encrypter.rb +73 -0
  54. data/lib/aws-sdk-s3/encryptionV2/key_provider.rb +31 -0
  55. data/lib/aws-sdk-s3/encryptionV2/kms_cipher_provider.rb +173 -0
  56. data/lib/aws-sdk-s3/encryptionV2/materials.rb +60 -0
  57. data/lib/aws-sdk-s3/encryptionV2/utils.rb +103 -0
  58. data/lib/aws-sdk-s3/encryption_v2.rb +23 -0
  59. data/lib/aws-sdk-s3/endpoint_parameters.rb +181 -0
  60. data/lib/aws-sdk-s3/endpoint_provider.rb +716 -0
  61. data/lib/aws-sdk-s3/endpoints.rb +1434 -0
  62. data/lib/aws-sdk-s3/errors.rb +170 -1
  63. data/lib/aws-sdk-s3/event_streams.rb +8 -1
  64. data/lib/aws-sdk-s3/express_credentials.rb +55 -0
  65. data/lib/aws-sdk-s3/express_credentials_provider.rb +59 -0
  66. data/lib/aws-sdk-s3/file_downloader.rb +161 -46
  67. data/lib/aws-sdk-s3/file_part.rb +11 -6
  68. data/lib/aws-sdk-s3/file_uploader.rb +39 -18
  69. data/lib/aws-sdk-s3/legacy_signer.rb +17 -25
  70. data/lib/aws-sdk-s3/multipart_file_uploader.rb +104 -27
  71. data/lib/aws-sdk-s3/multipart_stream_uploader.rb +61 -21
  72. data/lib/aws-sdk-s3/multipart_upload.rb +342 -32
  73. data/lib/aws-sdk-s3/multipart_upload_error.rb +2 -0
  74. data/lib/aws-sdk-s3/multipart_upload_part.rb +384 -46
  75. data/lib/aws-sdk-s3/object.rb +2600 -231
  76. data/lib/aws-sdk-s3/object_acl.rb +103 -25
  77. data/lib/aws-sdk-s3/object_copier.rb +9 -5
  78. data/lib/aws-sdk-s3/object_multipart_copier.rb +48 -22
  79. data/lib/aws-sdk-s3/object_summary.rb +2174 -204
  80. data/lib/aws-sdk-s3/object_version.rb +539 -80
  81. data/lib/aws-sdk-s3/plugins/accelerate.rb +17 -64
  82. data/lib/aws-sdk-s3/plugins/access_grants.rb +178 -0
  83. data/lib/aws-sdk-s3/plugins/arn.rb +70 -0
  84. data/lib/aws-sdk-s3/plugins/bucket_dns.rb +7 -43
  85. data/lib/aws-sdk-s3/plugins/bucket_name_restrictions.rb +20 -3
  86. data/lib/aws-sdk-s3/plugins/checksum_algorithm.rb +31 -0
  87. data/lib/aws-sdk-s3/plugins/dualstack.rb +7 -50
  88. data/lib/aws-sdk-s3/plugins/endpoints.rb +86 -0
  89. data/lib/aws-sdk-s3/plugins/expect_100_continue.rb +5 -4
  90. data/lib/aws-sdk-s3/plugins/express_session_auth.rb +88 -0
  91. data/lib/aws-sdk-s3/plugins/get_bucket_location_fix.rb +3 -1
  92. data/lib/aws-sdk-s3/plugins/http_200_errors.rb +62 -17
  93. data/lib/aws-sdk-s3/plugins/iad_regional_endpoint.rb +44 -0
  94. data/lib/aws-sdk-s3/plugins/location_constraint.rb +5 -1
  95. data/lib/aws-sdk-s3/plugins/md5s.rb +14 -70
  96. data/lib/aws-sdk-s3/plugins/redirects.rb +2 -0
  97. data/lib/aws-sdk-s3/plugins/s3_host_id.rb +2 -0
  98. data/lib/aws-sdk-s3/plugins/s3_signer.rb +63 -94
  99. data/lib/aws-sdk-s3/plugins/sse_cpk.rb +3 -1
  100. data/lib/aws-sdk-s3/plugins/streaming_retry.rb +139 -0
  101. data/lib/aws-sdk-s3/plugins/url_encoded_keys.rb +2 -0
  102. data/lib/aws-sdk-s3/presigned_post.rb +160 -99
  103. data/lib/aws-sdk-s3/presigner.rb +141 -62
  104. data/lib/aws-sdk-s3/resource.rb +156 -17
  105. data/lib/aws-sdk-s3/types.rb +13021 -4106
  106. data/lib/aws-sdk-s3/waiters.rb +67 -1
  107. data/lib/aws-sdk-s3.rb +46 -32
  108. data/sig/bucket.rbs +222 -0
  109. data/sig/bucket_acl.rbs +78 -0
  110. data/sig/bucket_cors.rbs +69 -0
  111. data/sig/bucket_lifecycle.rbs +88 -0
  112. data/sig/bucket_lifecycle_configuration.rbs +115 -0
  113. data/sig/bucket_logging.rbs +76 -0
  114. data/sig/bucket_notification.rbs +114 -0
  115. data/sig/bucket_policy.rbs +59 -0
  116. data/sig/bucket_request_payment.rbs +54 -0
  117. data/sig/bucket_tagging.rbs +65 -0
  118. data/sig/bucket_versioning.rbs +77 -0
  119. data/sig/bucket_website.rbs +93 -0
  120. data/sig/client.rbs +2472 -0
  121. data/sig/customizations/bucket.rbs +19 -0
  122. data/sig/customizations/object.rbs +38 -0
  123. data/sig/customizations/object_summary.rbs +35 -0
  124. data/sig/errors.rbs +42 -0
  125. data/sig/multipart_upload.rbs +120 -0
  126. data/sig/multipart_upload_part.rbs +109 -0
  127. data/sig/object.rbs +459 -0
  128. data/sig/object_acl.rbs +86 -0
  129. data/sig/object_summary.rbs +345 -0
  130. data/sig/object_version.rbs +143 -0
  131. data/sig/resource.rbs +134 -0
  132. data/sig/types.rbs +2712 -0
  133. data/sig/waiters.rbs +95 -0
  134. metadata +74 -15
@@ -1,94 +1,47 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Aws
2
4
  module S3
3
5
  module Plugins
4
-
5
6
  # Provides support for using `Aws::S3::Client` with Amazon S3 Transfer
6
7
  # Acceleration.
7
8
  #
8
9
  # Go here for more information about transfer acceleration:
9
10
  # [http://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html](http://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html)
10
11
  class Accelerate < Seahorse::Client::Plugin
11
-
12
- option(:use_accelerate_endpoint,
12
+ option(
13
+ :use_accelerate_endpoint,
13
14
  default: false,
14
15
  doc_type: 'Boolean',
15
16
  docstring: <<-DOCS)
16
17
  When set to `true`, accelerated bucket endpoints will be used
17
18
  for all object operations. You must first enable accelerate for
18
- each bucket. [Go here for more information](http://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html).
19
+ each bucket. [Go here for more information](http://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html).
19
20
  DOCS
20
21
 
21
22
  def add_handlers(handlers, config)
22
23
  operations = config.api.operation_names - [
23
- :create_bucket, :list_buckets, :delete_bucket,
24
+ :create_bucket, :list_buckets, :delete_bucket
24
25
  ]
25
- handlers.add(OptionHandler, step: :initialize, operations: operations)
26
- handlers.add(AccelerateHandler, step: :build, priority: 0, operations: operations)
26
+ handlers.add(
27
+ OptionHandler, step: :initialize, operations: operations
28
+ )
27
29
  end
28
30
 
29
31
  # @api private
30
32
  class OptionHandler < Seahorse::Client::Handler
31
33
  def call(context)
32
- accelerate = context.params.delete(:use_accelerate_endpoint)
33
- accelerate = context.config.use_accelerate_endpoint if accelerate.nil?
34
- context[:use_accelerate_endpoint] = accelerate
35
- @handler.call(context)
36
- end
37
- end
38
-
39
- # @api private
40
- class AccelerateHandler < Seahorse::Client::Handler
41
-
42
- def call(context)
43
- if context[:use_accelerate_endpoint]
44
- if context[:use_dualstack_endpoint]
45
- use_combined_accelerate_dualstack_endpoint(context)
46
- else
47
- use_accelerate_endpoint(context)
48
- end
34
+ # Support client configuration and per-operation configuration
35
+ # TODO: move this to an options hash and warn here.
36
+ if context.params.is_a?(Hash)
37
+ accelerate = context.params.delete(:use_accelerate_endpoint)
49
38
  end
50
- @handler.call(context)
51
- end
52
-
53
- private
54
-
55
- def use_accelerate_endpoint(context)
56
- bucket_name = context.params[:bucket]
57
- validate_bucket_name!(bucket_name)
58
- endpoint = URI.parse(context.http_request.endpoint.to_s)
59
- endpoint.scheme = 'https'
60
- endpoint.port = 443
61
- endpoint.host = "#{bucket_name}.s3-accelerate.amazonaws.com"
62
- context.http_request.endpoint = endpoint.to_s
63
- # s3 accelerate endpoint doesn't work with 'expect' header
64
- context.http_request.headers.delete('expect')
65
- end
66
-
67
- def use_combined_accelerate_dualstack_endpoint(context)
68
- bucket_name = context.params[:bucket]
69
- validate_bucket_name!(bucket_name)
70
- endpoint = URI.parse(context.http_request.endpoint.to_s)
71
- endpoint.scheme = 'https'
72
- endpoint.port = 443
73
- endpoint.host = "#{bucket_name}.s3-accelerate.dualstack.amazonaws.com"
74
- context.http_request.endpoint = endpoint.to_s
75
- # s3 accelerate endpoint doesn't work with 'expect' header
76
- context.http_request.headers.delete('expect')
77
- end
78
-
79
- def validate_bucket_name!(bucket_name)
80
- unless BucketDns.dns_compatible?(bucket_name, _ssl = true)
81
- msg = "unable to use `accelerate: true` on buckets with "
82
- msg << "non-DNS compatible names"
83
- raise ArgumentError, msg
84
- end
85
- if bucket_name.include?('.')
86
- msg = "unable to use `accelerate: true` on buckets with dots"
87
- msg << "in their name: #{bucket_name.inspect}"
88
- raise ArgumentError, msg
39
+ if accelerate.nil?
40
+ accelerate = context.config.use_accelerate_endpoint
89
41
  end
42
+ context[:use_accelerate_endpoint] = accelerate
43
+ @handler.call(context)
90
44
  end
91
-
92
45
  end
93
46
  end
94
47
  end
@@ -0,0 +1,178 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module S3
5
+ module Plugins
6
+ # @api private
7
+ class AccessGrants < Seahorse::Client::Plugin
8
+ @s3control =
9
+ begin
10
+ require 'aws-sdk-s3control'
11
+ true
12
+ rescue LoadError
13
+ false
14
+ end
15
+
16
+ option(
17
+ :access_grants,
18
+ default: false,
19
+ doc_type: 'Boolean',
20
+ docstring: <<-DOCS)
21
+ When `true`, the S3 client will use the S3 Access Grants feature to
22
+ authenticate requests. Bucket credentials will be fetched from S3
23
+ Control using the `get_data_access` API.
24
+ DOCS
25
+
26
+ option(:access_grants_credentials_provider,
27
+ doc_type: 'Aws::S3::AccessGrantsCredentialsProvider',
28
+ rbs_type: 'untyped',
29
+ docstring: <<-DOCS) do |_cfg|
30
+ When `access_grants` is `true`, this option can be used to provide
31
+ additional options to the credentials provider, including a privilege
32
+ setting, caching, and fallback behavior.
33
+ DOCS
34
+ Aws::S3::AccessGrantsCredentialsProvider.new
35
+ end
36
+
37
+ # @api private
38
+ class Handler < Seahorse::Client::Handler
39
+ PERMISSION_MAP = {
40
+ head_object: 'READ',
41
+ get_object: 'READ',
42
+ get_object_acl: 'READ',
43
+ list_multipart_uploads: 'READ',
44
+ list_objects_v2: 'READ',
45
+ list_object_versions: 'READ',
46
+ list_parts: 'READ',
47
+ head_bucket: 'READ',
48
+ get_object_attributes: 'READ',
49
+ put_object: 'WRITE',
50
+ put_object_acl: 'WRITE',
51
+ delete_object: 'WRITE',
52
+ abort_multipart_upload: 'WRITE',
53
+ create_multipart_upload: 'WRITE',
54
+ upload_part: 'WRITE',
55
+ complete_multipart_upload: 'WRITE',
56
+ delete_objects: 'WRITE',
57
+ copy_object: 'READWRITE'
58
+ }.freeze
59
+
60
+ def call(context)
61
+ provider = context.config.access_grants_credentials_provider
62
+
63
+ if access_grants_operation?(context) &&
64
+ !s3_express_endpoint?(context) &&
65
+ !credentials_head_bucket_call?(provider)
66
+ params = context[:endpoint_params]
67
+ permission = PERMISSION_MAP[context.operation_name]
68
+
69
+ key =
70
+ case context.operation_name
71
+ when :delete_objects
72
+ delete_params = context.params[:delete]
73
+ common_prefixes(delete_params[:objects].map { |o| o[:key] })
74
+ when :copy_object
75
+ source_bucket, source_key = params[:copy_source].split('/', 2)
76
+ if params[:bucket] != source_bucket
77
+ raise ArgumentError,
78
+ 'source and destination bucket must be the same'
79
+ end
80
+ common_prefixes([params[:key], source_key])
81
+ else
82
+ params[:key]
83
+ end
84
+
85
+ credentials = provider.access_grants_credentials_for(
86
+ bucket: params[:bucket],
87
+ key: key,
88
+ prefix: params[:prefix],
89
+ permission: permission
90
+ )
91
+ context[:sigv4_credentials] = credentials # Sign will use this
92
+ end
93
+
94
+ with_metric(credentials) { @handler.call(context) }
95
+ end
96
+
97
+ private
98
+
99
+ def with_metric(credentials, &block)
100
+ return block.call unless credentials
101
+
102
+ Aws::Plugins::UserAgent.metric('S3_ACCESS_GRANTS', &block)
103
+ end
104
+
105
+ # HeadBucket is a supported call. When fetching credentials,
106
+ # this plugin is executed again, and becomes recursive.
107
+ def credentials_head_bucket_call?(provider)
108
+ provider.instance_variable_get(:@head_bucket_call)
109
+ end
110
+
111
+ def access_grants_operation?(context)
112
+ params = context[:endpoint_params]
113
+ params[:bucket] && PERMISSION_MAP[context.operation_name]
114
+ end
115
+
116
+ def s3_express_endpoint?(context)
117
+ context[:endpoint_properties]['backend'] == 'S3Express'
118
+ end
119
+
120
+ # Return the common prefix of the keys, regardless of the delimiter.
121
+ # For example, given keys ['foo/bar', 'foo/baz'], the common prefix
122
+ # is 'foo/ba'.
123
+ def common_prefixes(keys)
124
+ return '' if keys.empty?
125
+
126
+ first_key = keys[0]
127
+ common_ancestor = first_key
128
+ last_prefix = ''
129
+ keys.each do |k|
130
+ until common_ancestor.empty?
131
+ break if k.start_with?(common_ancestor)
132
+
133
+ last_index = common_ancestor.rindex('/')
134
+ return '' if last_index.nil?
135
+
136
+ last_prefix = common_ancestor[(last_index + 1)..-1]
137
+ common_ancestor = common_ancestor[0...last_index]
138
+ end
139
+ end
140
+ new_common_ancestor = "#{common_ancestor}/#{last_prefix}"
141
+ keys.each do |k|
142
+ until last_prefix.empty?
143
+ break if k.start_with?(new_common_ancestor)
144
+
145
+ last_prefix = last_prefix[0...-1]
146
+ new_common_ancestor = "#{common_ancestor}/#{last_prefix}"
147
+ end
148
+ end
149
+ if new_common_ancestor == "#{first_key}/"
150
+ first_key
151
+ else
152
+ new_common_ancestor
153
+ end
154
+ end
155
+ end
156
+
157
+ def add_handlers(handlers, config)
158
+ return unless AccessGrants.s3control? && config.access_grants
159
+
160
+ handlers.add(Handler)
161
+ end
162
+
163
+ def after_initialize(client)
164
+ return unless AccessGrants.s3control? && client.config.access_grants
165
+
166
+ provider = client.config.access_grants_credentials_provider
167
+ provider.s3_client = client unless provider.s3_client
168
+ end
169
+
170
+ class << self
171
+ def s3control?
172
+ @s3control
173
+ end
174
+ end
175
+ end
176
+ end
177
+ end
178
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module S3
5
+ module Plugins
6
+ # When an accesspoint ARN is provided for :bucket in S3 operations, this
7
+ # plugin resolves the request endpoint from the ARN when possible.
8
+ # @api private
9
+ class ARN < Seahorse::Client::Plugin
10
+ option(
11
+ :s3_use_arn_region,
12
+ default: true,
13
+ doc_type: 'Boolean',
14
+ docstring: <<-DOCS) do |cfg|
15
+ For S3 ARNs passed into the `:bucket` parameter, this option will
16
+ use the region in the ARN, allowing for cross-region requests to
17
+ be made. Set to `false` to use the client's region instead.
18
+ DOCS
19
+ resolve_s3_use_arn_region(cfg)
20
+ end
21
+
22
+ option(
23
+ :s3_disable_multiregion_access_points,
24
+ default: false,
25
+ doc_type: 'Boolean',
26
+ docstring: <<-DOCS) do |cfg|
27
+ When set to `false` this will option will raise errors when multi-region
28
+ access point ARNs are used. Multi-region access points can potentially
29
+ result in cross region requests.
30
+ DOCS
31
+ resolve_s3_disable_multiregion_access_points(cfg)
32
+ end
33
+
34
+ class << self
35
+ private
36
+
37
+ def resolve_s3_use_arn_region(cfg)
38
+ value = ENV['AWS_S3_USE_ARN_REGION'] ||
39
+ Aws.shared_config.s3_use_arn_region(profile: cfg.profile) ||
40
+ 'true'
41
+ value = Aws::Util.str_2_bool(value)
42
+ # Raise if provided value is not true or false
43
+ if value.nil?
44
+ raise ArgumentError,
45
+ 'Must provide either `true` or `false` for the '\
46
+ '`s3_use_arn_region` profile option or for '\
47
+ "ENV['AWS_S3_USE_ARN_REGION']."
48
+ end
49
+ value
50
+ end
51
+
52
+ def resolve_s3_disable_multiregion_access_points(cfg)
53
+ value = ENV['AWS_S3_DISABLE_MULTIREGION_ACCESS_POINTS'] ||
54
+ Aws.shared_config.s3_disable_multiregion_access_points(profile: cfg.profile) ||
55
+ 'false'
56
+ value = Aws::Util.str_2_bool(value)
57
+ # Raise if provided value is not true or false
58
+ if value.nil?
59
+ raise ArgumentError,
60
+ 'Must provide either `true` or `false` for '\
61
+ 's3_use_arn_region profile option or for '\
62
+ "ENV['AWS_S3_USE_ARN_REGION']"
63
+ end
64
+ value
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Aws
2
4
  module S3
3
5
  module Plugins
@@ -21,47 +23,10 @@ When set to `true`, the bucket name is always left in the
21
23
  request URI and never moved to the host as a sub-domain.
22
24
  DOCS
23
25
 
24
- def add_handlers(handlers, config)
25
- handlers.add(Handler) unless config.force_path_style
26
- end
27
-
28
- # @api private
29
- class Handler < Seahorse::Client::Handler
30
-
31
- def call(context)
32
- move_dns_compat_bucket_to_subdomain(context)
33
- @handler.call(context)
34
- end
35
-
36
- private
37
-
38
- def move_dns_compat_bucket_to_subdomain(context)
39
- bucket_name = context.params[:bucket]
40
- endpoint = context.http_request.endpoint
41
- if
42
- bucket_name &&
43
- BucketDns.dns_compatible?(bucket_name, https?(endpoint)) &&
44
- context.operation_name.to_s != 'get_bucket_location'
45
- then
46
- move_bucket_to_subdomain(bucket_name, endpoint)
47
- end
48
- end
49
-
50
- def move_bucket_to_subdomain(bucket_name, endpoint)
51
- endpoint.host = "#{bucket_name}.#{endpoint.host}"
52
- path = endpoint.path.sub("/#{bucket_name}", '')
53
- path = "/#{path}" unless path.match(/^\//)
54
- endpoint.path = path
55
- end
56
-
57
- def https?(uri)
58
- uri.scheme == 'https'
59
- end
60
-
61
- end
62
-
26
+ # These class methods were originally used in a handler in this plugin.
27
+ # SigV2 legacy signer needs this logic so we keep it here as utility.
28
+ # New endpoint resolution will check this as a matcher.
63
29
  class << self
64
-
65
30
  # @param [String] bucket_name
66
31
  # @param [Boolean] ssl
67
32
  # @return [Boolean]
@@ -73,15 +38,14 @@ request URI and never moved to the host as a sub-domain.
73
38
  end
74
39
  end
75
40
 
76
- private
77
-
41
+ # @param [String] bucket_name
42
+ # @return [Boolean]
78
43
  def valid_subdomain?(bucket_name)
79
44
  bucket_name.size < 64 &&
80
45
  bucket_name =~ /^[a-z0-9][a-z0-9.-]+[a-z0-9]$/ &&
81
46
  bucket_name !~ /(\d+\.){3}\d+/ &&
82
47
  bucket_name !~ /[.-]{2}/
83
48
  end
84
-
85
49
  end
86
50
  end
87
51
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Aws
2
4
  module S3
3
5
  module Plugins
@@ -5,14 +7,29 @@ module Aws
5
7
  class BucketNameRestrictions < Seahorse::Client::Plugin
6
8
  class Handler < Seahorse::Client::Handler
7
9
 
10
+ # Useful because Aws::S3::Errors::SignatureDoesNotMatch is thrown
11
+ # when passed a bucket with a forward slash. Instead provide a more
12
+ # helpful error. Ideally should not be a plugin?
8
13
  def call(context)
9
- if context.params.key?(:bucket) && context.params[:bucket].include?('/')
10
- msg = ":bucket option must not contain a forward-slash (/)"
11
- raise ArgumentError, msg
14
+ bucket_member = _bucket_member(context.operation.input.shape)
15
+ if bucket_member && (bucket = context.params[bucket_member])
16
+ if !Aws::ARNParser.arn?(bucket) && bucket.include?('/')
17
+ raise ArgumentError,
18
+ 'bucket name must not contain a forward-slash (/)'
19
+ end
12
20
  end
13
21
  @handler.call(context)
14
22
  end
15
23
 
24
+ private
25
+
26
+ def _bucket_member(input)
27
+ input.members.each do |member, ref|
28
+ return member if ref.shape.name == 'BucketName'
29
+ end
30
+ nil
31
+ end
32
+
16
33
  end
17
34
 
18
35
  handler(Handler)
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module S3
5
+ module Plugins
6
+ # @api private
7
+ class ChecksumAlgorithm < Seahorse::Client::Plugin
8
+
9
+ # S3 GetObject results for whole Multipart Objects contain a checksum
10
+ # that cannot be validated. These should be skipped by the
11
+ # ChecksumAlgorithm plugin.
12
+ class SkipWholeMultipartGetChecksumsHandler < Seahorse::Client::Handler
13
+ def call(context)
14
+ context[:http_checksum] ||= {}
15
+ context[:http_checksum][:skip_on_suffix] = true
16
+
17
+ @handler.call(context)
18
+ end
19
+ end
20
+
21
+ def add_handlers(handlers, _config)
22
+ handlers.add(
23
+ SkipWholeMultipartGetChecksumsHandler,
24
+ step: :initialize,
25
+ operations: [:get_object]
26
+ )
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,69 +1,26 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Aws
2
4
  module S3
3
5
  module Plugins
4
6
  # @api private
5
7
  class Dualstack < Seahorse::Client::Plugin
6
-
7
- option(:use_dualstack_endpoint,
8
- default: false,
9
- doc_type: 'Boolean',
10
- docstring: <<-DOCS)
11
- When set to `true`, IPv6-compatible bucket endpoints will be used
12
- for all operations.
13
- DOCS
14
-
15
- def add_handlers(handlers, config)
8
+ def add_handlers(handlers, _config)
16
9
  handlers.add(OptionHandler, step: :initialize)
17
- handlers.add(DualstackHandler, step: :build, priority: 0)
18
10
  end
19
11
 
20
12
  # @api private
21
13
  class OptionHandler < Seahorse::Client::Handler
22
14
  def call(context)
23
- dualstack = context.params.delete(:use_dualstack_endpoint)
15
+ # Support client configuration and per-operation configuration
16
+ if context.params.is_a?(Hash)
17
+ dualstack = context.params.delete(:use_dualstack_endpoint)
18
+ end
24
19
  dualstack = context.config.use_dualstack_endpoint if dualstack.nil?
25
20
  context[:use_dualstack_endpoint] = dualstack
26
21
  @handler.call(context)
27
22
  end
28
23
  end
29
-
30
- # @api private
31
- class DualstackHandler < Seahorse::Client::Handler
32
- def call(context)
33
- apply_dualstack_endpoint(context) if use_dualstack_endpoint?(context)
34
- @handler.call(context)
35
- end
36
-
37
- private
38
- def apply_dualstack_endpoint(context)
39
- bucket_name = context.params[:bucket]
40
- region = context.config.region
41
- context.config.force_path_style
42
- dns_suffix = Aws::Partitions::EndpointProvider.dns_suffix_for(region)
43
-
44
- if use_bucket_dns?(bucket_name, context)
45
- host = "#{bucket_name}.s3.dualstack.#{region}.#{dns_suffix}"
46
- else
47
- host = "s3.dualstack.#{region}.#{dns_suffix}"
48
- end
49
- endpoint = URI.parse(context.http_request.endpoint.to_s)
50
- endpoint.scheme = context.http_request.endpoint.scheme
51
- endpoint.port = context.http_request.endpoint.port
52
- endpoint.host = host
53
- context.http_request.endpoint = endpoint.to_s
54
- end
55
-
56
- def use_bucket_dns?(bucket_name, context)
57
- ssl = context.http_request.endpoint.scheme == "https"
58
- bucket_name && BucketDns.dns_compatible?(bucket_name, ssl) &&
59
- !context.config.force_path_style
60
- end
61
-
62
- def use_dualstack_endpoint?(context)
63
- context[:use_dualstack_endpoint] && !context[:use_accelerate_endpoint]
64
- end
65
- end
66
-
67
24
  end
68
25
  end
69
26
  end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ # WARNING ABOUT GENERATED CODE
4
+ #
5
+ # This file is generated. See the contributing guide for more information:
6
+ # https://github.com/aws/aws-sdk-ruby/blob/version-3/CONTRIBUTING.md
7
+ #
8
+ # WARNING ABOUT GENERATED CODE
9
+
10
+
11
+ module Aws::S3
12
+ module Plugins
13
+ class Endpoints < Seahorse::Client::Plugin
14
+ option(
15
+ :endpoint_provider,
16
+ doc_type: 'Aws::S3::EndpointProvider',
17
+ rbs_type: 'untyped',
18
+ docstring: <<~DOCS) do |_cfg|
19
+ The endpoint provider used to resolve endpoints. Any object that responds to
20
+ `#resolve_endpoint(parameters)` where `parameters` is a Struct similar to
21
+ `Aws::S3::EndpointParameters`.
22
+ DOCS
23
+ Aws::S3::EndpointProvider.new
24
+ end
25
+
26
+ option(
27
+ :disable_s3_express_session_auth,
28
+ doc_type: 'Boolean',
29
+ docstring: <<~DOCS) do |cfg|
30
+ Parameter to indicate whether S3Express session auth should be disabled
31
+ DOCS
32
+ nil
33
+ end
34
+
35
+ # @api private
36
+ class Handler < Seahorse::Client::Handler
37
+ def call(context)
38
+ unless context[:discovered_endpoint]
39
+ params = Aws::S3::Endpoints.parameters_for_operation(context)
40
+ endpoint = context.config.endpoint_provider.resolve_endpoint(params)
41
+
42
+ context.http_request.endpoint = endpoint.url
43
+ apply_endpoint_headers(context, endpoint.headers)
44
+
45
+ context[:endpoint_params] = params
46
+ context[:endpoint_properties] = endpoint.properties
47
+ end
48
+
49
+ context[:auth_scheme] =
50
+ Aws::Endpoints.resolve_auth_scheme(context, endpoint)
51
+
52
+ with_metrics(context) { @handler.call(context) }
53
+ end
54
+
55
+ private
56
+
57
+ def with_metrics(context, &block)
58
+ metrics = []
59
+ metrics << 'ENDPOINT_OVERRIDE' unless context.config.regional_endpoint
60
+ if context[:auth_scheme] && context[:auth_scheme]['name'] == 'sigv4a'
61
+ metrics << 'SIGV4A_SIGNING'
62
+ end
63
+ if context.config.credentials&.credentials&.account_id
64
+ metrics << 'RESOLVED_ACCOUNT_ID'
65
+ end
66
+ Aws::Plugins::UserAgent.metric(*metrics, &block)
67
+ end
68
+
69
+ def apply_endpoint_headers(context, headers)
70
+ headers.each do |key, values|
71
+ value = values
72
+ .compact
73
+ .map { |s| Seahorse::Util.escape_header_list_string(s.to_s) }
74
+ .join(',')
75
+
76
+ context.http_request.headers[key] = value
77
+ end
78
+ end
79
+ end
80
+
81
+ def add_handlers(handlers, _config)
82
+ handlers.add(Handler, step: :build, priority: 75)
83
+ end
84
+ end
85
+ end
86
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Aws
2
4
  module S3
3
5
  module Plugins
@@ -13,10 +15,9 @@ module Aws
13
15
  class Handler < Seahorse::Client::Handler
14
16
 
15
17
  def call(context)
16
- if
17
- context.http_request.body &&
18
- context.http_request.body.size > 0
19
- then
18
+ body = context.http_request.body
19
+ if body.respond_to?(:size) && body.size > 0 &&
20
+ !context[:use_accelerate_endpoint]
20
21
  context.http_request.headers['expect'] = '100-continue'
21
22
  end
22
23
  @handler.call(context)