google-cloud-storage 1.29.1 → 1.32.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 +50 -0
- data/CONTRIBUTING.md +4 -5
- data/lib/google/cloud/storage/bucket.rb +242 -76
- data/lib/google/cloud/storage/bucket/acl.rb +12 -14
- data/lib/google/cloud/storage/bucket/cors.rb +4 -1
- data/lib/google/cloud/storage/bucket/lifecycle.rb +11 -11
- data/lib/google/cloud/storage/bucket/list.rb +3 -3
- data/lib/google/cloud/storage/credentials.rb +16 -14
- data/lib/google/cloud/storage/file.rb +223 -32
- data/lib/google/cloud/storage/file/acl.rb +181 -20
- data/lib/google/cloud/storage/file/list.rb +3 -3
- data/lib/google/cloud/storage/file/signer_v2.rb +2 -4
- data/lib/google/cloud/storage/file/signer_v4.rb +12 -10
- data/lib/google/cloud/storage/file/verifier.rb +2 -2
- data/lib/google/cloud/storage/hmac_key/list.rb +3 -3
- data/lib/google/cloud/storage/policy.rb +2 -2
- data/lib/google/cloud/storage/policy/binding.rb +5 -3
- data/lib/google/cloud/storage/policy/bindings.rb +2 -2
- data/lib/google/cloud/storage/policy/condition.rb +4 -2
- data/lib/google/cloud/storage/post_object.rb +2 -1
- data/lib/google/cloud/storage/project.rb +18 -6
- data/lib/google/cloud/storage/service.rb +193 -64
- data/lib/google/cloud/storage/version.rb +1 -1
- metadata +34 -14
@@ -190,7 +190,7 @@ module Google
|
|
190
190
|
generation: generation,
|
191
191
|
user_project: user_project
|
192
192
|
entity = gapi.entity
|
193
|
-
@owners
|
193
|
+
@owners&.push entity
|
194
194
|
entity
|
195
195
|
end
|
196
196
|
|
@@ -241,7 +241,7 @@ module Google
|
|
241
241
|
generation: generation,
|
242
242
|
user_project: user_project
|
243
243
|
entity = gapi.entity
|
244
|
-
@readers
|
244
|
+
@readers&.push entity
|
245
245
|
entity
|
246
246
|
end
|
247
247
|
|
@@ -281,8 +281,8 @@ module Google
|
|
281
281
|
@service.delete_file_acl \
|
282
282
|
@bucket, @file, entity,
|
283
283
|
generation: generation, user_project: user_project
|
284
|
-
@owners
|
285
|
-
@readers
|
284
|
+
@owners&.delete entity
|
285
|
+
@readers&.delete entity
|
286
286
|
true
|
287
287
|
end
|
288
288
|
|
@@ -297,6 +297,22 @@ module Google
|
|
297
297
|
# Convenience method to apply the `authenticatedRead` predefined ACL
|
298
298
|
# rule to the file.
|
299
299
|
#
|
300
|
+
# @param [Integer] generation Select a specific revision of the file to
|
301
|
+
# update. The default is the latest version.
|
302
|
+
# @param [Integer] if_generation_match Makes the operation conditional
|
303
|
+
# on whether the file's current generation matches the given value.
|
304
|
+
# Setting to 0 makes the operation succeed only if there are no live
|
305
|
+
# versions of the file.
|
306
|
+
# @param [Integer] if_generation_not_match Makes the operation conditional
|
307
|
+
# on whether the file's current generation does not match the given
|
308
|
+
# value. If no live file exists, the precondition fails. Setting to 0
|
309
|
+
# makes the operation succeed only if there is a live version of the file.
|
310
|
+
# @param [Integer] if_metageneration_match Makes the operation conditional
|
311
|
+
# on whether the file's current metageneration matches the given value.
|
312
|
+
# @param [Integer] if_metageneration_not_match Makes the operation
|
313
|
+
# conditional on whether the file's current metageneration does not
|
314
|
+
# match the given value.
|
315
|
+
#
|
300
316
|
# @example
|
301
317
|
# require "google/cloud/storage"
|
302
318
|
#
|
@@ -307,8 +323,17 @@ module Google
|
|
307
323
|
# file = bucket.file "path/to/my-file.ext"
|
308
324
|
# file.acl.auth!
|
309
325
|
#
|
310
|
-
def auth!
|
311
|
-
|
326
|
+
def auth! generation: nil,
|
327
|
+
if_generation_match: nil,
|
328
|
+
if_generation_not_match: nil,
|
329
|
+
if_metageneration_match: nil,
|
330
|
+
if_metageneration_not_match: nil
|
331
|
+
update_predefined_acl! "authenticatedRead",
|
332
|
+
generation: generation,
|
333
|
+
if_generation_match: if_generation_match,
|
334
|
+
if_generation_not_match: if_generation_not_match,
|
335
|
+
if_metageneration_match: if_metageneration_match,
|
336
|
+
if_metageneration_not_match: if_metageneration_not_match
|
312
337
|
end
|
313
338
|
alias authenticatedRead! auth!
|
314
339
|
alias auth_read! auth!
|
@@ -319,6 +344,22 @@ module Google
|
|
319
344
|
# Convenience method to apply the `bucketOwnerFullControl` predefined
|
320
345
|
# ACL rule to the file.
|
321
346
|
#
|
347
|
+
# @param [Integer] generation Select a specific revision of the file to
|
348
|
+
# update. The default is the latest version.
|
349
|
+
# @param [Integer] if_generation_match Makes the operation conditional
|
350
|
+
# on whether the file's current generation matches the given value.
|
351
|
+
# Setting to 0 makes the operation succeed only if there are no live
|
352
|
+
# versions of the file.
|
353
|
+
# @param [Integer] if_generation_not_match Makes the operation conditional
|
354
|
+
# on whether the file's current generation does not match the given
|
355
|
+
# value. If no live file exists, the precondition fails. Setting to 0
|
356
|
+
# makes the operation succeed only if there is a live version of the file.
|
357
|
+
# @param [Integer] if_metageneration_match Makes the operation conditional
|
358
|
+
# on whether the file's current metageneration matches the given value.
|
359
|
+
# @param [Integer] if_metageneration_not_match Makes the operation
|
360
|
+
# conditional on whether the file's current metageneration does not
|
361
|
+
# match the given value.
|
362
|
+
#
|
322
363
|
# @example
|
323
364
|
# require "google/cloud/storage"
|
324
365
|
#
|
@@ -329,8 +370,17 @@ module Google
|
|
329
370
|
# file = bucket.file "path/to/my-file.ext"
|
330
371
|
# file.acl.owner_full!
|
331
372
|
#
|
332
|
-
def owner_full!
|
333
|
-
|
373
|
+
def owner_full! generation: nil,
|
374
|
+
if_generation_match: nil,
|
375
|
+
if_generation_not_match: nil,
|
376
|
+
if_metageneration_match: nil,
|
377
|
+
if_metageneration_not_match: nil
|
378
|
+
update_predefined_acl! "bucketOwnerFullControl",
|
379
|
+
generation: generation,
|
380
|
+
if_generation_match: if_generation_match,
|
381
|
+
if_generation_not_match: if_generation_not_match,
|
382
|
+
if_metageneration_match: if_metageneration_match,
|
383
|
+
if_metageneration_not_match: if_metageneration_not_match
|
334
384
|
end
|
335
385
|
alias bucketOwnerFullControl! owner_full!
|
336
386
|
|
@@ -338,6 +388,22 @@ module Google
|
|
338
388
|
# Convenience method to apply the `bucketOwnerRead` predefined ACL
|
339
389
|
# rule to the file.
|
340
390
|
#
|
391
|
+
# @param [Integer] generation Select a specific revision of the file to
|
392
|
+
# update. The default is the latest version.
|
393
|
+
# @param [Integer] if_generation_match Makes the operation conditional
|
394
|
+
# on whether the file's current generation matches the given value.
|
395
|
+
# Setting to 0 makes the operation succeed only if there are no live
|
396
|
+
# versions of the file.
|
397
|
+
# @param [Integer] if_generation_not_match Makes the operation conditional
|
398
|
+
# on whether the file's current generation does not match the given
|
399
|
+
# value. If no live file exists, the precondition fails. Setting to 0
|
400
|
+
# makes the operation succeed only if there is a live version of the file.
|
401
|
+
# @param [Integer] if_metageneration_match Makes the operation conditional
|
402
|
+
# on whether the file's current metageneration matches the given value.
|
403
|
+
# @param [Integer] if_metageneration_not_match Makes the operation
|
404
|
+
# conditional on whether the file's current metageneration does not
|
405
|
+
# match the given value.
|
406
|
+
#
|
341
407
|
# @example
|
342
408
|
# require "google/cloud/storage"
|
343
409
|
#
|
@@ -348,8 +414,17 @@ module Google
|
|
348
414
|
# file = bucket.file "path/to/my-file.ext"
|
349
415
|
# file.acl.owner_read!
|
350
416
|
#
|
351
|
-
def owner_read!
|
352
|
-
|
417
|
+
def owner_read! generation: nil,
|
418
|
+
if_generation_match: nil,
|
419
|
+
if_generation_not_match: nil,
|
420
|
+
if_metageneration_match: nil,
|
421
|
+
if_metageneration_not_match: nil
|
422
|
+
update_predefined_acl! "bucketOwnerRead",
|
423
|
+
generation: generation,
|
424
|
+
if_generation_match: if_generation_match,
|
425
|
+
if_generation_not_match: if_generation_not_match,
|
426
|
+
if_metageneration_match: if_metageneration_match,
|
427
|
+
if_metageneration_not_match: if_metageneration_not_match
|
353
428
|
end
|
354
429
|
alias bucketOwnerRead! owner_read!
|
355
430
|
|
@@ -357,6 +432,22 @@ module Google
|
|
357
432
|
# Convenience method to apply the `private` predefined ACL
|
358
433
|
# rule to the file.
|
359
434
|
#
|
435
|
+
# @param [Integer] generation Select a specific revision of the file to
|
436
|
+
# update. The default is the latest version.
|
437
|
+
# @param [Integer] if_generation_match Makes the operation conditional
|
438
|
+
# on whether the file's current generation matches the given value.
|
439
|
+
# Setting to 0 makes the operation succeed only if there are no live
|
440
|
+
# versions of the file.
|
441
|
+
# @param [Integer] if_generation_not_match Makes the operation conditional
|
442
|
+
# on whether the file's current generation does not match the given
|
443
|
+
# value. If no live file exists, the precondition fails. Setting to 0
|
444
|
+
# makes the operation succeed only if there is a live version of the file.
|
445
|
+
# @param [Integer] if_metageneration_match Makes the operation conditional
|
446
|
+
# on whether the file's current metageneration matches the given value.
|
447
|
+
# @param [Integer] if_metageneration_not_match Makes the operation
|
448
|
+
# conditional on whether the file's current metageneration does not
|
449
|
+
# match the given value.
|
450
|
+
#
|
360
451
|
# @example
|
361
452
|
# require "google/cloud/storage"
|
362
453
|
#
|
@@ -367,14 +458,39 @@ module Google
|
|
367
458
|
# file = bucket.file "path/to/my-file.ext"
|
368
459
|
# file.acl.private!
|
369
460
|
#
|
370
|
-
def private!
|
371
|
-
|
461
|
+
def private! generation: nil,
|
462
|
+
if_generation_match: nil,
|
463
|
+
if_generation_not_match: nil,
|
464
|
+
if_metageneration_match: nil,
|
465
|
+
if_metageneration_not_match: nil
|
466
|
+
update_predefined_acl! "private",
|
467
|
+
generation: generation,
|
468
|
+
if_generation_match: if_generation_match,
|
469
|
+
if_generation_not_match: if_generation_not_match,
|
470
|
+
if_metageneration_match: if_metageneration_match,
|
471
|
+
if_metageneration_not_match: if_metageneration_not_match
|
372
472
|
end
|
373
473
|
|
374
474
|
##
|
375
475
|
# Convenience method to apply the `projectPrivate` predefined ACL
|
376
476
|
# rule to the file.
|
377
477
|
#
|
478
|
+
# @param [Integer] generation Select a specific revision of the file to
|
479
|
+
# update. The default is the latest version.
|
480
|
+
# @param [Integer] if_generation_match Makes the operation conditional
|
481
|
+
# on whether the file's current generation matches the given value.
|
482
|
+
# Setting to 0 makes the operation succeed only if there are no live
|
483
|
+
# versions of the file.
|
484
|
+
# @param [Integer] if_generation_not_match Makes the operation conditional
|
485
|
+
# on whether the file's current generation does not match the given
|
486
|
+
# value. If no live file exists, the precondition fails. Setting to 0
|
487
|
+
# makes the operation succeed only if there is a live version of the file.
|
488
|
+
# @param [Integer] if_metageneration_match Makes the operation conditional
|
489
|
+
# on whether the file's current metageneration matches the given value.
|
490
|
+
# @param [Integer] if_metageneration_not_match Makes the operation
|
491
|
+
# conditional on whether the file's current metageneration does not
|
492
|
+
# match the given value.
|
493
|
+
#
|
378
494
|
# @example
|
379
495
|
# require "google/cloud/storage"
|
380
496
|
#
|
@@ -385,8 +501,17 @@ module Google
|
|
385
501
|
# file = bucket.file "path/to/my-file.ext"
|
386
502
|
# file.acl.project_private!
|
387
503
|
#
|
388
|
-
def project_private!
|
389
|
-
|
504
|
+
def project_private! generation: nil,
|
505
|
+
if_generation_match: nil,
|
506
|
+
if_generation_not_match: nil,
|
507
|
+
if_metageneration_match: nil,
|
508
|
+
if_metageneration_not_match: nil
|
509
|
+
update_predefined_acl! "projectPrivate",
|
510
|
+
generation: generation,
|
511
|
+
if_generation_match: if_generation_match,
|
512
|
+
if_generation_not_match: if_generation_not_match,
|
513
|
+
if_metageneration_match: if_metageneration_match,
|
514
|
+
if_metageneration_not_match: if_metageneration_not_match
|
390
515
|
end
|
391
516
|
alias projectPrivate! project_private!
|
392
517
|
|
@@ -394,6 +519,22 @@ module Google
|
|
394
519
|
# Convenience method to apply the `publicRead` predefined ACL
|
395
520
|
# rule to the file.
|
396
521
|
#
|
522
|
+
# @param [Integer] generation Select a specific revision of the file to
|
523
|
+
# update. The default is the latest version.
|
524
|
+
# @param [Integer] if_generation_match Makes the operation conditional
|
525
|
+
# on whether the file's current generation matches the given value.
|
526
|
+
# Setting to 0 makes the operation succeed only if there are no live
|
527
|
+
# versions of the file.
|
528
|
+
# @param [Integer] if_generation_not_match Makes the operation conditional
|
529
|
+
# on whether the file's current generation does not match the given
|
530
|
+
# value. If no live file exists, the precondition fails. Setting to 0
|
531
|
+
# makes the operation succeed only if there is a live version of the file.
|
532
|
+
# @param [Integer] if_metageneration_match Makes the operation conditional
|
533
|
+
# on whether the file's current metageneration matches the given value.
|
534
|
+
# @param [Integer] if_metageneration_not_match Makes the operation
|
535
|
+
# conditional on whether the file's current metageneration does not
|
536
|
+
# match the given value.
|
537
|
+
#
|
397
538
|
# @example
|
398
539
|
# require "google/cloud/storage"
|
399
540
|
#
|
@@ -404,8 +545,17 @@ module Google
|
|
404
545
|
# file = bucket.file "path/to/my-file.ext"
|
405
546
|
# file.acl.public!
|
406
547
|
#
|
407
|
-
def public!
|
408
|
-
|
548
|
+
def public! generation: nil,
|
549
|
+
if_generation_match: nil,
|
550
|
+
if_generation_not_match: nil,
|
551
|
+
if_metageneration_match: nil,
|
552
|
+
if_metageneration_not_match: nil
|
553
|
+
update_predefined_acl! "publicRead",
|
554
|
+
generation: generation,
|
555
|
+
if_generation_match: if_generation_match,
|
556
|
+
if_generation_not_match: if_generation_not_match,
|
557
|
+
if_metageneration_match: if_metageneration_match,
|
558
|
+
if_metageneration_not_match: if_metageneration_not_match
|
409
559
|
end
|
410
560
|
alias publicRead! public!
|
411
561
|
alias public_read! public!
|
@@ -418,9 +568,21 @@ module Google
|
|
418
568
|
self
|
419
569
|
end
|
420
570
|
|
421
|
-
def update_predefined_acl! acl_role
|
571
|
+
def update_predefined_acl! acl_role,
|
572
|
+
generation: nil,
|
573
|
+
if_generation_match: nil,
|
574
|
+
if_generation_not_match: nil,
|
575
|
+
if_metageneration_match: nil,
|
576
|
+
if_metageneration_not_match: nil
|
422
577
|
patched_file = Google::Apis::StorageV1::Object.new acl: []
|
423
|
-
@service.patch_file @bucket,
|
578
|
+
@service.patch_file @bucket,
|
579
|
+
@file,
|
580
|
+
patched_file,
|
581
|
+
generation: generation,
|
582
|
+
if_generation_match: if_generation_match,
|
583
|
+
if_generation_not_match: if_generation_not_match,
|
584
|
+
if_metageneration_match: if_metageneration_match,
|
585
|
+
if_metageneration_not_match: if_metageneration_not_match,
|
424
586
|
predefined_acl: acl_role,
|
425
587
|
user_project: user_project
|
426
588
|
clear!
|
@@ -428,8 +590,7 @@ module Google
|
|
428
590
|
|
429
591
|
def entities_from_acls acls, role
|
430
592
|
selected = acls.select { |acl| acl.role == role }
|
431
|
-
|
432
|
-
entities
|
593
|
+
selected.map(&:entity)
|
433
594
|
end
|
434
595
|
end
|
435
596
|
end
|
@@ -141,17 +141,17 @@ module Google
|
|
141
141
|
# puts file.name
|
142
142
|
# end
|
143
143
|
#
|
144
|
-
def all request_limit: nil
|
144
|
+
def all request_limit: nil, &block
|
145
145
|
request_limit = request_limit.to_i if request_limit
|
146
146
|
unless block_given?
|
147
147
|
return enum_for :all, request_limit: request_limit
|
148
148
|
end
|
149
149
|
results = self
|
150
150
|
loop do
|
151
|
-
results.each
|
151
|
+
results.each(&block)
|
152
152
|
if request_limit
|
153
153
|
request_limit -= 1
|
154
|
-
break if request_limit
|
154
|
+
break if request_limit.negative?
|
155
155
|
end
|
156
156
|
break unless results.next?
|
157
157
|
results = results.next
|
@@ -147,10 +147,8 @@ module Google
|
|
147
147
|
"&Expires=#{expires}" \
|
148
148
|
"&Signature=#{url_escape signed_string}"
|
149
149
|
|
150
|
-
|
151
|
-
|
152
|
-
url << "&#{url_escape name}=#{url_escape value}"
|
153
|
-
end
|
150
|
+
query&.each do |name, value|
|
151
|
+
url << "&#{url_escape name}=#{url_escape value}"
|
154
152
|
end
|
155
153
|
|
156
154
|
url
|
@@ -60,7 +60,7 @@ module Google
|
|
60
60
|
|
61
61
|
p = {}
|
62
62
|
p["conditions"] = policy_conditions base_fields, conditions, fields
|
63
|
-
expires ||= 60*60*24
|
63
|
+
expires ||= 60 * 60 * 24
|
64
64
|
p["expiration"] = (now + expires).strftime "%Y-%m-%dT%H:%M:%SZ"
|
65
65
|
|
66
66
|
policy_str = escape_characters p.to_json
|
@@ -100,7 +100,7 @@ module Google
|
|
100
100
|
|
101
101
|
algorithm = "GOOG4-RSA-SHA256"
|
102
102
|
expires = determine_expires expires
|
103
|
-
credential = issuer
|
103
|
+
credential = "#{issuer}/#{scope}"
|
104
104
|
canonical_query_str = canonical_query query, algorithm, credential, goog_date, expires, signed_headers_str
|
105
105
|
|
106
106
|
# From AWS: You don't include a payload hash in the Canonical
|
@@ -129,11 +129,10 @@ module Google
|
|
129
129
|
end
|
130
130
|
|
131
131
|
# methods below are public visibility only for unit testing
|
132
|
+
# rubocop:disable Style/StringLiterals
|
132
133
|
def escape_characters str
|
133
134
|
str.split("").map do |s|
|
134
|
-
if
|
135
|
-
escape_special_unicode s
|
136
|
-
else
|
135
|
+
if s.ascii_only?
|
137
136
|
case s
|
138
137
|
when "\\"
|
139
138
|
'\\'
|
@@ -152,12 +151,15 @@ module Google
|
|
152
151
|
else
|
153
152
|
s
|
154
153
|
end
|
154
|
+
else
|
155
|
+
escape_special_unicode s
|
155
156
|
end
|
156
157
|
end.join
|
157
158
|
end
|
159
|
+
# rubocop:enable Style/StringLiterals
|
158
160
|
|
159
161
|
def escape_special_unicode str
|
160
|
-
str.unpack("U*").map { |i|
|
162
|
+
str.unpack("U*").map { |i| "\\u#{i.to_s(16).rjust(4, '0')}" }.join
|
161
163
|
end
|
162
164
|
|
163
165
|
protected
|
@@ -177,7 +179,7 @@ module Google
|
|
177
179
|
# Add the bucket to the head of the base_fields. This is not returned in the PostObject fields.
|
178
180
|
conditions.unshift "bucket" => @bucket_name
|
179
181
|
# Add user-provided conditions to the head of the conditions array.
|
180
|
-
conditions
|
182
|
+
conditions = user_conditions + conditions if user_conditions
|
181
183
|
if user_fields
|
182
184
|
# Convert each pair in fields hash to a single-entry hash and add it to the head of the conditions array.
|
183
185
|
user_fields.to_a.reverse.each { |f| conditions.unshift Hash[*f] }
|
@@ -212,14 +214,14 @@ module Google
|
|
212
214
|
if signer.is_a? Proc
|
213
215
|
lambda do |string_to_sign|
|
214
216
|
sig = signer.call string_to_sign
|
215
|
-
sig.
|
217
|
+
sig.unpack1 "H*"
|
216
218
|
end
|
217
219
|
else
|
218
220
|
signer = OpenSSL::PKey::RSA.new signer unless signer.respond_to? :sign
|
219
221
|
# Sign string to sign
|
220
222
|
lambda do |string_to_sign|
|
221
223
|
sig = signer.sign OpenSSL::Digest::SHA256.new, string_to_sign
|
222
|
-
sig.
|
224
|
+
sig.unpack1 "H*"
|
223
225
|
end
|
224
226
|
end
|
225
227
|
end
|
@@ -359,7 +361,7 @@ module Google
|
|
359
361
|
end
|
360
362
|
packed_signature = signing_key.sign OpenSSL::Digest::SHA256.new, data
|
361
363
|
end
|
362
|
-
packed_signature.
|
364
|
+
packed_signature.unpack1("H*").force_encoding "utf-8"
|
363
365
|
end
|
364
366
|
end
|
365
367
|
end
|
@@ -50,7 +50,7 @@ module Google
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def self.md5_for local_file
|
53
|
-
if local_file.respond_to? :
|
53
|
+
if local_file.respond_to? :to_path
|
54
54
|
::File.open Pathname(local_file).to_path, "rb" do |f|
|
55
55
|
::Digest::MD5.file(f).base64digest
|
56
56
|
end
|
@@ -63,7 +63,7 @@ module Google
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def self.crc32c_for local_file
|
66
|
-
if local_file.respond_to? :
|
66
|
+
if local_file.respond_to? :to_path
|
67
67
|
::File.open Pathname(local_file).to_path, "rb" do |f|
|
68
68
|
::Digest::CRC32c.file(f).base64digest
|
69
69
|
end
|
@@ -131,17 +131,17 @@ module Google
|
|
131
131
|
# puts key.access_id
|
132
132
|
# end
|
133
133
|
#
|
134
|
-
def all request_limit: nil
|
134
|
+
def all request_limit: nil, &block
|
135
135
|
request_limit = request_limit.to_i if request_limit
|
136
136
|
unless block_given?
|
137
137
|
return enum_for :all, request_limit: request_limit
|
138
138
|
end
|
139
139
|
results = self
|
140
140
|
loop do
|
141
|
-
results.each
|
141
|
+
results.each(&block)
|
142
142
|
if request_limit
|
143
143
|
request_limit -= 1
|
144
|
-
break if request_limit
|
144
|
+
break if request_limit.negative?
|
145
145
|
end
|
146
146
|
break unless results.next?
|
147
147
|
results = results.next
|