aws-sdk-s3 1.48.0 → 1.169.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (134) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +1270 -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 +959 -106
  8. data/lib/aws-sdk-s3/bucket_acl.rb +64 -18
  9. data/lib/aws-sdk-s3/bucket_cors.rb +79 -18
  10. data/lib/aws-sdk-s3/bucket_lifecycle.rb +66 -20
  11. data/lib/aws-sdk-s3/bucket_lifecycle_configuration.rb +106 -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 +107 -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 +13765 -1019
  21. data/lib/aws-sdk-s3/client_api.rb +1137 -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 +592 -0
  61. data/lib/aws-sdk-s3/endpoints.rb +1392 -0
  62. data/lib/aws-sdk-s3/errors.rb +126 -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 +176 -44
  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 +82 -23
  71. data/lib/aws-sdk-s3/multipart_stream_uploader.rb +61 -21
  72. data/lib/aws-sdk-s3/multipart_upload.rb +265 -32
  73. data/lib/aws-sdk-s3/multipart_upload_error.rb +2 -0
  74. data/lib/aws-sdk-s3/multipart_upload_part.rb +367 -45
  75. data/lib/aws-sdk-s3/object.rb +2475 -228
  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 +2075 -203
  80. data/lib/aws-sdk-s3/object_version.rb +492 -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/dualstack.rb +7 -50
  87. data/lib/aws-sdk-s3/plugins/endpoints.rb +86 -0
  88. data/lib/aws-sdk-s3/plugins/expect_100_continue.rb +5 -4
  89. data/lib/aws-sdk-s3/plugins/express_session_auth.rb +97 -0
  90. data/lib/aws-sdk-s3/plugins/get_bucket_location_fix.rb +3 -1
  91. data/lib/aws-sdk-s3/plugins/http_200_errors.rb +60 -15
  92. data/lib/aws-sdk-s3/plugins/iad_regional_endpoint.rb +44 -0
  93. data/lib/aws-sdk-s3/plugins/location_constraint.rb +5 -1
  94. data/lib/aws-sdk-s3/plugins/md5s.rb +35 -30
  95. data/lib/aws-sdk-s3/plugins/redirects.rb +2 -0
  96. data/lib/aws-sdk-s3/plugins/s3_host_id.rb +2 -0
  97. data/lib/aws-sdk-s3/plugins/s3_signer.rb +63 -94
  98. data/lib/aws-sdk-s3/plugins/skip_whole_multipart_get_checksums.rb +31 -0
  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 +138 -59
  104. data/lib/aws-sdk-s3/resource.rb +155 -17
  105. data/lib/aws-sdk-s3/types.rb +12229 -4377
  106. data/lib/aws-sdk-s3/waiters.rb +67 -1
  107. data/lib/aws-sdk-s3.rb +46 -32
  108. data/sig/bucket.rbs +216 -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 +2406 -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 +34 -0
  125. data/sig/multipart_upload.rbs +111 -0
  126. data/sig/multipart_upload_part.rbs +105 -0
  127. data/sig/object.rbs +443 -0
  128. data/sig/object_acl.rbs +86 -0
  129. data/sig/object_summary.rbs +335 -0
  130. data/sig/object_version.rbs +137 -0
  131. data/sig/resource.rbs +132 -0
  132. data/sig/types.rbs +2596 -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)
@@ -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)