google-cloud-storage 1.18.1 → 1.44.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/AUTHENTICATION.md +17 -30
- data/CHANGELOG.md +312 -0
- data/CONTRIBUTING.md +4 -5
- data/LOGGING.md +1 -1
- data/OVERVIEW.md +37 -5
- data/TROUBLESHOOTING.md +2 -8
- data/lib/google/cloud/storage/bucket/acl.rb +40 -40
- data/lib/google/cloud/storage/bucket/cors.rb +4 -1
- data/lib/google/cloud/storage/bucket/lifecycle.rb +259 -44
- data/lib/google/cloud/storage/bucket/list.rb +3 -3
- data/lib/google/cloud/storage/bucket.rb +1096 -172
- data/lib/google/cloud/storage/convert.rb +4 -3
- data/lib/google/cloud/storage/credentials.rb +16 -14
- data/lib/google/cloud/storage/errors.rb +7 -2
- data/lib/google/cloud/storage/file/acl.rb +181 -20
- data/lib/google/cloud/storage/file/list.rb +10 -8
- data/lib/google/cloud/storage/file/signer_v2.rb +36 -18
- data/lib/google/cloud/storage/file/signer_v4.rb +249 -61
- data/lib/google/cloud/storage/file/verifier.rb +2 -2
- data/lib/google/cloud/storage/file.rb +450 -84
- data/lib/google/cloud/storage/hmac_key/list.rb +182 -0
- data/lib/google/cloud/storage/hmac_key.rb +316 -0
- data/lib/google/cloud/storage/policy/binding.rb +246 -0
- data/lib/google/cloud/storage/policy/bindings.rb +196 -0
- data/lib/google/cloud/storage/policy/condition.rb +138 -0
- data/lib/google/cloud/storage/policy.rb +277 -24
- data/lib/google/cloud/storage/post_object.rb +20 -2
- data/lib/google/cloud/storage/project.rb +249 -50
- data/lib/google/cloud/storage/service.rb +479 -288
- data/lib/google/cloud/storage/version.rb +1 -1
- data/lib/google/cloud/storage.rb +86 -16
- data/lib/google-cloud-storage.rb +54 -7
- metadata +74 -27
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
require "google/cloud/storage/version"
|
|
17
17
|
require "google/apis/storage_v1"
|
|
18
18
|
require "digest"
|
|
19
|
-
require "
|
|
19
|
+
require "mini_mime"
|
|
20
20
|
require "pathname"
|
|
21
21
|
|
|
22
22
|
module Google
|
|
@@ -38,24 +38,37 @@ module Google
|
|
|
38
38
|
|
|
39
39
|
##
|
|
40
40
|
# Creates a new Service instance.
|
|
41
|
-
|
|
41
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
42
|
+
def initialize project, credentials, retries: nil,
|
|
43
|
+
timeout: nil, open_timeout: nil, read_timeout: nil,
|
|
44
|
+
send_timeout: nil, host: nil, quota_project: nil,
|
|
45
|
+
max_elapsed_time: nil, base_interval: nil, max_interval: nil,
|
|
46
|
+
multiplier: nil
|
|
42
47
|
@project = project
|
|
43
48
|
@credentials = credentials
|
|
44
49
|
@service = API::StorageService.new
|
|
45
50
|
@service.client_options.application_name = "gcloud-ruby"
|
|
46
51
|
@service.client_options.application_version = \
|
|
47
52
|
Google::Cloud::Storage::VERSION
|
|
48
|
-
@service.client_options.open_timeout_sec = timeout
|
|
49
|
-
@service.client_options.read_timeout_sec = timeout
|
|
50
|
-
@service.client_options.send_timeout_sec = timeout
|
|
53
|
+
@service.client_options.open_timeout_sec = (open_timeout || timeout)
|
|
54
|
+
@service.client_options.read_timeout_sec = (read_timeout || timeout)
|
|
55
|
+
@service.client_options.send_timeout_sec = (send_timeout || timeout)
|
|
51
56
|
@service.client_options.transparent_gzip_decompression = false
|
|
52
57
|
@service.request_options.retries = retries || 3
|
|
53
58
|
@service.request_options.header ||= {}
|
|
54
59
|
@service.request_options.header["x-goog-api-client"] = \
|
|
55
60
|
"gl-ruby/#{RUBY_VERSION} gccl/#{Google::Cloud::Storage::VERSION}"
|
|
56
61
|
@service.request_options.header["Accept-Encoding"] = "gzip"
|
|
62
|
+
@service.request_options.quota_project = quota_project if quota_project
|
|
63
|
+
@service.request_options.max_elapsed_time = max_elapsed_time if max_elapsed_time
|
|
64
|
+
@service.request_options.base_interval = base_interval if base_interval
|
|
65
|
+
@service.request_options.max_interval = max_interval if max_interval
|
|
66
|
+
@service.request_options.multiplier = multiplier if multiplier
|
|
67
|
+
@service.request_options.add_invocation_id_header = true
|
|
57
68
|
@service.authorization = @credentials.client if @credentials
|
|
69
|
+
@service.root_url = host if host
|
|
58
70
|
end
|
|
71
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
59
72
|
|
|
60
73
|
def service
|
|
61
74
|
return mocked_service if mocked_service
|
|
@@ -69,21 +82,28 @@ module Google
|
|
|
69
82
|
|
|
70
83
|
##
|
|
71
84
|
# Retrieves a list of buckets for the given project.
|
|
72
|
-
def list_buckets prefix: nil, token: nil, max: nil, user_project: nil
|
|
85
|
+
def list_buckets prefix: nil, token: nil, max: nil, user_project: nil, options: {}
|
|
73
86
|
execute do
|
|
74
87
|
service.list_buckets \
|
|
75
88
|
@project, prefix: prefix, page_token: token, max_results: max,
|
|
76
|
-
user_project: user_project(user_project)
|
|
89
|
+
user_project: user_project(user_project), options: options
|
|
77
90
|
end
|
|
78
91
|
end
|
|
79
92
|
|
|
80
93
|
##
|
|
81
94
|
# Retrieves bucket by name.
|
|
82
95
|
# Returns Google::Apis::StorageV1::Bucket.
|
|
83
|
-
def get_bucket bucket_name,
|
|
96
|
+
def get_bucket bucket_name,
|
|
97
|
+
if_metageneration_match: nil,
|
|
98
|
+
if_metageneration_not_match: nil,
|
|
99
|
+
user_project: nil,
|
|
100
|
+
options: {}
|
|
84
101
|
execute do
|
|
85
102
|
service.get_bucket bucket_name,
|
|
86
|
-
|
|
103
|
+
if_metageneration_match: if_metageneration_match,
|
|
104
|
+
if_metageneration_not_match: if_metageneration_not_match,
|
|
105
|
+
user_project: user_project(user_project),
|
|
106
|
+
options: options
|
|
87
107
|
end
|
|
88
108
|
end
|
|
89
109
|
|
|
@@ -91,148 +111,191 @@ module Google
|
|
|
91
111
|
# Creates a new bucket.
|
|
92
112
|
# Returns Google::Apis::StorageV1::Bucket.
|
|
93
113
|
def insert_bucket bucket_gapi, acl: nil, default_acl: nil,
|
|
94
|
-
user_project: nil
|
|
114
|
+
user_project: nil, options: {}
|
|
95
115
|
execute do
|
|
96
116
|
service.insert_bucket \
|
|
97
117
|
@project, bucket_gapi,
|
|
98
118
|
predefined_acl: acl,
|
|
99
119
|
predefined_default_object_acl: default_acl,
|
|
100
|
-
user_project: user_project(user_project)
|
|
120
|
+
user_project: user_project(user_project),
|
|
121
|
+
options: options
|
|
101
122
|
end
|
|
102
123
|
end
|
|
103
124
|
|
|
104
125
|
##
|
|
105
126
|
# Updates a bucket, including its ACL metadata.
|
|
106
|
-
def patch_bucket bucket_name,
|
|
107
|
-
|
|
127
|
+
def patch_bucket bucket_name,
|
|
128
|
+
bucket_gapi = nil,
|
|
129
|
+
predefined_acl: nil,
|
|
130
|
+
predefined_default_acl: nil,
|
|
131
|
+
if_metageneration_match: nil,
|
|
132
|
+
if_metageneration_not_match: nil,
|
|
133
|
+
user_project: nil,
|
|
134
|
+
options: {}
|
|
108
135
|
bucket_gapi ||= Google::Apis::StorageV1::Bucket.new
|
|
109
136
|
bucket_gapi.acl = [] if predefined_acl
|
|
110
137
|
bucket_gapi.default_object_acl = [] if predefined_default_acl
|
|
111
138
|
|
|
139
|
+
if options[:retries].nil?
|
|
140
|
+
is_idempotent = retry? if_metageneration_match: if_metageneration_match
|
|
141
|
+
options = is_idempotent ? {} : { retries: 0 }
|
|
142
|
+
end
|
|
143
|
+
|
|
112
144
|
execute do
|
|
113
|
-
service.patch_bucket
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
145
|
+
service.patch_bucket bucket_name,
|
|
146
|
+
bucket_gapi,
|
|
147
|
+
predefined_acl: predefined_acl,
|
|
148
|
+
predefined_default_object_acl: predefined_default_acl,
|
|
149
|
+
if_metageneration_match: if_metageneration_match,
|
|
150
|
+
if_metageneration_not_match: if_metageneration_not_match,
|
|
151
|
+
user_project: user_project(user_project),
|
|
152
|
+
options: options
|
|
118
153
|
end
|
|
119
154
|
end
|
|
120
155
|
|
|
121
156
|
##
|
|
122
157
|
# Permanently deletes an empty bucket.
|
|
123
|
-
def delete_bucket bucket_name,
|
|
158
|
+
def delete_bucket bucket_name,
|
|
159
|
+
if_metageneration_match: nil,
|
|
160
|
+
if_metageneration_not_match: nil,
|
|
161
|
+
user_project: nil,
|
|
162
|
+
options: {}
|
|
124
163
|
execute do
|
|
125
164
|
service.delete_bucket bucket_name,
|
|
126
|
-
|
|
165
|
+
if_metageneration_match: if_metageneration_match,
|
|
166
|
+
if_metageneration_not_match: if_metageneration_not_match,
|
|
167
|
+
user_project: user_project(user_project),
|
|
168
|
+
options: options
|
|
127
169
|
end
|
|
128
170
|
end
|
|
129
171
|
|
|
130
172
|
##
|
|
131
173
|
# Locks retention policy on a bucket.
|
|
132
174
|
def lock_bucket_retention_policy bucket_name, metageneration,
|
|
133
|
-
user_project: nil
|
|
175
|
+
user_project: nil,
|
|
176
|
+
options: {}
|
|
134
177
|
execute do
|
|
135
178
|
service.lock_bucket_retention_policy \
|
|
136
179
|
bucket_name, metageneration,
|
|
137
|
-
user_project: user_project(user_project)
|
|
180
|
+
user_project: user_project(user_project),
|
|
181
|
+
options: options
|
|
138
182
|
end
|
|
139
183
|
end
|
|
140
184
|
|
|
141
185
|
##
|
|
142
186
|
# Retrieves a list of ACLs for the given bucket.
|
|
143
|
-
def list_bucket_acls bucket_name, user_project: nil
|
|
187
|
+
def list_bucket_acls bucket_name, user_project: nil, options: {}
|
|
144
188
|
execute do
|
|
145
189
|
service.list_bucket_access_controls \
|
|
146
|
-
bucket_name, user_project: user_project(user_project)
|
|
190
|
+
bucket_name, user_project: user_project(user_project),
|
|
191
|
+
options: options
|
|
147
192
|
end
|
|
148
193
|
end
|
|
149
194
|
|
|
150
195
|
##
|
|
151
196
|
# Creates a new bucket ACL.
|
|
152
|
-
def insert_bucket_acl bucket_name, entity, role, user_project: nil
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
197
|
+
def insert_bucket_acl bucket_name, entity, role, user_project: nil, options: {}
|
|
198
|
+
params = { entity: entity, role: role }.delete_if { |_k, v| v.nil? }
|
|
199
|
+
new_acl = Google::Apis::StorageV1::BucketAccessControl.new(**params)
|
|
200
|
+
if options[:retries].nil?
|
|
201
|
+
options = options.merge({ retries: 0 })
|
|
202
|
+
end
|
|
156
203
|
execute do
|
|
157
204
|
service.insert_bucket_access_control \
|
|
158
|
-
bucket_name, new_acl, user_project: user_project(user_project)
|
|
205
|
+
bucket_name, new_acl, user_project: user_project(user_project),
|
|
206
|
+
options: options
|
|
159
207
|
end
|
|
160
208
|
end
|
|
161
209
|
|
|
162
210
|
##
|
|
163
211
|
# Permanently deletes a bucket ACL.
|
|
164
|
-
def delete_bucket_acl bucket_name, entity, user_project: nil
|
|
212
|
+
def delete_bucket_acl bucket_name, entity, user_project: nil, options: {}
|
|
213
|
+
if options[:retries].nil?
|
|
214
|
+
options = options.merge({ retries: 0 })
|
|
215
|
+
end
|
|
165
216
|
execute do
|
|
166
217
|
service.delete_bucket_access_control \
|
|
167
|
-
bucket_name, entity, user_project: user_project(user_project)
|
|
218
|
+
bucket_name, entity, user_project: user_project(user_project),
|
|
219
|
+
options: options
|
|
168
220
|
end
|
|
169
221
|
end
|
|
170
222
|
|
|
171
223
|
##
|
|
172
224
|
# Retrieves a list of default ACLs for the given bucket.
|
|
173
|
-
def list_default_acls bucket_name, user_project: nil
|
|
225
|
+
def list_default_acls bucket_name, user_project: nil, options: {}
|
|
174
226
|
execute do
|
|
175
227
|
service.list_default_object_access_controls \
|
|
176
|
-
bucket_name, user_project: user_project(user_project)
|
|
228
|
+
bucket_name, user_project: user_project(user_project),
|
|
229
|
+
options: options
|
|
177
230
|
end
|
|
178
231
|
end
|
|
179
232
|
|
|
180
233
|
##
|
|
181
234
|
# Creates a new default ACL.
|
|
182
|
-
def insert_default_acl bucket_name, entity, role, user_project: nil
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
235
|
+
def insert_default_acl bucket_name, entity, role, user_project: nil, options: {}
|
|
236
|
+
if options[:retries].nil?
|
|
237
|
+
options = options.merge({ retries: 0 })
|
|
238
|
+
end
|
|
239
|
+
param = { entity: entity, role: role }.delete_if { |_k, v| v.nil? }
|
|
240
|
+
new_acl = Google::Apis::StorageV1::ObjectAccessControl.new(**param)
|
|
186
241
|
execute do
|
|
187
242
|
service.insert_default_object_access_control \
|
|
188
|
-
bucket_name, new_acl, user_project: user_project(user_project)
|
|
243
|
+
bucket_name, new_acl, user_project: user_project(user_project),
|
|
244
|
+
options: options
|
|
189
245
|
end
|
|
190
246
|
end
|
|
191
247
|
|
|
192
248
|
##
|
|
193
249
|
# Permanently deletes a default ACL.
|
|
194
|
-
def delete_default_acl bucket_name, entity, user_project: nil
|
|
250
|
+
def delete_default_acl bucket_name, entity, user_project: nil, options: {}
|
|
251
|
+
if options[:retries].nil?
|
|
252
|
+
options = options.merge({ retries: 0 })
|
|
253
|
+
end
|
|
195
254
|
execute do
|
|
196
255
|
service.delete_default_object_access_control \
|
|
197
|
-
bucket_name, entity, user_project: user_project(user_project)
|
|
256
|
+
bucket_name, entity, user_project: user_project(user_project),
|
|
257
|
+
options: options
|
|
198
258
|
end
|
|
199
259
|
end
|
|
200
260
|
|
|
201
261
|
##
|
|
202
262
|
# Returns Google::Apis::StorageV1::Policy
|
|
203
|
-
def get_bucket_policy bucket_name, user_project: nil
|
|
263
|
+
def get_bucket_policy bucket_name, requested_policy_version: nil, user_project: nil,
|
|
264
|
+
options: {}
|
|
204
265
|
# get_bucket_iam_policy(bucket, fields: nil, quota_user: nil,
|
|
205
266
|
# user_ip: nil, options: nil)
|
|
206
267
|
execute do
|
|
207
|
-
service.get_bucket_iam_policy
|
|
208
|
-
|
|
268
|
+
service.get_bucket_iam_policy bucket_name, options_requested_policy_version: requested_policy_version,
|
|
269
|
+
user_project: user_project(user_project), options: options
|
|
209
270
|
end
|
|
210
271
|
end
|
|
211
272
|
|
|
212
273
|
##
|
|
213
274
|
# Returns Google::Apis::StorageV1::Policy
|
|
214
|
-
def set_bucket_policy bucket_name, new_policy, user_project: nil
|
|
275
|
+
def set_bucket_policy bucket_name, new_policy, user_project: nil, options: {}
|
|
215
276
|
execute do
|
|
216
277
|
service.set_bucket_iam_policy \
|
|
217
|
-
bucket_name, new_policy, user_project: user_project(user_project)
|
|
278
|
+
bucket_name, new_policy, user_project: user_project(user_project), options: options
|
|
218
279
|
end
|
|
219
280
|
end
|
|
220
281
|
|
|
221
282
|
##
|
|
222
283
|
# Returns Google::Apis::StorageV1::TestIamPermissionsResponse
|
|
223
|
-
def test_bucket_permissions bucket_name, permissions, user_project: nil
|
|
284
|
+
def test_bucket_permissions bucket_name, permissions, user_project: nil, options: {}
|
|
224
285
|
execute do
|
|
225
286
|
service.test_bucket_iam_permissions \
|
|
226
|
-
bucket_name, permissions, user_project: user_project(user_project)
|
|
287
|
+
bucket_name, permissions, user_project: user_project(user_project),
|
|
288
|
+
options: options
|
|
227
289
|
end
|
|
228
290
|
end
|
|
229
291
|
|
|
230
292
|
##
|
|
231
293
|
# Retrieves a list of Pub/Sub notification subscriptions for a bucket.
|
|
232
|
-
def list_notifications bucket_name, user_project: nil
|
|
294
|
+
def list_notifications bucket_name, user_project: nil, options: {}
|
|
233
295
|
execute do
|
|
234
296
|
service.list_notifications bucket_name,
|
|
235
|
-
user_project: user_project(user_project)
|
|
297
|
+
user_project: user_project(user_project),
|
|
298
|
+
options: options
|
|
236
299
|
end
|
|
237
300
|
end
|
|
238
301
|
|
|
@@ -240,133 +303,244 @@ module Google
|
|
|
240
303
|
# Creates a new Pub/Sub notification subscription for a bucket.
|
|
241
304
|
def insert_notification bucket_name, topic_name, custom_attrs: nil,
|
|
242
305
|
event_types: nil, prefix: nil, payload: nil,
|
|
243
|
-
user_project: nil
|
|
244
|
-
|
|
306
|
+
user_project: nil, options: {}
|
|
307
|
+
params =
|
|
245
308
|
{ custom_attributes: custom_attrs,
|
|
246
309
|
event_types: event_types(event_types),
|
|
247
310
|
object_name_prefix: prefix,
|
|
248
311
|
payload_format: payload_format(payload),
|
|
249
312
|
topic: topic_path(topic_name) }.delete_if { |_k, v| v.nil? }
|
|
250
|
-
)
|
|
313
|
+
new_notification = Google::Apis::StorageV1::Notification.new(**params)
|
|
314
|
+
|
|
315
|
+
if options[:retries].nil?
|
|
316
|
+
options = options.merge({ retries: 0 })
|
|
317
|
+
end
|
|
251
318
|
|
|
252
319
|
execute do
|
|
253
320
|
service.insert_notification \
|
|
254
321
|
bucket_name, new_notification,
|
|
255
|
-
user_project: user_project(user_project)
|
|
322
|
+
user_project: user_project(user_project),
|
|
323
|
+
options: options
|
|
256
324
|
end
|
|
257
325
|
end
|
|
258
326
|
|
|
259
327
|
##
|
|
260
328
|
# Retrieves a Pub/Sub notification subscription for a bucket.
|
|
261
|
-
def get_notification bucket_name, notification_id, user_project: nil
|
|
329
|
+
def get_notification bucket_name, notification_id, user_project: nil, options: {}
|
|
262
330
|
execute do
|
|
263
331
|
service.get_notification bucket_name, notification_id,
|
|
264
|
-
user_project: user_project(user_project)
|
|
332
|
+
user_project: user_project(user_project),
|
|
333
|
+
options: options
|
|
265
334
|
end
|
|
266
335
|
end
|
|
267
336
|
|
|
268
337
|
##
|
|
269
338
|
# Deletes a new Pub/Sub notification subscription for a bucket.
|
|
270
|
-
def delete_notification bucket_name, notification_id, user_project: nil
|
|
339
|
+
def delete_notification bucket_name, notification_id, user_project: nil, options: {}
|
|
271
340
|
execute do
|
|
272
341
|
service.delete_notification bucket_name, notification_id,
|
|
273
|
-
user_project: user_project(user_project)
|
|
342
|
+
user_project: user_project(user_project),
|
|
343
|
+
options: options
|
|
274
344
|
end
|
|
275
345
|
end
|
|
276
346
|
|
|
277
347
|
##
|
|
278
348
|
# Retrieves a list of files matching the criteria.
|
|
279
349
|
def list_files bucket_name, delimiter: nil, max: nil, token: nil,
|
|
280
|
-
prefix: nil, versions: nil, user_project: nil
|
|
350
|
+
prefix: nil, versions: nil, user_project: nil,
|
|
351
|
+
options: {}
|
|
281
352
|
execute do
|
|
282
353
|
service.list_objects \
|
|
283
354
|
bucket_name, delimiter: delimiter, max_results: max,
|
|
284
355
|
page_token: token, prefix: prefix,
|
|
285
356
|
versions: versions,
|
|
286
|
-
user_project: user_project(user_project)
|
|
357
|
+
user_project: user_project(user_project),
|
|
358
|
+
options: options
|
|
287
359
|
end
|
|
288
360
|
end
|
|
289
361
|
|
|
290
362
|
##
|
|
291
363
|
# Inserts a new file for the given bucket
|
|
292
|
-
def insert_file bucket_name,
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
364
|
+
def insert_file bucket_name,
|
|
365
|
+
source,
|
|
366
|
+
path = nil,
|
|
367
|
+
acl: nil,
|
|
368
|
+
cache_control: nil,
|
|
369
|
+
content_disposition: nil,
|
|
370
|
+
content_encoding: nil,
|
|
371
|
+
content_language: nil,
|
|
372
|
+
content_type: nil,
|
|
373
|
+
custom_time: nil,
|
|
374
|
+
crc32c: nil,
|
|
375
|
+
md5: nil,
|
|
376
|
+
metadata: nil,
|
|
377
|
+
storage_class: nil,
|
|
378
|
+
key: nil,
|
|
379
|
+
kms_key: nil,
|
|
380
|
+
temporary_hold: nil,
|
|
381
|
+
event_based_hold: nil,
|
|
382
|
+
if_generation_match: nil,
|
|
383
|
+
if_generation_not_match: nil,
|
|
384
|
+
if_metageneration_match: nil,
|
|
385
|
+
if_metageneration_not_match: nil,
|
|
386
|
+
user_project: nil,
|
|
387
|
+
options: {}
|
|
388
|
+
params = {
|
|
389
|
+
cache_control: cache_control,
|
|
390
|
+
content_type: content_type,
|
|
391
|
+
custom_time: custom_time,
|
|
392
|
+
content_disposition: content_disposition,
|
|
393
|
+
md5_hash: md5,
|
|
394
|
+
content_encoding: content_encoding,
|
|
395
|
+
crc32c: crc32c,
|
|
396
|
+
content_language: content_language,
|
|
397
|
+
metadata: metadata,
|
|
398
|
+
storage_class: storage_class,
|
|
399
|
+
temporary_hold: temporary_hold,
|
|
400
|
+
event_based_hold: event_based_hold
|
|
401
|
+
}.delete_if { |_k, v| v.nil? }
|
|
402
|
+
file_obj = Google::Apis::StorageV1::Object.new(**params)
|
|
307
403
|
content_type ||= mime_type_for(path || Pathname(source).to_path)
|
|
308
404
|
|
|
405
|
+
if options[:retries].nil?
|
|
406
|
+
is_idempotent = retry? if_generation_match: if_generation_match
|
|
407
|
+
options = is_idempotent ? key_options(key) : key_options(key).merge(retries: 0)
|
|
408
|
+
else
|
|
409
|
+
options = key_options(key).merge options
|
|
410
|
+
end
|
|
411
|
+
|
|
309
412
|
execute do
|
|
310
|
-
service.insert_object
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
413
|
+
service.insert_object bucket_name,
|
|
414
|
+
file_obj,
|
|
415
|
+
name: path,
|
|
416
|
+
predefined_acl: acl,
|
|
417
|
+
upload_source: source,
|
|
418
|
+
content_encoding: content_encoding,
|
|
419
|
+
content_type: content_type,
|
|
420
|
+
if_generation_match: if_generation_match,
|
|
421
|
+
if_generation_not_match: if_generation_not_match,
|
|
422
|
+
if_metageneration_match: if_metageneration_match,
|
|
423
|
+
if_metageneration_not_match: if_metageneration_not_match,
|
|
424
|
+
kms_key_name: kms_key,
|
|
425
|
+
user_project: user_project(user_project),
|
|
426
|
+
options: options
|
|
316
427
|
end
|
|
317
428
|
end
|
|
318
429
|
|
|
319
430
|
##
|
|
320
431
|
# Retrieves an object or its metadata.
|
|
321
|
-
def get_file bucket_name,
|
|
322
|
-
|
|
432
|
+
def get_file bucket_name,
|
|
433
|
+
file_path,
|
|
434
|
+
generation: nil,
|
|
435
|
+
if_generation_match: nil,
|
|
436
|
+
if_generation_not_match: nil,
|
|
437
|
+
if_metageneration_match: nil,
|
|
438
|
+
if_metageneration_not_match: nil,
|
|
439
|
+
key: nil,
|
|
440
|
+
user_project: nil,
|
|
441
|
+
options: {}
|
|
323
442
|
execute do
|
|
324
443
|
service.get_object \
|
|
325
444
|
bucket_name, file_path,
|
|
326
445
|
generation: generation,
|
|
446
|
+
if_generation_match: if_generation_match,
|
|
447
|
+
if_generation_not_match: if_generation_not_match,
|
|
448
|
+
if_metageneration_match: if_metageneration_match,
|
|
449
|
+
if_metageneration_not_match: if_metageneration_not_match,
|
|
327
450
|
user_project: user_project(user_project),
|
|
328
|
-
options: key_options(key)
|
|
451
|
+
options: key_options(key).merge(options)
|
|
329
452
|
end
|
|
330
453
|
end
|
|
331
454
|
|
|
332
455
|
## Rewrite a file from source bucket/object to a
|
|
333
456
|
# destination bucket/object.
|
|
334
|
-
def rewrite_file source_bucket_name,
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
457
|
+
def rewrite_file source_bucket_name,
|
|
458
|
+
source_file_path,
|
|
459
|
+
destination_bucket_name,
|
|
460
|
+
destination_file_path,
|
|
461
|
+
file_gapi = nil,
|
|
462
|
+
source_key: nil,
|
|
463
|
+
destination_key: nil,
|
|
464
|
+
destination_kms_key: nil,
|
|
465
|
+
acl: nil,
|
|
466
|
+
generation: nil,
|
|
467
|
+
if_generation_match: nil,
|
|
468
|
+
if_generation_not_match: nil,
|
|
469
|
+
if_metageneration_match: nil,
|
|
470
|
+
if_metageneration_not_match: nil,
|
|
471
|
+
if_source_generation_match: nil,
|
|
472
|
+
if_source_generation_not_match: nil,
|
|
473
|
+
if_source_metageneration_match: nil,
|
|
474
|
+
if_source_metageneration_not_match: nil,
|
|
475
|
+
token: nil,
|
|
476
|
+
user_project: nil,
|
|
477
|
+
options: {}
|
|
339
478
|
key_options = rewrite_key_options source_key, destination_key
|
|
479
|
+
|
|
480
|
+
if options[:retries].nil?
|
|
481
|
+
is_idempotent = retry? if_generation_match: if_generation_match
|
|
482
|
+
options = is_idempotent ? key_options : key_options.merge(retries: 0)
|
|
483
|
+
else
|
|
484
|
+
options = key_options.merge options
|
|
485
|
+
end
|
|
486
|
+
|
|
340
487
|
execute do
|
|
341
|
-
service.rewrite_object
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
488
|
+
service.rewrite_object source_bucket_name,
|
|
489
|
+
source_file_path,
|
|
490
|
+
destination_bucket_name,
|
|
491
|
+
destination_file_path,
|
|
492
|
+
file_gapi,
|
|
493
|
+
destination_kms_key_name: destination_kms_key,
|
|
494
|
+
destination_predefined_acl: acl,
|
|
495
|
+
source_generation: generation,
|
|
496
|
+
if_generation_match: if_generation_match,
|
|
497
|
+
if_generation_not_match: if_generation_not_match,
|
|
498
|
+
if_metageneration_match: if_metageneration_match,
|
|
499
|
+
if_metageneration_not_match: if_metageneration_not_match,
|
|
500
|
+
if_source_generation_match: if_source_generation_match,
|
|
501
|
+
if_source_generation_not_match: if_source_generation_not_match,
|
|
502
|
+
if_source_metageneration_match: if_source_metageneration_match,
|
|
503
|
+
if_source_metageneration_not_match: if_source_metageneration_not_match,
|
|
504
|
+
rewrite_token: token,
|
|
505
|
+
user_project: user_project(user_project),
|
|
506
|
+
options: options
|
|
351
507
|
end
|
|
352
508
|
end
|
|
353
509
|
|
|
354
510
|
## Copy a file from source bucket/object to a
|
|
355
511
|
# destination bucket/object.
|
|
356
|
-
def compose_file bucket_name,
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
512
|
+
def compose_file bucket_name,
|
|
513
|
+
source_files,
|
|
514
|
+
destination_path,
|
|
515
|
+
destination_gapi,
|
|
516
|
+
acl: nil,
|
|
517
|
+
key: nil,
|
|
518
|
+
if_source_generation_match: nil,
|
|
519
|
+
if_generation_match: nil,
|
|
520
|
+
if_metageneration_match: nil,
|
|
521
|
+
user_project: nil,
|
|
522
|
+
options: {}
|
|
523
|
+
|
|
524
|
+
source_objects = compose_file_source_objects source_files, if_source_generation_match
|
|
525
|
+
compose_req = Google::Apis::StorageV1::ComposeRequest.new source_objects: source_objects,
|
|
526
|
+
destination: destination_gapi
|
|
527
|
+
|
|
528
|
+
if options[:retries].nil?
|
|
529
|
+
is_idempotent = retry? if_generation_match: if_generation_match
|
|
530
|
+
options = is_idempotent ? key_options(key) : key_options(key).merge(retries: 0)
|
|
531
|
+
else
|
|
532
|
+
options = key_options.merge options
|
|
533
|
+
end
|
|
362
534
|
|
|
363
535
|
execute do
|
|
364
|
-
service.compose_object
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
536
|
+
service.compose_object bucket_name,
|
|
537
|
+
destination_path,
|
|
538
|
+
compose_req,
|
|
539
|
+
destination_predefined_acl: acl,
|
|
540
|
+
if_generation_match: if_generation_match,
|
|
541
|
+
if_metageneration_match: if_metageneration_match,
|
|
542
|
+
user_project: user_project(user_project),
|
|
543
|
+
options: options
|
|
370
544
|
end
|
|
371
545
|
end
|
|
372
546
|
|
|
@@ -380,12 +554,12 @@ module Google
|
|
|
380
554
|
# Apis::StorageV1::StorageService and Apis::Core::DownloadCommand at
|
|
381
555
|
# the end of this file.
|
|
382
556
|
def download_file bucket_name, file_path, target_path, generation: nil,
|
|
383
|
-
key: nil, range: nil, user_project: nil
|
|
384
|
-
options = key_options
|
|
557
|
+
key: nil, range: nil, user_project: nil, options: {}
|
|
558
|
+
options = key_options(key).merge(options)
|
|
385
559
|
options = range_header options, range
|
|
386
560
|
|
|
387
561
|
execute do
|
|
388
|
-
service.
|
|
562
|
+
service.get_object \
|
|
389
563
|
bucket_name, file_path,
|
|
390
564
|
download_dest: target_path, generation: generation,
|
|
391
565
|
user_project: user_project(user_project),
|
|
@@ -395,59 +569,214 @@ module Google
|
|
|
395
569
|
|
|
396
570
|
##
|
|
397
571
|
# Updates a file's metadata.
|
|
398
|
-
def patch_file bucket_name,
|
|
399
|
-
|
|
572
|
+
def patch_file bucket_name,
|
|
573
|
+
file_path,
|
|
574
|
+
file_gapi = nil,
|
|
575
|
+
generation: nil,
|
|
576
|
+
if_generation_match: nil,
|
|
577
|
+
if_generation_not_match: nil,
|
|
578
|
+
if_metageneration_match: nil,
|
|
579
|
+
if_metageneration_not_match: nil,
|
|
580
|
+
predefined_acl: nil,
|
|
581
|
+
user_project: nil,
|
|
582
|
+
options: {}
|
|
400
583
|
file_gapi ||= Google::Apis::StorageV1::Object.new
|
|
584
|
+
|
|
585
|
+
if options[:retries].nil?
|
|
586
|
+
is_idempotent = retry? if_metageneration_match: if_metageneration_match
|
|
587
|
+
options = is_idempotent ? {} : { retries: 0 }
|
|
588
|
+
end
|
|
589
|
+
|
|
401
590
|
execute do
|
|
402
|
-
service.patch_object
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
591
|
+
service.patch_object bucket_name,
|
|
592
|
+
file_path,
|
|
593
|
+
file_gapi,
|
|
594
|
+
generation: generation,
|
|
595
|
+
if_generation_match: if_generation_match,
|
|
596
|
+
if_generation_not_match: if_generation_not_match,
|
|
597
|
+
if_metageneration_match: if_metageneration_match,
|
|
598
|
+
if_metageneration_not_match: if_metageneration_not_match,
|
|
599
|
+
predefined_acl: predefined_acl,
|
|
600
|
+
user_project: user_project(user_project),
|
|
601
|
+
options: options
|
|
406
602
|
end
|
|
407
603
|
end
|
|
408
604
|
|
|
409
605
|
##
|
|
410
606
|
# Permanently deletes a file.
|
|
411
|
-
def delete_file bucket_name,
|
|
412
|
-
|
|
607
|
+
def delete_file bucket_name,
|
|
608
|
+
file_path,
|
|
609
|
+
generation: nil,
|
|
610
|
+
if_generation_match: nil,
|
|
611
|
+
if_generation_not_match: nil,
|
|
612
|
+
if_metageneration_match: nil,
|
|
613
|
+
if_metageneration_not_match: nil,
|
|
614
|
+
user_project: nil,
|
|
615
|
+
options: {}
|
|
616
|
+
|
|
617
|
+
if options[:retries].nil?
|
|
618
|
+
is_idempotent = retry? generation: generation, if_generation_match: if_generation_match
|
|
619
|
+
options = is_idempotent ? {} : { retries: 0 }
|
|
620
|
+
end
|
|
621
|
+
|
|
413
622
|
execute do
|
|
414
623
|
service.delete_object bucket_name, file_path,
|
|
415
624
|
generation: generation,
|
|
416
|
-
|
|
625
|
+
if_generation_match: if_generation_match,
|
|
626
|
+
if_generation_not_match: if_generation_not_match,
|
|
627
|
+
if_metageneration_match: if_metageneration_match,
|
|
628
|
+
if_metageneration_not_match: if_metageneration_not_match,
|
|
629
|
+
user_project: user_project(user_project),
|
|
630
|
+
options: options
|
|
417
631
|
end
|
|
418
632
|
end
|
|
419
633
|
|
|
420
634
|
##
|
|
421
635
|
# Retrieves a list of ACLs for the given file.
|
|
422
|
-
def list_file_acls bucket_name, file_name, user_project: nil
|
|
636
|
+
def list_file_acls bucket_name, file_name, user_project: nil, options: {}
|
|
423
637
|
execute do
|
|
424
638
|
service.list_object_access_controls \
|
|
425
|
-
bucket_name, file_name, user_project: user_project(user_project)
|
|
639
|
+
bucket_name, file_name, user_project: user_project(user_project),
|
|
640
|
+
options: options
|
|
426
641
|
end
|
|
427
642
|
end
|
|
428
643
|
|
|
429
644
|
##
|
|
430
645
|
# Creates a new file ACL.
|
|
431
646
|
def insert_file_acl bucket_name, file_name, entity, role,
|
|
432
|
-
generation: nil, user_project: nil
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
647
|
+
generation: nil, user_project: nil,
|
|
648
|
+
options: {}
|
|
649
|
+
if options[:retries].nil?
|
|
650
|
+
options = options.merge({ retries: 0 })
|
|
651
|
+
end
|
|
652
|
+
params = { entity: entity, role: role }.delete_if { |_k, v| v.nil? }
|
|
653
|
+
new_acl = Google::Apis::StorageV1::ObjectAccessControl.new(**params)
|
|
436
654
|
execute do
|
|
437
655
|
service.insert_object_access_control \
|
|
438
656
|
bucket_name, file_name, new_acl,
|
|
439
|
-
generation: generation, user_project: user_project(user_project)
|
|
657
|
+
generation: generation, user_project: user_project(user_project),
|
|
658
|
+
options: options
|
|
440
659
|
end
|
|
441
660
|
end
|
|
442
661
|
|
|
443
662
|
##
|
|
444
663
|
# Permanently deletes a file ACL.
|
|
445
664
|
def delete_file_acl bucket_name, file_name, entity, generation: nil,
|
|
446
|
-
user_project: nil
|
|
665
|
+
user_project: nil, options: {}
|
|
666
|
+
if options[:retries].nil?
|
|
667
|
+
options = options.merge({ retries: 0 })
|
|
668
|
+
end
|
|
447
669
|
execute do
|
|
448
670
|
service.delete_object_access_control \
|
|
449
671
|
bucket_name, file_name, entity,
|
|
450
|
-
generation: generation, user_project: user_project(user_project)
|
|
672
|
+
generation: generation, user_project: user_project(user_project),
|
|
673
|
+
options: options
|
|
674
|
+
end
|
|
675
|
+
end
|
|
676
|
+
|
|
677
|
+
##
|
|
678
|
+
# Creates a new HMAC key for the specified service account.
|
|
679
|
+
# Returns Google::Apis::StorageV1::HmacKey.
|
|
680
|
+
def create_hmac_key service_account_email, project_id: nil,
|
|
681
|
+
user_project: nil, options: {}
|
|
682
|
+
|
|
683
|
+
if options[:retries].nil?
|
|
684
|
+
options = options.merge({ retries: 0 })
|
|
685
|
+
end
|
|
686
|
+
|
|
687
|
+
execute do
|
|
688
|
+
service.create_project_hmac_key \
|
|
689
|
+
(project_id || @project), service_account_email,
|
|
690
|
+
user_project: user_project(user_project),
|
|
691
|
+
options: options
|
|
692
|
+
end
|
|
693
|
+
end
|
|
694
|
+
|
|
695
|
+
##
|
|
696
|
+
# Deletes an HMAC key. Key must be in the INACTIVE state.
|
|
697
|
+
def delete_hmac_key access_id, project_id: nil, user_project: nil,
|
|
698
|
+
options: {}
|
|
699
|
+
execute do
|
|
700
|
+
service.delete_project_hmac_key \
|
|
701
|
+
(project_id || @project), access_id,
|
|
702
|
+
user_project: user_project(user_project),
|
|
703
|
+
options: options
|
|
704
|
+
end
|
|
705
|
+
end
|
|
706
|
+
|
|
707
|
+
##
|
|
708
|
+
# Retrieves an HMAC key's metadata.
|
|
709
|
+
# Returns Google::Apis::StorageV1::HmacKeyMetadata.
|
|
710
|
+
def get_hmac_key access_id, project_id: nil, user_project: nil,
|
|
711
|
+
options: {}
|
|
712
|
+
execute do
|
|
713
|
+
service.get_project_hmac_key \
|
|
714
|
+
(project_id || @project), access_id,
|
|
715
|
+
user_project: user_project(user_project),
|
|
716
|
+
options: options
|
|
717
|
+
end
|
|
718
|
+
end
|
|
719
|
+
|
|
720
|
+
##
|
|
721
|
+
# Retrieves a list of HMAC key metadata matching the criteria.
|
|
722
|
+
# Returns Google::Apis::StorageV1::HmacKeysMetadata.
|
|
723
|
+
def list_hmac_keys max: nil, token: nil, service_account_email: nil,
|
|
724
|
+
project_id: nil, show_deleted_keys: nil,
|
|
725
|
+
user_project: nil, options: {}
|
|
726
|
+
execute do
|
|
727
|
+
service.list_project_hmac_keys \
|
|
728
|
+
(project_id || @project),
|
|
729
|
+
max_results: max, page_token: token,
|
|
730
|
+
service_account_email: service_account_email,
|
|
731
|
+
show_deleted_keys: show_deleted_keys,
|
|
732
|
+
user_project: user_project(user_project),
|
|
733
|
+
options: options
|
|
734
|
+
end
|
|
735
|
+
end
|
|
736
|
+
|
|
737
|
+
##
|
|
738
|
+
# Updates the state of an HMAC key. See the HMAC Key resource descriptor
|
|
739
|
+
# for valid states.
|
|
740
|
+
# Returns Google::Apis::StorageV1::HmacKeyMetadata.
|
|
741
|
+
def update_hmac_key access_id, hmac_key_metadata_object,
|
|
742
|
+
project_id: nil, user_project: nil,
|
|
743
|
+
options: {}
|
|
744
|
+
execute do
|
|
745
|
+
service.update_project_hmac_key \
|
|
746
|
+
(project_id || @project), access_id, hmac_key_metadata_object,
|
|
747
|
+
user_project: user_project(user_project),
|
|
748
|
+
options: options
|
|
749
|
+
end
|
|
750
|
+
end
|
|
751
|
+
|
|
752
|
+
##
|
|
753
|
+
# Updates a bucket, including its ACL metadata.
|
|
754
|
+
def update_bucket bucket_name,
|
|
755
|
+
bucket_gapi = nil,
|
|
756
|
+
predefined_acl: nil,
|
|
757
|
+
predefined_default_acl: nil,
|
|
758
|
+
if_metageneration_match: nil,
|
|
759
|
+
if_metageneration_not_match: nil,
|
|
760
|
+
user_project: nil,
|
|
761
|
+
options: {}
|
|
762
|
+
bucket_gapi ||= Google::Apis::StorageV1::Bucket.new
|
|
763
|
+
bucket_gapi.acl = [] if predefined_acl
|
|
764
|
+
bucket_gapi.default_object_acl = [] if predefined_default_acl
|
|
765
|
+
|
|
766
|
+
if options[:retries].nil?
|
|
767
|
+
is_idempotent = retry? if_metageneration_match: if_metageneration_match
|
|
768
|
+
options = is_idempotent ? {} : { retries: 0 }
|
|
769
|
+
end
|
|
770
|
+
|
|
771
|
+
execute do
|
|
772
|
+
service.update_bucket bucket_name,
|
|
773
|
+
bucket_gapi,
|
|
774
|
+
predefined_acl: predefined_acl,
|
|
775
|
+
predefined_default_object_acl: predefined_default_acl,
|
|
776
|
+
if_metageneration_match: if_metageneration_match,
|
|
777
|
+
if_metageneration_not_match: if_metageneration_not_match,
|
|
778
|
+
user_project: user_project(user_project),
|
|
779
|
+
options: options
|
|
451
780
|
end
|
|
452
781
|
end
|
|
453
782
|
|
|
@@ -455,7 +784,9 @@ module Google
|
|
|
455
784
|
# Retrieves the mime-type for a file path.
|
|
456
785
|
# An empty string is returned if no mime-type can be found.
|
|
457
786
|
def mime_type_for path
|
|
458
|
-
|
|
787
|
+
mime_type = MiniMime.lookup_by_filename path
|
|
788
|
+
return "" if mime_type.nil?
|
|
789
|
+
mime_type.content_type
|
|
459
790
|
end
|
|
460
791
|
|
|
461
792
|
# @private
|
|
@@ -551,8 +882,8 @@ module Google
|
|
|
551
882
|
"false" => "NONE" }[str_or_bool.to_s.downcase]
|
|
552
883
|
end
|
|
553
884
|
|
|
554
|
-
def compose_file_source_objects source_files
|
|
555
|
-
source_files.map do |file|
|
|
885
|
+
def compose_file_source_objects source_files, if_source_generation_match
|
|
886
|
+
source_objects = source_files.map do |file|
|
|
556
887
|
if file.is_a? Google::Cloud::Storage::File
|
|
557
888
|
Google::Apis::StorageV1::ComposeRequest::SourceObject.new \
|
|
558
889
|
name: file.name,
|
|
@@ -562,6 +893,18 @@ module Google
|
|
|
562
893
|
name: file
|
|
563
894
|
end
|
|
564
895
|
end
|
|
896
|
+
return source_objects unless if_source_generation_match
|
|
897
|
+
if source_files.count != if_source_generation_match.count
|
|
898
|
+
raise ArgumentError, "if provided, if_source_generation_match length must match sources length"
|
|
899
|
+
end
|
|
900
|
+
if_source_generation_match.each_with_index do |generation, i|
|
|
901
|
+
next unless generation
|
|
902
|
+
object_preconditions = Google::Apis::StorageV1::ComposeRequest::SourceObject::ObjectPreconditions.new(
|
|
903
|
+
if_generation_match: generation
|
|
904
|
+
)
|
|
905
|
+
source_objects[i].object_preconditions = object_preconditions
|
|
906
|
+
end
|
|
907
|
+
source_objects
|
|
565
908
|
end
|
|
566
909
|
|
|
567
910
|
def execute
|
|
@@ -569,163 +912,11 @@ module Google
|
|
|
569
912
|
rescue Google::Apis::Error => e
|
|
570
913
|
raise Google::Cloud::Error.from_error(e)
|
|
571
914
|
end
|
|
572
|
-
end
|
|
573
|
-
end
|
|
574
|
-
end
|
|
575
|
-
|
|
576
|
-
# rubocop:disable all
|
|
577
|
-
|
|
578
|
-
# @private
|
|
579
|
-
#
|
|
580
|
-
# IMPORTANT: These monkey-patches of Apis::StorageV1::StorageService and
|
|
581
|
-
# Apis::Core::DownloadCommand must be verified and updated (if needed) for
|
|
582
|
-
# every upgrade of google-api-client.
|
|
583
|
-
#
|
|
584
|
-
# The purpose of these modifications is to provide access to response headers
|
|
585
|
-
# (in particular, the Content-Encoding header) for the #download_file method,
|
|
586
|
-
# above. If google-api-client is modified to expose response headers to its
|
|
587
|
-
# clients, this code should be removed, and #download_file updated to use that
|
|
588
|
-
# solution instead.
|
|
589
|
-
#
|
|
590
|
-
module Apis
|
|
591
|
-
# @private
|
|
592
|
-
module StorageV1
|
|
593
|
-
# @private
|
|
594
|
-
class StorageService
|
|
595
|
-
# Returns a two-element array containing:
|
|
596
|
-
# * The `result` that is the usual return type of #get_object.
|
|
597
|
-
# * The `http_resp` from DownloadCommand#execute_once.
|
|
598
|
-
def get_object_with_response(bucket, object, generation: nil, if_generation_match: nil, if_generation_not_match: nil, if_metageneration_match: nil, if_metageneration_not_match: nil, projection: nil, user_project: nil, fields: nil, quota_user: nil, user_ip: nil, download_dest: nil, options: nil, &block)
|
|
599
|
-
if download_dest.nil?
|
|
600
|
-
command = make_simple_command(:get, 'b/{bucket}/o/{object}', options)
|
|
601
|
-
else
|
|
602
|
-
command = make_download_command(:get, 'b/{bucket}/o/{object}', options)
|
|
603
|
-
command.download_dest = download_dest
|
|
604
|
-
end
|
|
605
|
-
command.response_representation = Google::Apis::StorageV1::Object::Representation
|
|
606
|
-
command.response_class = Google::Apis::StorageV1::Object
|
|
607
|
-
command.params['bucket'] = bucket unless bucket.nil?
|
|
608
|
-
command.params['object'] = object unless object.nil?
|
|
609
|
-
command.query['generation'] = generation unless generation.nil?
|
|
610
|
-
command.query['ifGenerationMatch'] = if_generation_match unless if_generation_match.nil?
|
|
611
|
-
command.query['ifGenerationNotMatch'] = if_generation_not_match unless if_generation_not_match.nil?
|
|
612
|
-
command.query['ifMetagenerationMatch'] = if_metageneration_match unless if_metageneration_match.nil?
|
|
613
|
-
command.query['ifMetagenerationNotMatch'] = if_metageneration_not_match unless if_metageneration_not_match.nil?
|
|
614
|
-
command.query['projection'] = projection unless projection.nil?
|
|
615
|
-
command.query['userProject'] = user_project unless user_project.nil?
|
|
616
|
-
command.query['fields'] = fields unless fields.nil?
|
|
617
|
-
command.query['quotaUser'] = quota_user unless quota_user.nil?
|
|
618
|
-
command.query['userIp'] = user_ip unless user_ip.nil?
|
|
619
|
-
execute_or_queue_command_with_response(command, &block)
|
|
620
|
-
end
|
|
621
915
|
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
# * The `http_resp` from DownloadCommand#execute_once.
|
|
625
|
-
def execute_or_queue_command_with_response(command, &callback)
|
|
626
|
-
batch_command = current_batch
|
|
627
|
-
if batch_command
|
|
628
|
-
raise "Can not combine services in a batch" if Thread.current[:google_api_batch_service] != self
|
|
629
|
-
batch_command.add(command, &callback)
|
|
630
|
-
nil
|
|
631
|
-
else
|
|
632
|
-
command.execute_with_response(client, &callback)
|
|
633
|
-
end
|
|
634
|
-
end
|
|
635
|
-
end
|
|
636
|
-
end
|
|
637
|
-
# @private
|
|
638
|
-
module Core
|
|
639
|
-
# @private
|
|
640
|
-
# Streaming/resumable media download support
|
|
641
|
-
class DownloadCommand < ApiCommand
|
|
642
|
-
# Returns a two-element array containing:
|
|
643
|
-
# * The `result` that is the usual return type of #execute.
|
|
644
|
-
# * The `http_resp` from #execute_once.
|
|
645
|
-
def execute_with_response(client)
|
|
646
|
-
prepare!
|
|
647
|
-
begin
|
|
648
|
-
Retriable.retriable tries: options.retries + 1,
|
|
649
|
-
base_interval: 1,
|
|
650
|
-
multiplier: 2,
|
|
651
|
-
on: RETRIABLE_ERRORS do |try|
|
|
652
|
-
# This 2nd level retriable only catches auth errors, and supports 1 retry, which allows
|
|
653
|
-
# auth to be re-attempted without having to retry all sorts of other failures like
|
|
654
|
-
# NotFound, etc
|
|
655
|
-
auth_tries = (try == 1 && authorization_refreshable? ? 2 : 1)
|
|
656
|
-
Retriable.retriable tries: auth_tries,
|
|
657
|
-
on: [Google::Apis::AuthorizationError, Signet::AuthorizationError],
|
|
658
|
-
on_retry: proc { |*| refresh_authorization } do
|
|
659
|
-
execute_once_with_response(client).tap do |result|
|
|
660
|
-
if block_given?
|
|
661
|
-
yield result, nil
|
|
662
|
-
end
|
|
663
|
-
end
|
|
664
|
-
end
|
|
665
|
-
end
|
|
666
|
-
rescue => e
|
|
667
|
-
if block_given?
|
|
668
|
-
yield nil, e
|
|
669
|
-
else
|
|
670
|
-
raise e
|
|
671
|
-
end
|
|
672
|
-
end
|
|
673
|
-
ensure
|
|
674
|
-
release!
|
|
675
|
-
end
|
|
676
|
-
|
|
677
|
-
# Returns a two-element array containing:
|
|
678
|
-
# * The `result` that is the usual return type of #execute_once.
|
|
679
|
-
# * The `http_resp`.
|
|
680
|
-
def execute_once_with_response(client, &block)
|
|
681
|
-
request_header = header.dup
|
|
682
|
-
apply_request_options(request_header)
|
|
683
|
-
download_offset = nil
|
|
684
|
-
|
|
685
|
-
if @offset > 0
|
|
686
|
-
logger.debug { sprintf('Resuming download from offset %d', @offset) }
|
|
687
|
-
request_header[RANGE_HEADER] = sprintf('bytes=%d-', @offset)
|
|
688
|
-
end
|
|
689
|
-
|
|
690
|
-
http_res = client.get(url.to_s,
|
|
691
|
-
query: query,
|
|
692
|
-
header: request_header,
|
|
693
|
-
follow_redirect: true) do |res, chunk|
|
|
694
|
-
status = res.http_header.status_code.to_i
|
|
695
|
-
next unless OK_STATUS.include?(status)
|
|
696
|
-
|
|
697
|
-
download_offset ||= (status == 206 ? @offset : 0)
|
|
698
|
-
download_offset += chunk.bytesize
|
|
699
|
-
|
|
700
|
-
if download_offset - chunk.bytesize == @offset
|
|
701
|
-
next_chunk = chunk
|
|
702
|
-
else
|
|
703
|
-
# Oh no! Requested a chunk, but received the entire content
|
|
704
|
-
chunk_index = @offset - (download_offset - chunk.bytesize)
|
|
705
|
-
next_chunk = chunk.byteslice(chunk_index..-1)
|
|
706
|
-
next if next_chunk.nil?
|
|
707
|
-
end
|
|
708
|
-
# logger.debug { sprintf('Writing chunk (%d bytes, %d total)', chunk.length, bytes_read) }
|
|
709
|
-
@download_io.write(next_chunk)
|
|
710
|
-
|
|
711
|
-
@offset += next_chunk.bytesize
|
|
712
|
-
end
|
|
713
|
-
|
|
714
|
-
@download_io.flush
|
|
715
|
-
|
|
716
|
-
if @close_io_on_finish
|
|
717
|
-
result = nil
|
|
718
|
-
else
|
|
719
|
-
result = @download_io
|
|
720
|
-
end
|
|
721
|
-
check_status(http_res.status.to_i, http_res.header, http_res.body)
|
|
722
|
-
success([result, http_res], &block)
|
|
723
|
-
rescue => e
|
|
724
|
-
@download_io.flush
|
|
725
|
-
error(e, rethrow: true, &block)
|
|
916
|
+
def retry? query_params
|
|
917
|
+
query_params.any? { |_key, val| !val.nil? }
|
|
726
918
|
end
|
|
727
919
|
end
|
|
728
920
|
end
|
|
729
921
|
end
|
|
730
|
-
# rubocop:enable all
|
|
731
922
|
end
|