aws-sdk-s3 1.148.0 → 1.151.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -2
- data/VERSION +1 -1
- data/lib/aws-sdk-s3/access_grants_credentials.rb +57 -0
- data/lib/aws-sdk-s3/access_grants_credentials_provider.rb +241 -0
- data/lib/aws-sdk-s3/bucket_region_cache.rb +9 -5
- data/lib/aws-sdk-s3/client.rb +104 -91
- data/lib/aws-sdk-s3/client_api.rb +1 -0
- data/lib/aws-sdk-s3/customizations/errors.rb +15 -2
- data/lib/aws-sdk-s3/customizations.rb +4 -1
- data/lib/aws-sdk-s3/express_credentials_provider.rb +27 -4
- data/lib/aws-sdk-s3/object_multipart_copier.rb +10 -8
- data/lib/aws-sdk-s3/plugins/access_grants.rb +108 -0
- data/lib/aws-sdk-s3/plugins/express_session_auth.rb +1 -1
- data/lib/aws-sdk-s3/plugins/s3_signer.rb +7 -2
- data/lib/aws-sdk-s3.rb +1 -1
- data/sig/client.rbs +2 -0
- data/sig/customizations/bucket.rbs +19 -0
- data/sig/customizations/object.rbs +38 -0
- data/sig/customizations/object_summary.rbs +35 -0
- data/sig/resource.rbs +2 -0
- metadata +10 -5
- data/lib/aws-sdk-s3/express_credentials_cache.rb +0 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6114dedb4a21eb5fbf21942e75b07672dc196f796c7803d700294aa8e1a591af
|
4
|
+
data.tar.gz: 450308ca25390a935185963b6d90dcba80b8ad54fb692db8c39a0e9d70a40527
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 89f03a41c4dfa28e743e7948d96c088fc983610fc5b60af7e63e92b33f088c411d3f72d264bd447e6806963807eb6256938991d571e9df59eb641194b1a5b99d
|
7
|
+
data.tar.gz: '09c924fb2e88f0789fee482eb95eb7f3e636b8246c6ed2f28d410396fa5a199c74d4adfd1fbd7c33ef4524a72c7ee18e78e74d65f58f5219b166d0b96ec550d9'
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,28 @@
|
|
1
1
|
Unreleased Changes
|
2
2
|
------------------
|
3
3
|
|
4
|
+
1.151.0 (2024-05-14)
|
5
|
+
------------------
|
6
|
+
|
7
|
+
* Feature - Updated a few x-id in the http uri traits
|
8
|
+
|
9
|
+
1.150.0 (2024-05-13)
|
10
|
+
------------------
|
11
|
+
|
12
|
+
* Feature - Code Generated Changes, see `./build_tools` or `aws-sdk-core`'s CHANGELOG.md for details.
|
13
|
+
|
14
|
+
1.149.1 (2024-05-06)
|
15
|
+
------------------
|
16
|
+
|
17
|
+
* Issue - Fix bug where destination bucket default encryption was inadvertently overridden by source object encryption.
|
18
|
+
|
19
|
+
1.149.0 (2024-04-30)
|
20
|
+
------------------
|
21
|
+
|
22
|
+
* Feature - Support S3 Access Grants authentication. Access Grants can be enabled with the `access_grants` option, and custom options can be passed into the `access_grants_credentials_provider` option. This feature requires `aws-sdk-s3control` to be installed.
|
23
|
+
|
24
|
+
* Feature - Add RBS signatures for customizations of S3.
|
25
|
+
|
4
26
|
1.148.0 (2024-04-25)
|
5
27
|
------------------
|
6
28
|
|
@@ -38,7 +60,6 @@ Unreleased Changes
|
|
38
60
|
|
39
61
|
* Issue - Include original part errors in message when aborting multipart upload fails (#2990).
|
40
62
|
|
41
|
-
|
42
63
|
1.143.0 (2024-01-26)
|
43
64
|
------------------
|
44
65
|
|
@@ -161,7 +182,7 @@ Unreleased Changes
|
|
161
182
|
1.123.2 (2023-06-12)
|
162
183
|
------------------
|
163
184
|
|
164
|
-
* Issue - Fix issue when decrypting noncurrent versions of objects when using client side encryption (#2866).
|
185
|
+
* Issue - Fix issue when decrypting noncurrent versions of objects when using client side encryption (#2866).
|
165
186
|
|
166
187
|
1.123.1 (2023-06-02)
|
167
188
|
------------------
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.151.0
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'set'
|
4
|
+
|
5
|
+
module Aws
|
6
|
+
module S3
|
7
|
+
# @api private
|
8
|
+
class AccessGrantsCredentials
|
9
|
+
include CredentialProvider
|
10
|
+
include RefreshingCredentials
|
11
|
+
|
12
|
+
def initialize(options = {})
|
13
|
+
@client = options[:client]
|
14
|
+
@get_data_access_params = {}
|
15
|
+
options.each_pair do |key, value|
|
16
|
+
if self.class.get_data_access_options.include?(key)
|
17
|
+
@get_data_access_params[key] = value
|
18
|
+
end
|
19
|
+
end
|
20
|
+
@async_refresh = true
|
21
|
+
super
|
22
|
+
end
|
23
|
+
|
24
|
+
# @return [S3Control::Client]
|
25
|
+
attr_reader :client
|
26
|
+
|
27
|
+
# @return [String]
|
28
|
+
attr_reader :matched_grant_target
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def refresh
|
33
|
+
c = @client.get_data_access(@get_data_access_params)
|
34
|
+
credentials = c.credentials
|
35
|
+
@matched_grant_target = c.matched_grant_target
|
36
|
+
@credentials = Credentials.new(
|
37
|
+
credentials.access_key_id,
|
38
|
+
credentials.secret_access_key,
|
39
|
+
credentials.session_token
|
40
|
+
)
|
41
|
+
@expiration = credentials.expiration
|
42
|
+
end
|
43
|
+
|
44
|
+
class << self
|
45
|
+
|
46
|
+
# @api private
|
47
|
+
def get_data_access_options
|
48
|
+
@gdao ||= begin
|
49
|
+
input = Aws::S3Control::Client.api.operation(:get_data_access).input
|
50
|
+
Set.new(input.shape.member_names)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,241 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Aws
|
4
|
+
module S3
|
5
|
+
# @api private
|
6
|
+
def self.access_grants_credentials_cache
|
7
|
+
@access_grants_credentials_cache ||= LRUCache.new(max_entries: 100)
|
8
|
+
end
|
9
|
+
|
10
|
+
# @api private
|
11
|
+
def self.access_grants_account_id_cache
|
12
|
+
@access_grants_account_id_cache ||= LRUCache.new(
|
13
|
+
max_entries: 100,
|
14
|
+
expiration: 60 * 10
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Returns Credentials class for S3 Access Grants. Accepts GetDataAccess
|
19
|
+
# params and other configuration as options. See
|
20
|
+
# {Aws::S3Control::Client#get_data_access} for details.
|
21
|
+
class AccessGrantsCredentialsProvider
|
22
|
+
# @param [Hash] options
|
23
|
+
# @option options [Hash] :s3_control_client_options The S3 Control
|
24
|
+
# client options used to create regional S3 Control clients to
|
25
|
+
# create the session. Region will be set to the region of the
|
26
|
+
# bucket.
|
27
|
+
# @option options [Aws::STS::Client] :sts_client The STS client used for
|
28
|
+
# fetching the Account ID for the credentials if credentials do not
|
29
|
+
# include an Account ID.
|
30
|
+
# @option options [Aws::S3::Client] :s3_client The S3 client used for
|
31
|
+
# fetching the location of the bucket so that a regional S3 Control
|
32
|
+
# client can be created. Defaults to the S3 client from the access
|
33
|
+
# grants plugin.
|
34
|
+
# @option options [String] :privilege ('Default') The privilege to use
|
35
|
+
# when requesting credentials. (see: {Aws::S3Control::Client#get_data_access})
|
36
|
+
# @option options [Boolean] :fallback (false) When true, if access is
|
37
|
+
# denied, the provider will fall back to the configured credentials.
|
38
|
+
# @option options [Boolean] :caching (true) When true, credentials and
|
39
|
+
# bucket account ids will be cached.
|
40
|
+
# @option options [Callable] :before_refresh Proc called before
|
41
|
+
# credentials are refreshed.
|
42
|
+
def initialize(options = {})
|
43
|
+
@s3_control_options = options.delete(:s3_control_client_options) || {}
|
44
|
+
@s3_client = options.delete(:s3_client)
|
45
|
+
@sts_client = options.delete(:sts_client)
|
46
|
+
@fallback = options.delete(:fallback) || false
|
47
|
+
@caching = options.delete(:caching) != false
|
48
|
+
@s3_control_clients = {}
|
49
|
+
@bucket_region_cache = Aws::S3.bucket_region_cache
|
50
|
+
return unless @caching
|
51
|
+
|
52
|
+
@credentials_cache = Aws::S3.access_grants_credentials_cache
|
53
|
+
@account_id_cache = Aws::S3.access_grants_account_id_cache
|
54
|
+
end
|
55
|
+
|
56
|
+
def access_grants_credentials_for(options = {})
|
57
|
+
target = target_prefix(
|
58
|
+
options[:bucket],
|
59
|
+
options[:key],
|
60
|
+
options[:prefix]
|
61
|
+
)
|
62
|
+
credentials = s3_client.config.credentials.credentials # resolves
|
63
|
+
|
64
|
+
if @caching
|
65
|
+
cached_credentials_for(target, options[:permission], credentials)
|
66
|
+
else
|
67
|
+
new_credentials_for(target, options[:permission], credentials)
|
68
|
+
end
|
69
|
+
rescue Aws::S3Control::Errors::AccessDenied
|
70
|
+
raise unless @fallback
|
71
|
+
|
72
|
+
warn 'Access denied for S3 Access Grants. Falling back to ' \
|
73
|
+
'configured credentials.'
|
74
|
+
s3_client.config.credentials
|
75
|
+
end
|
76
|
+
|
77
|
+
attr_accessor :s3_client
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def s3_control_client(bucket_region)
|
82
|
+
@s3_control_clients[bucket_region] ||= begin
|
83
|
+
credentials = s3_client.config.credentials
|
84
|
+
config = { credentials: credentials }.merge(@s3_control_options)
|
85
|
+
Aws::S3Control::Client.new(config.merge(
|
86
|
+
region: bucket_region,
|
87
|
+
use_fips_endpoint: s3_client.config.use_fips_endpoint,
|
88
|
+
use_dualstack_endpoint: s3_client.config.use_dualstack_endpoint
|
89
|
+
))
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def cached_credentials_for(target, permission, credentials)
|
94
|
+
cached_creds = broad_search_credentials_cache_prefix(target, permission, credentials)
|
95
|
+
return cached_creds if cached_creds
|
96
|
+
|
97
|
+
if %w[READ WRITE].include?(permission)
|
98
|
+
cached_creds = broad_search_credentials_cache_prefix(target, 'READWRITE', credentials)
|
99
|
+
return cached_creds if cached_creds
|
100
|
+
end
|
101
|
+
|
102
|
+
cached_creds = broad_search_credentials_cache_characters(target, permission, credentials)
|
103
|
+
return cached_creds if cached_creds
|
104
|
+
|
105
|
+
if %w[READ WRITE].include?(permission)
|
106
|
+
cached_creds = broad_search_credentials_cache_characters(target, 'READWRITE', credentials)
|
107
|
+
return cached_creds if cached_creds
|
108
|
+
end
|
109
|
+
|
110
|
+
creds = new_credentials_for(target, permission, credentials)
|
111
|
+
if creds.matched_grant_target.end_with?('*')
|
112
|
+
# remove /* from the end of the target
|
113
|
+
key = credentials_cache_key(creds.matched_grant_target[0...-2], permission, credentials)
|
114
|
+
@credentials_cache[key] = creds
|
115
|
+
end
|
116
|
+
|
117
|
+
creds
|
118
|
+
end
|
119
|
+
|
120
|
+
def broad_search_credentials_cache_prefix(target, permission, credentials)
|
121
|
+
prefix = target
|
122
|
+
while prefix != 's3:'
|
123
|
+
key = credentials_cache_key(prefix, permission, credentials)
|
124
|
+
return @credentials_cache[key] if @credentials_cache.key?(key)
|
125
|
+
|
126
|
+
prefix = prefix.split('/', -1)[0..-2].join('/')
|
127
|
+
end
|
128
|
+
nil
|
129
|
+
end
|
130
|
+
|
131
|
+
def broad_search_credentials_cache_characters(target, permission, credentials)
|
132
|
+
prefix = target
|
133
|
+
while prefix != 's3://'
|
134
|
+
key = credentials_cache_key("#{prefix}*", permission, credentials)
|
135
|
+
return @credentials_cache[key] if @credentials_cache.key?(key)
|
136
|
+
|
137
|
+
prefix = prefix[0..-2]
|
138
|
+
end
|
139
|
+
nil
|
140
|
+
end
|
141
|
+
|
142
|
+
def new_credentials_for(target, permission, credentials)
|
143
|
+
bucket_region = bucket_region_for_access_grants(target)
|
144
|
+
client = s3_control_client(bucket_region)
|
145
|
+
|
146
|
+
AccessGrantsCredentials.new(
|
147
|
+
target: target,
|
148
|
+
account_id: account_id_for_access_grants(target, credentials),
|
149
|
+
permission: permission,
|
150
|
+
client: client
|
151
|
+
)
|
152
|
+
end
|
153
|
+
|
154
|
+
def account_id_for_access_grants(target, credentials)
|
155
|
+
if @caching
|
156
|
+
cached_account_id_for(target, credentials)
|
157
|
+
else
|
158
|
+
new_account_id_for(target, credentials)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def cached_account_id_for(target, credentials)
|
163
|
+
bucket = bucket_name_from(target)
|
164
|
+
|
165
|
+
if @account_id_cache.key?(bucket)
|
166
|
+
@account_id_cache[bucket]
|
167
|
+
else
|
168
|
+
@account_id_cache[bucket] = new_account_id_for(target, credentials)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
# returns the account id associated with the access grants instance
|
173
|
+
def new_account_id_for(target, credentials)
|
174
|
+
bucket_region = bucket_region_for_access_grants(target)
|
175
|
+
s3_control_client = s3_control_client(bucket_region)
|
176
|
+
resp = s3_control_client.get_access_grants_instance_for_prefix(
|
177
|
+
s3_prefix: target,
|
178
|
+
account_id: account_id_for_credentials(bucket_region, credentials)
|
179
|
+
)
|
180
|
+
ARNParser.parse(resp.access_grants_instance_arn).account_id
|
181
|
+
end
|
182
|
+
|
183
|
+
def bucket_region_for_access_grants(target)
|
184
|
+
bucket = bucket_name_from(target)
|
185
|
+
# regardless of caching option, bucket region cache is always shared
|
186
|
+
cached_bucket_region_for(bucket)
|
187
|
+
end
|
188
|
+
|
189
|
+
def cached_bucket_region_for(bucket)
|
190
|
+
if @bucket_region_cache.key?(bucket)
|
191
|
+
@bucket_region_cache[bucket]
|
192
|
+
else
|
193
|
+
@bucket_region_cache[bucket] = new_bucket_region_for(bucket)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
def new_bucket_region_for(bucket)
|
198
|
+
@s3_client.head_bucket(bucket: bucket).bucket_region
|
199
|
+
rescue Aws::S3::Errors::Http301Error => e
|
200
|
+
e.data.region
|
201
|
+
end
|
202
|
+
|
203
|
+
# returns the account id for the configured credentials
|
204
|
+
def account_id_for_credentials(region, credentials)
|
205
|
+
# use resolved credentials to check for account id
|
206
|
+
if credentials.respond_to?(:account_id) && credentials.account_id &&
|
207
|
+
!credentials.account_id.empty?
|
208
|
+
credentials.account_id
|
209
|
+
else
|
210
|
+
@sts_client ||= Aws::STS::Client.new(
|
211
|
+
credentials: s3_client.config.credentials,
|
212
|
+
region: region,
|
213
|
+
use_fips_endpoint: s3_client.config.use_fips_endpoint,
|
214
|
+
use_dualstack_endpoint: s3_client.config.use_dualstack_endpoint
|
215
|
+
)
|
216
|
+
@sts_client.get_caller_identity.account
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
def target_prefix(bucket, key, prefix)
|
221
|
+
if key && !key.empty?
|
222
|
+
"s3://#{bucket}/#{key}"
|
223
|
+
elsif prefix && !prefix.empty?
|
224
|
+
"s3://#{bucket}/#{prefix}"
|
225
|
+
else
|
226
|
+
"s3://#{bucket}/*"
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
def credentials_cache_key(target, permission, credentials)
|
231
|
+
"#{credentials.access_key_id}-#{credentials.secret_access_key}" \
|
232
|
+
"-#{permission}-#{target}"
|
233
|
+
end
|
234
|
+
|
235
|
+
# extracts bucket name from target prefix
|
236
|
+
def bucket_name_from(target)
|
237
|
+
URI(target).host
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
@@ -15,7 +15,7 @@ module Aws
|
|
15
15
|
# Registers a block as a callback. This listener is called when a
|
16
16
|
# new bucket/region pair is added to the cache.
|
17
17
|
#
|
18
|
-
# S3
|
18
|
+
# Aws::S3.bucket_region_cache.bucket_added do |bucket_name, region_name|
|
19
19
|
# # ...
|
20
20
|
# end
|
21
21
|
#
|
@@ -59,6 +59,14 @@ module Aws
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
+
# @param [String] key
|
63
|
+
# @return [Boolean]
|
64
|
+
def key?(key)
|
65
|
+
@mutex.synchronize do
|
66
|
+
@regions.key?(key)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
62
70
|
# @api private
|
63
71
|
def clear
|
64
72
|
@mutex.synchronize { @regions = {} }
|
@@ -73,9 +81,5 @@ module Aws
|
|
73
81
|
alias to_h to_hash
|
74
82
|
|
75
83
|
end
|
76
|
-
|
77
|
-
# @api private
|
78
|
-
BUCKET_REGIONS = BucketRegionCache.new
|
79
|
-
|
80
84
|
end
|
81
85
|
end
|
data/lib/aws-sdk-s3/client.rb
CHANGED
@@ -35,6 +35,7 @@ require 'aws-sdk-core/plugins/recursion_detection.rb'
|
|
35
35
|
require 'aws-sdk-core/plugins/sign.rb'
|
36
36
|
require 'aws-sdk-core/plugins/protocols/rest_xml.rb'
|
37
37
|
require 'aws-sdk-s3/plugins/accelerate.rb'
|
38
|
+
require 'aws-sdk-s3/plugins/access_grants.rb'
|
38
39
|
require 'aws-sdk-s3/plugins/arn.rb'
|
39
40
|
require 'aws-sdk-s3/plugins/bucket_dns.rb'
|
40
41
|
require 'aws-sdk-s3/plugins/bucket_name_restrictions.rb'
|
@@ -106,6 +107,7 @@ module Aws::S3
|
|
106
107
|
add_plugin(Aws::Plugins::Sign)
|
107
108
|
add_plugin(Aws::Plugins::Protocols::RestXml)
|
108
109
|
add_plugin(Aws::S3::Plugins::Accelerate)
|
110
|
+
add_plugin(Aws::S3::Plugins::AccessGrants)
|
109
111
|
add_plugin(Aws::S3::Plugins::ARN)
|
110
112
|
add_plugin(Aws::S3::Plugins::BucketDns)
|
111
113
|
add_plugin(Aws::S3::Plugins::BucketNameRestrictions)
|
@@ -186,6 +188,16 @@ module Aws::S3
|
|
186
188
|
# * `~/.aws/credentials`
|
187
189
|
# * `~/.aws/config`
|
188
190
|
#
|
191
|
+
# @option options [Boolean] :access_grants (false)
|
192
|
+
# When `true`, the S3 client will use the S3 Access Grants feature to
|
193
|
+
# authenticate requests. Bucket credentials will be fetched from S3
|
194
|
+
# Control using the `get_data_access` API.
|
195
|
+
#
|
196
|
+
# @option options [Aws::S3::AccessGrantsCredentialsProvider] :access_grants_credentials_provider
|
197
|
+
# When `access_grants` is `true`, this option can be used to provide
|
198
|
+
# additional options to the credentials provider, including a privilege
|
199
|
+
# setting, caching, and fallback behavior.
|
200
|
+
#
|
189
201
|
# @option options [String] :access_key_id
|
190
202
|
#
|
191
203
|
# @option options [Boolean] :active_endpoint_cache (false)
|
@@ -391,8 +403,9 @@ module Aws::S3
|
|
391
403
|
#
|
392
404
|
# @option options [String] :sdk_ua_app_id
|
393
405
|
# A unique and opaque application ID that is appended to the
|
394
|
-
# User-Agent header as app
|
395
|
-
# maximum length of 50.
|
406
|
+
# User-Agent header as app/sdk_ua_app_id. It should have a
|
407
|
+
# maximum length of 50. This variable is sourced from environment
|
408
|
+
# variable AWS_SDK_UA_APP_ID or the shared config profile attribute sdk_ua_app_id.
|
396
409
|
#
|
397
410
|
# @option options [String] :secret_access_key
|
398
411
|
#
|
@@ -4474,6 +4487,15 @@ module Aws::S3
|
|
4474
4487
|
# * {Types::DeleteObjectOutput#request_charged #request_charged} => String
|
4475
4488
|
#
|
4476
4489
|
#
|
4490
|
+
# @example Example: To delete an object (from a non-versioned bucket)
|
4491
|
+
#
|
4492
|
+
# # The following example deletes an object from a non-versioned bucket.
|
4493
|
+
#
|
4494
|
+
# resp = client.delete_object({
|
4495
|
+
# bucket: "ExampleBucket",
|
4496
|
+
# key: "HappyFace.jpg",
|
4497
|
+
# })
|
4498
|
+
#
|
4477
4499
|
# @example Example: To delete an object
|
4478
4500
|
#
|
4479
4501
|
# # The following example deletes an object from an S3 bucket.
|
@@ -4487,15 +4509,6 @@ module Aws::S3
|
|
4487
4509
|
# {
|
4488
4510
|
# }
|
4489
4511
|
#
|
4490
|
-
# @example Example: To delete an object (from a non-versioned bucket)
|
4491
|
-
#
|
4492
|
-
# # The following example deletes an object from a non-versioned bucket.
|
4493
|
-
#
|
4494
|
-
# resp = client.delete_object({
|
4495
|
-
# bucket: "ExampleBucket",
|
4496
|
-
# key: "HappyFace.jpg",
|
4497
|
-
# })
|
4498
|
-
#
|
4499
4512
|
# @example Request syntax with placeholder values
|
4500
4513
|
#
|
4501
4514
|
# resp = client.delete_object({
|
@@ -4905,22 +4918,20 @@ module Aws::S3
|
|
4905
4918
|
# * {Types::DeleteObjectsOutput#errors #errors} => Array<Types::Error>
|
4906
4919
|
#
|
4907
4920
|
#
|
4908
|
-
# @example Example: To delete multiple
|
4921
|
+
# @example Example: To delete multiple objects from a versioned bucket
|
4909
4922
|
#
|
4910
|
-
# # The following example deletes objects from a bucket. The
|
4911
|
-
# #
|
4923
|
+
# # The following example deletes objects from a bucket. The bucket is versioned, and the request does not specify the
|
4924
|
+
# # object version to delete. In this case, all versions remain in the bucket and S3 adds a delete marker.
|
4912
4925
|
#
|
4913
4926
|
# resp = client.delete_objects({
|
4914
4927
|
# bucket: "examplebucket",
|
4915
4928
|
# delete: {
|
4916
4929
|
# objects: [
|
4917
4930
|
# {
|
4918
|
-
# key: "
|
4919
|
-
# version_id: "2LWg7lQLnY41.maGB5Z6SWW.dcq0vx7b",
|
4931
|
+
# key: "objectkey1",
|
4920
4932
|
# },
|
4921
4933
|
# {
|
4922
|
-
# key: "
|
4923
|
-
# version_id: "yoz3HB.ZhCS_tKVEmIOr7qYyyAaZSKVd",
|
4934
|
+
# key: "objectkey2",
|
4924
4935
|
# },
|
4925
4936
|
# ],
|
4926
4937
|
# quiet: false,
|
@@ -4931,30 +4942,34 @@ module Aws::S3
|
|
4931
4942
|
# {
|
4932
4943
|
# deleted: [
|
4933
4944
|
# {
|
4934
|
-
#
|
4935
|
-
#
|
4945
|
+
# delete_marker: true,
|
4946
|
+
# delete_marker_version_id: "A._w1z6EFiCF5uhtQMDal9JDkID9tQ7F",
|
4947
|
+
# key: "objectkey1",
|
4936
4948
|
# },
|
4937
4949
|
# {
|
4938
|
-
#
|
4939
|
-
#
|
4950
|
+
# delete_marker: true,
|
4951
|
+
# delete_marker_version_id: "iOd_ORxhkKe_e8G8_oSGxt2PjsCZKlkt",
|
4952
|
+
# key: "objectkey2",
|
4940
4953
|
# },
|
4941
4954
|
# ],
|
4942
4955
|
# }
|
4943
4956
|
#
|
4944
|
-
# @example Example: To delete multiple
|
4957
|
+
# @example Example: To delete multiple object versions from a versioned bucket
|
4945
4958
|
#
|
4946
|
-
# # The following example deletes objects from a bucket. The
|
4947
|
-
# #
|
4959
|
+
# # The following example deletes objects from a bucket. The request specifies object versions. S3 deletes specific object
|
4960
|
+
# # versions and returns the key and versions of deleted objects in the response.
|
4948
4961
|
#
|
4949
4962
|
# resp = client.delete_objects({
|
4950
4963
|
# bucket: "examplebucket",
|
4951
4964
|
# delete: {
|
4952
4965
|
# objects: [
|
4953
4966
|
# {
|
4954
|
-
# key: "
|
4967
|
+
# key: "HappyFace.jpg",
|
4968
|
+
# version_id: "2LWg7lQLnY41.maGB5Z6SWW.dcq0vx7b",
|
4955
4969
|
# },
|
4956
4970
|
# {
|
4957
|
-
# key: "
|
4971
|
+
# key: "HappyFace.jpg",
|
4972
|
+
# version_id: "yoz3HB.ZhCS_tKVEmIOr7qYyyAaZSKVd",
|
4958
4973
|
# },
|
4959
4974
|
# ],
|
4960
4975
|
# quiet: false,
|
@@ -4965,14 +4980,12 @@ module Aws::S3
|
|
4965
4980
|
# {
|
4966
4981
|
# deleted: [
|
4967
4982
|
# {
|
4968
|
-
#
|
4969
|
-
#
|
4970
|
-
# key: "objectkey1",
|
4983
|
+
# key: "HappyFace.jpg",
|
4984
|
+
# version_id: "yoz3HB.ZhCS_tKVEmIOr7qYyyAaZSKVd",
|
4971
4985
|
# },
|
4972
4986
|
# {
|
4973
|
-
#
|
4974
|
-
#
|
4975
|
-
# key: "objectkey2",
|
4987
|
+
# key: "HappyFace.jpg",
|
4988
|
+
# version_id: "2LWg7lQLnY41.maGB5Z6SWW.dcq0vx7b",
|
4976
4989
|
# },
|
4977
4990
|
# ],
|
4978
4991
|
# }
|
@@ -8722,49 +8735,49 @@ module Aws::S3
|
|
8722
8735
|
# * {Types::GetObjectTaggingOutput#tag_set #tag_set} => Array<Types::Tag>
|
8723
8736
|
#
|
8724
8737
|
#
|
8725
|
-
# @example Example: To retrieve tag set of
|
8738
|
+
# @example Example: To retrieve tag set of an object
|
8726
8739
|
#
|
8727
|
-
# # The following example retrieves tag set of an object.
|
8740
|
+
# # The following example retrieves tag set of an object.
|
8728
8741
|
#
|
8729
8742
|
# resp = client.get_object_tagging({
|
8730
8743
|
# bucket: "examplebucket",
|
8731
|
-
# key: "
|
8732
|
-
# version_id: "ydlaNkwWm0SfKJR.T1b1fIdPRbldTYRI",
|
8744
|
+
# key: "HappyFace.jpg",
|
8733
8745
|
# })
|
8734
8746
|
#
|
8735
8747
|
# resp.to_h outputs the following:
|
8736
8748
|
# {
|
8737
8749
|
# tag_set: [
|
8738
8750
|
# {
|
8739
|
-
# key: "
|
8740
|
-
# value: "
|
8751
|
+
# key: "Key4",
|
8752
|
+
# value: "Value4",
|
8753
|
+
# },
|
8754
|
+
# {
|
8755
|
+
# key: "Key3",
|
8756
|
+
# value: "Value3",
|
8741
8757
|
# },
|
8742
8758
|
# ],
|
8743
|
-
# version_id: "
|
8759
|
+
# version_id: "null",
|
8744
8760
|
# }
|
8745
8761
|
#
|
8746
|
-
# @example Example: To retrieve tag set of
|
8762
|
+
# @example Example: To retrieve tag set of a specific object version
|
8747
8763
|
#
|
8748
|
-
# # The following example retrieves tag set of an object.
|
8764
|
+
# # The following example retrieves tag set of an object. The request specifies object version.
|
8749
8765
|
#
|
8750
8766
|
# resp = client.get_object_tagging({
|
8751
8767
|
# bucket: "examplebucket",
|
8752
|
-
# key: "
|
8768
|
+
# key: "exampleobject",
|
8769
|
+
# version_id: "ydlaNkwWm0SfKJR.T1b1fIdPRbldTYRI",
|
8753
8770
|
# })
|
8754
8771
|
#
|
8755
8772
|
# resp.to_h outputs the following:
|
8756
8773
|
# {
|
8757
8774
|
# tag_set: [
|
8758
8775
|
# {
|
8759
|
-
# key: "
|
8760
|
-
# value: "
|
8761
|
-
# },
|
8762
|
-
# {
|
8763
|
-
# key: "Key3",
|
8764
|
-
# value: "Value3",
|
8776
|
+
# key: "Key1",
|
8777
|
+
# value: "Value1",
|
8765
8778
|
# },
|
8766
8779
|
# ],
|
8767
|
-
# version_id: "
|
8780
|
+
# version_id: "ydlaNkwWm0SfKJR.T1b1fIdPRbldTYRI",
|
8768
8781
|
# }
|
8769
8782
|
#
|
8770
8783
|
# @example Request syntax with placeholder values
|
@@ -15397,21 +15410,25 @@ module Aws::S3
|
|
15397
15410
|
# * {Types::PutObjectOutput#request_charged #request_charged} => String
|
15398
15411
|
#
|
15399
15412
|
#
|
15400
|
-
# @example Example: To upload
|
15413
|
+
# @example Example: To upload object and specify user-defined metadata
|
15401
15414
|
#
|
15402
|
-
# # The following example
|
15403
|
-
# #
|
15415
|
+
# # The following example creates an object. The request also specifies optional metadata. If the bucket is versioning
|
15416
|
+
# # enabled, S3 returns version ID in response.
|
15404
15417
|
#
|
15405
15418
|
# resp = client.put_object({
|
15406
|
-
# body: "
|
15419
|
+
# body: "filetoupload",
|
15407
15420
|
# bucket: "examplebucket",
|
15408
|
-
# key: "
|
15421
|
+
# key: "exampleobject",
|
15422
|
+
# metadata: {
|
15423
|
+
# "metadata1" => "value1",
|
15424
|
+
# "metadata2" => "value2",
|
15425
|
+
# },
|
15409
15426
|
# })
|
15410
15427
|
#
|
15411
15428
|
# resp.to_h outputs the following:
|
15412
15429
|
# {
|
15413
15430
|
# etag: "\"6805f2cfc46c0f04559748bb039d69ae\"",
|
15414
|
-
# version_id: "
|
15431
|
+
# version_id: "pSKidl4pHBiNwukdbcPXAIs.sshFFOc0",
|
15415
15432
|
# }
|
15416
15433
|
#
|
15417
15434
|
# @example Example: To upload an object (specify optional headers)
|
@@ -15434,97 +15451,93 @@ module Aws::S3
|
|
15434
15451
|
# version_id: "CG612hodqujkf8FaaNfp8U..FIhLROcp",
|
15435
15452
|
# }
|
15436
15453
|
#
|
15437
|
-
# @example Example: To upload object and specify
|
15454
|
+
# @example Example: To upload an object and specify optional tags
|
15438
15455
|
#
|
15439
|
-
# # The following example
|
15440
|
-
# #
|
15456
|
+
# # The following example uploads an object. The request specifies optional object tags. The bucket is versioned, therefore
|
15457
|
+
# # S3 returns version ID of the newly created object.
|
15441
15458
|
#
|
15442
15459
|
# resp = client.put_object({
|
15443
|
-
# body: "
|
15460
|
+
# body: "c:\\HappyFace.jpg",
|
15444
15461
|
# bucket: "examplebucket",
|
15445
|
-
# key: "
|
15446
|
-
#
|
15447
|
-
# "metadata1" => "value1",
|
15448
|
-
# "metadata2" => "value2",
|
15449
|
-
# },
|
15462
|
+
# key: "HappyFace.jpg",
|
15463
|
+
# tagging: "key1=value1&key2=value2",
|
15450
15464
|
# })
|
15451
15465
|
#
|
15452
15466
|
# resp.to_h outputs the following:
|
15453
15467
|
# {
|
15454
15468
|
# etag: "\"6805f2cfc46c0f04559748bb039d69ae\"",
|
15455
|
-
# version_id: "
|
15469
|
+
# version_id: "psM2sYY4.o1501dSx8wMvnkOzSBB.V4a",
|
15456
15470
|
# }
|
15457
15471
|
#
|
15458
|
-
# @example Example: To
|
15472
|
+
# @example Example: To create an object.
|
15459
15473
|
#
|
15460
|
-
# # The following example
|
15461
|
-
# # access to authenticated users. If the bucket is versioning enabled, S3 returns version ID in response.
|
15474
|
+
# # The following example creates an object. If the bucket is versioning enabled, S3 returns version ID in response.
|
15462
15475
|
#
|
15463
15476
|
# resp = client.put_object({
|
15464
|
-
# acl: "authenticated-read",
|
15465
15477
|
# body: "filetoupload",
|
15466
15478
|
# bucket: "examplebucket",
|
15467
|
-
# key: "
|
15479
|
+
# key: "objectkey",
|
15468
15480
|
# })
|
15469
15481
|
#
|
15470
15482
|
# resp.to_h outputs the following:
|
15471
15483
|
# {
|
15472
15484
|
# etag: "\"6805f2cfc46c0f04559748bb039d69ae\"",
|
15473
|
-
# version_id: "
|
15485
|
+
# version_id: "Bvq0EDKxOcXLJXNo_Lkz37eM3R4pfzyQ",
|
15474
15486
|
# }
|
15475
15487
|
#
|
15476
|
-
# @example Example: To
|
15488
|
+
# @example Example: To upload an object
|
15477
15489
|
#
|
15478
|
-
# # The following example
|
15490
|
+
# # The following example uploads an object to a versioning-enabled bucket. The source file is specified using Windows file
|
15491
|
+
# # syntax. S3 returns VersionId of the newly created object.
|
15479
15492
|
#
|
15480
15493
|
# resp = client.put_object({
|
15481
|
-
# body: "
|
15494
|
+
# body: "HappyFace.jpg",
|
15482
15495
|
# bucket: "examplebucket",
|
15483
|
-
# key: "
|
15496
|
+
# key: "HappyFace.jpg",
|
15484
15497
|
# })
|
15485
15498
|
#
|
15486
15499
|
# resp.to_h outputs the following:
|
15487
15500
|
# {
|
15488
15501
|
# etag: "\"6805f2cfc46c0f04559748bb039d69ae\"",
|
15489
|
-
# version_id: "
|
15502
|
+
# version_id: "tpf3zF08nBplQK1XLOefGskR7mGDwcDk",
|
15490
15503
|
# }
|
15491
15504
|
#
|
15492
|
-
# @example Example: To upload an object and specify
|
15505
|
+
# @example Example: To upload an object and specify canned ACL.
|
15493
15506
|
#
|
15494
|
-
# # The following example uploads
|
15495
|
-
# #
|
15507
|
+
# # The following example uploads and object. The request specifies optional canned ACL (access control list) to all READ
|
15508
|
+
# # access to authenticated users. If the bucket is versioning enabled, S3 returns version ID in response.
|
15496
15509
|
#
|
15497
15510
|
# resp = client.put_object({
|
15511
|
+
# acl: "authenticated-read",
|
15498
15512
|
# body: "filetoupload",
|
15499
15513
|
# bucket: "examplebucket",
|
15500
15514
|
# key: "exampleobject",
|
15501
|
-
# server_side_encryption: "AES256",
|
15502
|
-
# tagging: "key1=value1&key2=value2",
|
15503
15515
|
# })
|
15504
15516
|
#
|
15505
15517
|
# resp.to_h outputs the following:
|
15506
15518
|
# {
|
15507
15519
|
# etag: "\"6805f2cfc46c0f04559748bb039d69ae\"",
|
15508
|
-
#
|
15509
|
-
# version_id: "Ri.vC6qVlA4dEnjgRV4ZHsHoFIjqEMNt",
|
15520
|
+
# version_id: "Kirh.unyZwjQ69YxcQLA8z4F5j3kJJKr",
|
15510
15521
|
# }
|
15511
15522
|
#
|
15512
|
-
# @example Example: To upload an object and specify
|
15523
|
+
# @example Example: To upload an object and specify server-side encryption and object tags
|
15513
15524
|
#
|
15514
|
-
# # The following example uploads an object. The request specifies optional
|
15515
|
-
# # S3 returns version ID
|
15525
|
+
# # The following example uploads an object. The request specifies the optional server-side encryption option. The request
|
15526
|
+
# # also specifies optional object tags. If the bucket is versioning enabled, S3 returns version ID in response.
|
15516
15527
|
#
|
15517
15528
|
# resp = client.put_object({
|
15518
|
-
# body: "
|
15529
|
+
# body: "filetoupload",
|
15519
15530
|
# bucket: "examplebucket",
|
15520
|
-
# key: "
|
15531
|
+
# key: "exampleobject",
|
15532
|
+
# server_side_encryption: "AES256",
|
15521
15533
|
# tagging: "key1=value1&key2=value2",
|
15522
15534
|
# })
|
15523
15535
|
#
|
15524
15536
|
# resp.to_h outputs the following:
|
15525
15537
|
# {
|
15526
15538
|
# etag: "\"6805f2cfc46c0f04559748bb039d69ae\"",
|
15527
|
-
#
|
15539
|
+
# server_side_encryption: "AES256",
|
15540
|
+
# version_id: "Ri.vC6qVlA4dEnjgRV4ZHsHoFIjqEMNt",
|
15528
15541
|
# }
|
15529
15542
|
#
|
15530
15543
|
# @example Streaming a file from disk
|
@@ -18815,7 +18828,7 @@ module Aws::S3
|
|
18815
18828
|
params: params,
|
18816
18829
|
config: config)
|
18817
18830
|
context[:gem_name] = 'aws-sdk-s3'
|
18818
|
-
context[:gem_version] = '1.
|
18831
|
+
context[:gem_version] = '1.151.0'
|
18819
18832
|
Seahorse::Client::Request.new(handlers, context)
|
18820
18833
|
end
|
18821
18834
|
|
@@ -2764,6 +2764,7 @@ module Aws::S3
|
|
2764
2764
|
"endpointPrefix" => "s3",
|
2765
2765
|
"globalEndpoint" => "s3.amazonaws.com",
|
2766
2766
|
"protocol" => "rest-xml",
|
2767
|
+
"protocols" => ["rest-xml"],
|
2767
2768
|
"serviceAbbreviation" => "Amazon S3",
|
2768
2769
|
"serviceFullName" => "Amazon Simple Storage Service",
|
2769
2770
|
"serviceId" => "S3",
|
@@ -3,8 +3,8 @@
|
|
3
3
|
module Aws
|
4
4
|
module S3
|
5
5
|
module Errors
|
6
|
-
# Hijack PermanentRedirect dynamic error to
|
7
|
-
# and
|
6
|
+
# Hijack PermanentRedirect dynamic error to include the bucket, region,
|
7
|
+
# and endpoint.
|
8
8
|
class PermanentRedirect < ServiceError
|
9
9
|
# @param [Seahorse::Client::RequestContext] context
|
10
10
|
# @param [String] message
|
@@ -22,6 +22,19 @@ module Aws
|
|
22
22
|
super(context, message, data)
|
23
23
|
end
|
24
24
|
end
|
25
|
+
|
26
|
+
# Hijack PermanentRedirect (HeadBucket case - no body) dynamic error to
|
27
|
+
# include the region.
|
28
|
+
class Http301Error < ServiceError
|
29
|
+
# @param [Seahorse::Client::RequestContext] context
|
30
|
+
# @param [String] message
|
31
|
+
# @param [Aws::S3::Types::PermanentRedirect] _data
|
32
|
+
def initialize(context, message, _data = Aws::EmptyStructure.new)
|
33
|
+
data = Aws::S3::Types::PermanentRedirect.new(message: message)
|
34
|
+
data.region = context.http_response.headers['x-amz-bucket-region']
|
35
|
+
super(context, message, data)
|
36
|
+
end
|
37
|
+
end
|
25
38
|
end
|
26
39
|
end
|
27
40
|
end
|
@@ -18,9 +18,12 @@ require 'aws-sdk-s3/presigner'
|
|
18
18
|
|
19
19
|
# s3 express session auth
|
20
20
|
require 'aws-sdk-s3/express_credentials'
|
21
|
-
require 'aws-sdk-s3/express_credentials_cache'
|
22
21
|
require 'aws-sdk-s3/express_credentials_provider'
|
23
22
|
|
23
|
+
# s3 access grants auth
|
24
|
+
require 'aws-sdk-s3/access_grants_credentials'
|
25
|
+
require 'aws-sdk-s3/access_grants_credentials_provider'
|
26
|
+
|
24
27
|
# customizations to generated classes
|
25
28
|
require 'aws-sdk-s3/customizations/bucket'
|
26
29
|
require 'aws-sdk-s3/customizations/errors'
|
@@ -2,30 +2,53 @@
|
|
2
2
|
|
3
3
|
module Aws
|
4
4
|
module S3
|
5
|
+
# @api private
|
6
|
+
def self.express_credentials_cache
|
7
|
+
@express_credentials_cache ||= LRUCache.new(max_entries: 100)
|
8
|
+
end
|
9
|
+
|
5
10
|
# Returns Credentials class for S3 Express. Accepts CreateSession
|
6
11
|
# params as options. See {Client#create_session} for details.
|
7
12
|
class ExpressCredentialsProvider
|
8
13
|
# @param [Hash] options
|
9
|
-
# @option options [Client] :client The S3 client used to create the
|
14
|
+
# @option options [Client] :client The S3 client used to create the
|
15
|
+
# session.
|
10
16
|
# @option options [String] :session_mode (see: {Client#create_session})
|
17
|
+
# @option options [Boolean] :caching (true) When true, credentials will
|
18
|
+
# be cached.
|
11
19
|
# @option options [Callable] :before_refresh Proc called before
|
12
20
|
# credentials are refreshed.
|
13
21
|
def initialize(options = {})
|
14
22
|
@client = options.delete(:client)
|
23
|
+
@caching = options.delete(:caching) != false
|
15
24
|
@options = options
|
16
|
-
|
25
|
+
return unless @caching
|
26
|
+
|
27
|
+
@cache = Aws::S3.express_credentials_cache
|
17
28
|
end
|
18
29
|
|
19
30
|
def express_credentials_for(bucket)
|
20
|
-
@
|
31
|
+
if @caching
|
32
|
+
cached_credentials_for(bucket)
|
33
|
+
else
|
34
|
+
new_credentials_for(bucket)
|
35
|
+
end
|
21
36
|
end
|
22
37
|
|
23
38
|
attr_accessor :client
|
24
39
|
|
25
40
|
private
|
26
41
|
|
42
|
+
def cached_credentials_for(bucket)
|
43
|
+
if @cache.key?(bucket)
|
44
|
+
@cache[bucket]
|
45
|
+
else
|
46
|
+
@cache[bucket] = new_credentials_for(bucket)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
27
50
|
def new_credentials_for(bucket)
|
28
|
-
|
51
|
+
ExpressCredentials.new(
|
29
52
|
bucket: bucket,
|
30
53
|
client: @client,
|
31
54
|
**@options
|
@@ -138,9 +138,7 @@ module Aws
|
|
138
138
|
end
|
139
139
|
|
140
140
|
def source_metadata(options)
|
141
|
-
if options[:content_length]
|
142
|
-
return { content_length: options.delete(:content_length) }
|
143
|
-
end
|
141
|
+
return options.slice(:content_length) if options[:content_length]
|
144
142
|
|
145
143
|
client = options[:copy_source_client] || @client
|
146
144
|
|
@@ -150,11 +148,15 @@ module Aws
|
|
150
148
|
bucket, key = options[:copy_source].match(/([^\/]+?)\/(.+)/)[1,2]
|
151
149
|
end
|
152
150
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
151
|
+
head_opts = { bucket: bucket, key: CGI.unescape(key) }.tap { |opts|
|
152
|
+
opts[:version_id] = version_id if version_id
|
153
|
+
opts[:part_number] = options[:part_number] if options[:part_number]
|
154
|
+
}
|
155
|
+
|
156
|
+
client.head_object(head_opts).to_h.tap { |head|
|
157
|
+
head.delete(:server_side_encryption)
|
158
|
+
head.delete(:ssekms_key_id)
|
159
|
+
}
|
158
160
|
end
|
159
161
|
|
160
162
|
def default_part_size(source_size)
|
@@ -0,0 +1,108 @@
|
|
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
|
+
put_object: 'WRITE',
|
48
|
+
put_object_acl: 'WRITE',
|
49
|
+
delete_object: 'WRITE',
|
50
|
+
abort_multipart_upload: 'WRITE',
|
51
|
+
create_multipart_upload: 'WRITE',
|
52
|
+
upload_part: 'WRITE',
|
53
|
+
complete_multipart_upload: 'WRITE'
|
54
|
+
}.freeze
|
55
|
+
|
56
|
+
def call(context)
|
57
|
+
if access_grants_operation?(context) &&
|
58
|
+
!s3_express_endpoint?(context)
|
59
|
+
params = context[:endpoint_params]
|
60
|
+
permission = PERMISSION_MAP[context.operation_name]
|
61
|
+
|
62
|
+
provider = context.config.access_grants_credentials_provider
|
63
|
+
credentials = provider.access_grants_credentials_for(
|
64
|
+
bucket: params[:bucket],
|
65
|
+
key: params[:key],
|
66
|
+
prefix: params[:prefix],
|
67
|
+
permission: permission
|
68
|
+
)
|
69
|
+
context[:sigv4_credentials] = credentials # Sign will use this
|
70
|
+
end
|
71
|
+
|
72
|
+
@handler.call(context)
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def access_grants_operation?(context)
|
78
|
+
params = context[:endpoint_params]
|
79
|
+
params[:bucket] && PERMISSION_MAP[context.operation_name]
|
80
|
+
end
|
81
|
+
|
82
|
+
def s3_express_endpoint?(context)
|
83
|
+
context[:endpoint_properties]['backend'] == 'S3Express'
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def add_handlers(handlers, config)
|
88
|
+
return unless AccessGrants.s3control? && config.access_grants
|
89
|
+
|
90
|
+
handlers.add(Handler)
|
91
|
+
end
|
92
|
+
|
93
|
+
def after_initialize(client)
|
94
|
+
return unless AccessGrants.s3control? && client.config.access_grants
|
95
|
+
|
96
|
+
provider = client.config.access_grants_credentials_provider
|
97
|
+
provider.s3_client = client unless provider.s3_client
|
98
|
+
end
|
99
|
+
|
100
|
+
class << self
|
101
|
+
def s3control?
|
102
|
+
@s3control
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -31,7 +31,7 @@ for different buckets.
|
|
31
31
|
def call(context)
|
32
32
|
if (props = context[:endpoint_properties])
|
33
33
|
# S3 Express endpoint - turn off md5 and enable crc32 default
|
34
|
-
if
|
34
|
+
if props['backend'] == 'S3Express'
|
35
35
|
if context.operation_name == :put_object || checksum_required?(context)
|
36
36
|
context[:default_request_checksum_algorithm] = 'CRC32'
|
37
37
|
end
|
@@ -4,6 +4,11 @@ require 'aws-sigv4'
|
|
4
4
|
|
5
5
|
module Aws
|
6
6
|
module S3
|
7
|
+
# @api private
|
8
|
+
def self.bucket_region_cache
|
9
|
+
@bucket_region_cache ||= BucketRegionCache.new
|
10
|
+
end
|
11
|
+
|
7
12
|
module Plugins
|
8
13
|
# This plugin used to have a V4 signer but it was removed in favor of
|
9
14
|
# generic Sign plugin that uses endpoint auth scheme.
|
@@ -51,7 +56,7 @@ module Aws
|
|
51
56
|
private
|
52
57
|
|
53
58
|
def check_for_cached_region(context, bucket)
|
54
|
-
cached_region = S3
|
59
|
+
cached_region = Aws::S3.bucket_region_cache[bucket]
|
55
60
|
if cached_region &&
|
56
61
|
cached_region != context.config.region &&
|
57
62
|
!S3Signer.custom_endpoint?(context)
|
@@ -97,7 +102,7 @@ module Aws
|
|
97
102
|
end
|
98
103
|
|
99
104
|
def update_bucket_cache(context, actual_region)
|
100
|
-
S3
|
105
|
+
Aws::S3.bucket_region_cache[context.params[:bucket]] = actual_region
|
101
106
|
end
|
102
107
|
|
103
108
|
def fips_region?(resp)
|
data/lib/aws-sdk-s3.rb
CHANGED
data/sig/client.rbs
CHANGED
@@ -0,0 +1,19 @@
|
|
1
|
+
module Aws
|
2
|
+
module S3
|
3
|
+
class Bucket
|
4
|
+
# https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Bucket.html#clear!-instance_method
|
5
|
+
def clear!: () -> void
|
6
|
+
|
7
|
+
# https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Bucket.html#delete!-instance_method
|
8
|
+
def delete!: (?max_attempts: ::Integer, ?initial_wait: ::Float) -> void
|
9
|
+
| (?Hash[Symbol, untyped]) -> void
|
10
|
+
|
11
|
+
# https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Bucket.html#url-instance_method
|
12
|
+
def url: (?virtual_host: boolish, ?secure: boolish) -> String
|
13
|
+
| (?Hash[Symbol, untyped]) -> String
|
14
|
+
|
15
|
+
# https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Bucket.html#presigned_post-instance_method
|
16
|
+
def presigned_post: (Hash[Symbol, untyped]) -> untyped
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Aws
|
2
|
+
module S3
|
3
|
+
class Object
|
4
|
+
alias size content_length
|
5
|
+
|
6
|
+
# https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Object.html#copy_from-instance_method
|
7
|
+
def copy_from: (untyped source, ?Hash[Symbol, untyped] options) -> void
|
8
|
+
| ...
|
9
|
+
|
10
|
+
# https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Object.html#copy_to-instance_method
|
11
|
+
def copy_to: (untyped target, ?Hash[Symbol, untyped] options) -> void
|
12
|
+
|
13
|
+
# https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Object.html#move_to-instance_method
|
14
|
+
def move_to: (untyped target, ?Hash[Symbol, untyped] options) -> void
|
15
|
+
|
16
|
+
# https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Object.html#presigned_post-instance_method
|
17
|
+
def presigned_post: (?Hash[Symbol, untyped]) -> untyped
|
18
|
+
|
19
|
+
# https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Object.html#presigned_url-instance_method
|
20
|
+
def presigned_url: (Symbol | String method, ?Hash[Symbol, untyped] params) -> String
|
21
|
+
|
22
|
+
# https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Object.html#presigned_request-instance_method
|
23
|
+
def presigned_request: (Symbol | String method, ?Hash[Symbol, untyped] params) -> [String, Hash[String, String]]
|
24
|
+
|
25
|
+
# https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Object.html#public_url-instance_method
|
26
|
+
def public_url: (?Hash[Symbol, untyped] options) -> String
|
27
|
+
|
28
|
+
# https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Object.html#upload_stream-instance_method
|
29
|
+
def upload_stream: (?Hash[Symbol, untyped] options) { (IO write_stream) -> void } -> bool
|
30
|
+
|
31
|
+
# https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Object.html#upload_file-instance_method
|
32
|
+
def upload_file: (untyped source, ?Hash[Symbol, untyped] options) ?{ (untyped response) -> void } -> bool
|
33
|
+
|
34
|
+
# https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Object.html#download_file-instance_method
|
35
|
+
def download_file: (String destination, ?Hash[Symbol, untyped] options) -> bool
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Aws
|
2
|
+
module S3
|
3
|
+
class ObjectSummary
|
4
|
+
alias content_length size
|
5
|
+
|
6
|
+
# https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/ObjectSummary.html#copy_from-instance_method
|
7
|
+
def copy_from: (untyped source, ?Hash[Symbol, untyped] options) -> void
|
8
|
+
| ...
|
9
|
+
|
10
|
+
# https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/ObjectSummary.html#copy_to-instance_method
|
11
|
+
def copy_to: (untyped target, ?Hash[Symbol, untyped] options) -> void
|
12
|
+
|
13
|
+
# https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/ObjectSummary.html#move_to-instance_method
|
14
|
+
def move_to: (untyped target, ?Hash[Symbol, untyped] options) -> void
|
15
|
+
|
16
|
+
# https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/ObjectSummary.html#presigned_post-instance_method
|
17
|
+
def presigned_post: (Hash[Symbol, untyped]) -> untyped
|
18
|
+
|
19
|
+
# https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/ObjectSummary.html#presigned_url-instance_method
|
20
|
+
def presigned_url: (Symbol | String method, ?Hash[Symbol, untyped] params) -> String
|
21
|
+
|
22
|
+
# https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/ObjectSummary.html#public_url-instance_method
|
23
|
+
def public_url: (?Hash[Symbol, untyped] options) -> String
|
24
|
+
|
25
|
+
# https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/ObjectSummary.html#upload_file-instance_method
|
26
|
+
def upload_file: (untyped source, ?Hash[Symbol, untyped] options) ?{ (untyped response) -> void } -> bool
|
27
|
+
|
28
|
+
# https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/ObjectSummary.html#upload_stream-instance_method
|
29
|
+
def upload_stream: (?Hash[Symbol, untyped] options) { (IO write_stream) -> void } -> bool
|
30
|
+
|
31
|
+
# https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/ObjectSummary.html#download_file-instance_method
|
32
|
+
def download_file: (String destination, ?Hash[Symbol, untyped] options) -> bool
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/sig/resource.rbs
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aws-sdk-s3
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.151.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Amazon Web Services
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-05-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk-kms
|
@@ -47,7 +47,7 @@ dependencies:
|
|
47
47
|
version: '3'
|
48
48
|
- - ">="
|
49
49
|
- !ruby/object:Gem::Version
|
50
|
-
version: 3.
|
50
|
+
version: 3.194.0
|
51
51
|
type: :runtime
|
52
52
|
prerelease: false
|
53
53
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -57,7 +57,7 @@ dependencies:
|
|
57
57
|
version: '3'
|
58
58
|
- - ">="
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version: 3.
|
60
|
+
version: 3.194.0
|
61
61
|
description: Official AWS Ruby gem for Amazon Simple Storage Service (Amazon S3).
|
62
62
|
This gem is part of the AWS SDK for Ruby.
|
63
63
|
email:
|
@@ -70,6 +70,8 @@ files:
|
|
70
70
|
- LICENSE.txt
|
71
71
|
- VERSION
|
72
72
|
- lib/aws-sdk-s3.rb
|
73
|
+
- lib/aws-sdk-s3/access_grants_credentials.rb
|
74
|
+
- lib/aws-sdk-s3/access_grants_credentials_provider.rb
|
73
75
|
- lib/aws-sdk-s3/bucket.rb
|
74
76
|
- lib/aws-sdk-s3/bucket_acl.rb
|
75
77
|
- lib/aws-sdk-s3/bucket_cors.rb
|
@@ -127,7 +129,6 @@ files:
|
|
127
129
|
- lib/aws-sdk-s3/errors.rb
|
128
130
|
- lib/aws-sdk-s3/event_streams.rb
|
129
131
|
- lib/aws-sdk-s3/express_credentials.rb
|
130
|
-
- lib/aws-sdk-s3/express_credentials_cache.rb
|
131
132
|
- lib/aws-sdk-s3/express_credentials_provider.rb
|
132
133
|
- lib/aws-sdk-s3/file_downloader.rb
|
133
134
|
- lib/aws-sdk-s3/file_part.rb
|
@@ -145,6 +146,7 @@ files:
|
|
145
146
|
- lib/aws-sdk-s3/object_summary.rb
|
146
147
|
- lib/aws-sdk-s3/object_version.rb
|
147
148
|
- lib/aws-sdk-s3/plugins/accelerate.rb
|
149
|
+
- lib/aws-sdk-s3/plugins/access_grants.rb
|
148
150
|
- lib/aws-sdk-s3/plugins/arn.rb
|
149
151
|
- lib/aws-sdk-s3/plugins/bucket_dns.rb
|
150
152
|
- lib/aws-sdk-s3/plugins/bucket_name_restrictions.rb
|
@@ -182,6 +184,9 @@ files:
|
|
182
184
|
- sig/bucket_versioning.rbs
|
183
185
|
- sig/bucket_website.rbs
|
184
186
|
- sig/client.rbs
|
187
|
+
- sig/customizations/bucket.rbs
|
188
|
+
- sig/customizations/object.rbs
|
189
|
+
- sig/customizations/object_summary.rbs
|
185
190
|
- sig/errors.rbs
|
186
191
|
- sig/multipart_upload.rbs
|
187
192
|
- sig/multipart_upload_part.rbs
|
@@ -1,30 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Aws
|
4
|
-
module S3
|
5
|
-
# @api private
|
6
|
-
class ExpressCredentialsCache
|
7
|
-
def initialize
|
8
|
-
@credentials = {}
|
9
|
-
@mutex = Mutex.new
|
10
|
-
end
|
11
|
-
|
12
|
-
def [](bucket_name)
|
13
|
-
@mutex.synchronize { @credentials[bucket_name] }
|
14
|
-
end
|
15
|
-
|
16
|
-
def []=(bucket_name, credential_provider)
|
17
|
-
@mutex.synchronize do
|
18
|
-
@credentials[bucket_name] = credential_provider
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def clear
|
23
|
-
@mutex.synchronize { @credentials = {} }
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
# @api private
|
28
|
-
EXPRESS_CREDENTIALS_CACHE = ExpressCredentialsCache.new
|
29
|
-
end
|
30
|
-
end
|