aws-sdk-s3 1.87.0 → 1.143.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1106 -0
  3. data/LICENSE.txt +202 -0
  4. data/VERSION +1 -0
  5. data/lib/aws-sdk-s3/bucket.rb +605 -114
  6. data/lib/aws-sdk-s3/bucket_acl.rb +36 -11
  7. data/lib/aws-sdk-s3/bucket_cors.rb +40 -15
  8. data/lib/aws-sdk-s3/bucket_lifecycle.rb +42 -15
  9. data/lib/aws-sdk-s3/bucket_lifecycle_configuration.rb +43 -13
  10. data/lib/aws-sdk-s3/bucket_logging.rb +40 -11
  11. data/lib/aws-sdk-s3/bucket_notification.rb +30 -12
  12. data/lib/aws-sdk-s3/bucket_policy.rb +82 -13
  13. data/lib/aws-sdk-s3/bucket_request_payment.rb +35 -13
  14. data/lib/aws-sdk-s3/bucket_tagging.rb +38 -13
  15. data/lib/aws-sdk-s3/bucket_versioning.rb +82 -21
  16. data/lib/aws-sdk-s3/bucket_website.rb +38 -13
  17. data/lib/aws-sdk-s3/client.rb +8666 -3425
  18. data/lib/aws-sdk-s3/client_api.rb +774 -225
  19. data/lib/aws-sdk-s3/customizations/bucket.rb +31 -50
  20. data/lib/aws-sdk-s3/customizations/errors.rb +27 -0
  21. data/lib/aws-sdk-s3/customizations/object.rb +211 -37
  22. data/lib/aws-sdk-s3/customizations/types/permanent_redirect.rb +26 -0
  23. data/lib/aws-sdk-s3/customizations.rb +7 -0
  24. data/lib/aws-sdk-s3/encryption/client.rb +7 -3
  25. data/lib/aws-sdk-s3/encryption/decrypt_handler.rb +0 -4
  26. data/lib/aws-sdk-s3/encryption/kms_cipher_provider.rb +13 -9
  27. data/lib/aws-sdk-s3/encryptionV2/client.rb +7 -3
  28. data/lib/aws-sdk-s3/encryptionV2/decrypt_handler.rb +1 -4
  29. data/lib/aws-sdk-s3/encryptionV2/default_cipher_provider.rb +3 -3
  30. data/lib/aws-sdk-s3/encryptionV2/encrypt_handler.rb +0 -4
  31. data/lib/aws-sdk-s3/encryptionV2/kms_cipher_provider.rb +10 -6
  32. data/lib/aws-sdk-s3/endpoint_parameters.rb +178 -0
  33. data/lib/aws-sdk-s3/endpoint_provider.rb +591 -0
  34. data/lib/aws-sdk-s3/endpoints.rb +2590 -0
  35. data/lib/aws-sdk-s3/errors.rb +1 -1
  36. data/lib/aws-sdk-s3/event_streams.rb +1 -1
  37. data/lib/aws-sdk-s3/express_credentials.rb +55 -0
  38. data/lib/aws-sdk-s3/express_credentials_cache.rb +30 -0
  39. data/lib/aws-sdk-s3/express_credentials_provider.rb +36 -0
  40. data/lib/aws-sdk-s3/file_downloader.rb +171 -41
  41. data/lib/aws-sdk-s3/file_uploader.rb +14 -7
  42. data/lib/aws-sdk-s3/multipart_file_uploader.rb +26 -8
  43. data/lib/aws-sdk-s3/multipart_stream_uploader.rb +41 -14
  44. data/lib/aws-sdk-s3/multipart_upload.rb +198 -23
  45. data/lib/aws-sdk-s3/multipart_upload_part.rb +285 -34
  46. data/lib/aws-sdk-s3/object.rb +1824 -266
  47. data/lib/aws-sdk-s3/object_acl.rb +58 -19
  48. data/lib/aws-sdk-s3/object_copier.rb +7 -5
  49. data/lib/aws-sdk-s3/object_multipart_copier.rb +41 -19
  50. data/lib/aws-sdk-s3/object_summary.rb +1579 -299
  51. data/lib/aws-sdk-s3/object_version.rb +372 -64
  52. data/lib/aws-sdk-s3/plugins/accelerate.rb +1 -39
  53. data/lib/aws-sdk-s3/plugins/arn.rb +25 -142
  54. data/lib/aws-sdk-s3/plugins/bucket_dns.rb +3 -39
  55. data/lib/aws-sdk-s3/plugins/bucket_name_restrictions.rb +1 -6
  56. data/lib/aws-sdk-s3/plugins/dualstack.rb +2 -49
  57. data/lib/aws-sdk-s3/plugins/endpoints.rb +274 -0
  58. data/lib/aws-sdk-s3/plugins/expect_100_continue.rb +3 -1
  59. data/lib/aws-sdk-s3/plugins/express_session_auth.rb +91 -0
  60. data/lib/aws-sdk-s3/plugins/get_bucket_location_fix.rb +1 -1
  61. data/lib/aws-sdk-s3/plugins/iad_regional_endpoint.rb +8 -31
  62. data/lib/aws-sdk-s3/plugins/location_constraint.rb +3 -1
  63. data/lib/aws-sdk-s3/plugins/md5s.rb +6 -3
  64. data/lib/aws-sdk-s3/plugins/s3_signer.rb +35 -102
  65. data/lib/aws-sdk-s3/plugins/skip_whole_multipart_get_checksums.rb +31 -0
  66. data/lib/aws-sdk-s3/plugins/streaming_retry.rb +23 -2
  67. data/lib/aws-sdk-s3/presigned_post.rb +99 -78
  68. data/lib/aws-sdk-s3/presigner.rb +43 -51
  69. data/lib/aws-sdk-s3/resource.rb +102 -6
  70. data/lib/aws-sdk-s3/types.rb +7404 -5114
  71. data/lib/aws-sdk-s3/waiters.rb +1 -1
  72. data/lib/aws-sdk-s3.rb +6 -2
  73. data/sig/bucket.rbs +212 -0
  74. data/sig/bucket_acl.rbs +78 -0
  75. data/sig/bucket_cors.rbs +69 -0
  76. data/sig/bucket_lifecycle.rbs +88 -0
  77. data/sig/bucket_lifecycle_configuration.rbs +111 -0
  78. data/sig/bucket_logging.rbs +76 -0
  79. data/sig/bucket_notification.rbs +114 -0
  80. data/sig/bucket_policy.rbs +59 -0
  81. data/sig/bucket_request_payment.rbs +54 -0
  82. data/sig/bucket_tagging.rbs +65 -0
  83. data/sig/bucket_versioning.rbs +77 -0
  84. data/sig/bucket_website.rbs +93 -0
  85. data/sig/client.rbs +2360 -0
  86. data/sig/errors.rbs +34 -0
  87. data/sig/multipart_upload.rbs +110 -0
  88. data/sig/multipart_upload_part.rbs +105 -0
  89. data/sig/object.rbs +436 -0
  90. data/sig/object_acl.rbs +86 -0
  91. data/sig/object_summary.rbs +334 -0
  92. data/sig/object_version.rbs +131 -0
  93. data/sig/resource.rbs +124 -0
  94. data/sig/types.rbs +2562 -0
  95. data/sig/waiters.rbs +83 -0
  96. metadata +51 -17
  97. data/lib/aws-sdk-s3/arn/access_point_arn.rb +0 -62
  98. data/lib/aws-sdk-s3/arn/outpost_access_point_arn.rb +0 -71
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module S3
5
+ module Plugins
6
+ # @api private
7
+ class ExpressSessionAuth < Seahorse::Client::Plugin
8
+ # This should be s3_disable_express_auth instead
9
+ # But this is not a built in. We're overwriting the generated value
10
+ option(:disable_s3_express_session_auth,
11
+ default: false,
12
+ doc_type: 'Boolean',
13
+ docstring: <<-DOCS) do |cfg|
14
+ When `true`, S3 Express session authentication is disabled.
15
+ DOCS
16
+ resolve_disable_s3_express_session_auth(cfg)
17
+ end
18
+
19
+ option(:express_credentials_provider,
20
+ doc_type: 'Aws::S3::ExpressCredentialsProvider',
21
+ rbs_type: 'untyped',
22
+ docstring: <<-DOCS) do |_cfg|
23
+ Credential Provider for S3 Express endpoints. Manages credentials
24
+ for different buckets.
25
+ DOCS
26
+ Aws::S3::ExpressCredentialsProvider.new
27
+ end
28
+
29
+ # @api private
30
+ class Handler < Seahorse::Client::Handler
31
+ def call(context)
32
+ if (props = context[:endpoint_properties])
33
+ # S3 Express endpoint - turn off md5 and enable crc32 default
34
+ if (backend = props['backend']) && backend == 'S3Express'
35
+ if context.operation_name == :put_object || checksum_required?(context)
36
+ context[:default_request_checksum_algorithm] = 'CRC32'
37
+ end
38
+ context[:s3_express_endpoint] = true
39
+ end
40
+
41
+ # if s3 express auth, use new credentials and sign additional header
42
+ if context[:auth_scheme]['name'] == 'sigv4-s3express' &&
43
+ !context.config.disable_s3_express_session_auth
44
+ bucket = context.params[:bucket]
45
+ credentials_provider = context.config.express_credentials_provider
46
+ credentials = credentials_provider.express_credentials_for(bucket)
47
+ context[:sigv4_credentials] = credentials # Sign will use this
48
+ end
49
+ end
50
+ @handler.call(context)
51
+ end
52
+
53
+ private
54
+
55
+ def checksum_required?(context)
56
+ context.operation.http_checksum_required ||
57
+ (context.operation.http_checksum &&
58
+ context.operation.http_checksum['requestChecksumRequired'])
59
+ end
60
+ end
61
+
62
+ handler(Handler)
63
+
64
+ # Optimization - sets this client as the client to create sessions.
65
+ def after_initialize(client)
66
+ provider = client.config.express_credentials_provider
67
+ provider.client = client unless provider.client
68
+ end
69
+
70
+ class << self
71
+ private
72
+
73
+ def resolve_disable_s3_express_session_auth(cfg)
74
+ value = ENV['AWS_S3_DISABLE_EXPRESS_SESSION_AUTH'] ||
75
+ Aws.shared_config.s3_disable_express_session_auth(profile: cfg.profile) ||
76
+ 'false'
77
+ value = Aws::Util.str_2_bool(value)
78
+ # Raise if provided value is not true or false
79
+ if value.nil?
80
+ raise ArgumentError,
81
+ 'Must provide either `true` or `false` for the '\
82
+ '`s3_disable_express_session_auth` profile option or for '\
83
+ "ENV['AWS_S3_DISABLE_EXPRESS_SESSION_AUTH']."
84
+ end
85
+ value
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
@@ -11,7 +11,7 @@ module Aws
11
11
  @handler.call(context).on(200) do |response|
12
12
  response.data = S3::Types::GetBucketLocationOutput.new
13
13
  xml = context.http_response.body_contents
14
- matches = xml.match(/>(.+?)<\/LocationConstraint>/)
14
+ matches = xml.match(/<LocationConstraint.*?>(.+?)<\/LocationConstraint>/)
15
15
  response.data[:location_constraint] = matches ? matches[1] : ''
16
16
  end
17
17
  end
@@ -10,46 +10,23 @@ module Aws
10
10
  default: 'legacy',
11
11
  doc_type: String,
12
12
  docstring: <<-DOCS) do |cfg|
13
- Passing in `regional` to enable regional endpoint for S3's `us-east-1`
14
- region. Defaults to `legacy` mode using global endpoint.
13
+ Pass in `regional` to enable the `us-east-1` regional endpoint.
14
+ Defaults to `legacy` mode which uses the global endpoint.
15
15
  DOCS
16
16
  resolve_iad_regional_endpoint(cfg)
17
17
  end
18
18
 
19
- def add_handlers(handlers, config)
20
- if config.region == 'us-east-1'
21
- handlers.add(Handler)
22
- end
23
- end
24
-
25
- # @api private
26
- class Handler < Seahorse::Client::Handler
27
-
28
- def call(context)
29
- # keep legacy global endpoint pattern by default
30
- if context.config.s3_us_east_1_regional_endpoint == 'legacy'
31
- host = context.http_request.endpoint.host
32
- # if it's an ARN, don't touch the endpoint at all
33
- # TODO this should use context.metadata[:s3_arn] later
34
- unless host.include?('.s3-outposts.') || host.include?('.s3-accesspoint.')
35
- legacy_host = IADRegionalEndpoint.legacy_host(host)
36
- context.http_request.endpoint.host = legacy_host
37
- end
38
- end
39
- @handler.call(context)
40
- end
41
-
42
- end
43
-
44
- def self.legacy_host(host)
45
- host.sub(".us-east-1", '')
46
- end
47
-
48
19
  private
49
20
 
50
21
  def self.resolve_iad_regional_endpoint(cfg)
22
+ default_mode_value =
23
+ if cfg.respond_to?(:defaults_mode_config_resolver)
24
+ cfg.defaults_mode_config_resolver.resolve(:s3_us_east_1_regional_endpoint)
25
+ end
26
+
51
27
  mode = ENV['AWS_S3_US_EAST_1_REGIONAL_ENDPOINT'] ||
52
28
  Aws.shared_config.s3_us_east_1_regional_endpoint(profile: cfg.profile) ||
29
+ default_mode_value ||
53
30
  'legacy'
54
31
  mode = mode.downcase
55
32
  unless %w(legacy regional).include?(mode)
@@ -22,7 +22,9 @@ module Aws
22
22
 
23
23
  def populate_location_constraint(params, region)
24
24
  params[:create_bucket_configuration] ||= {}
25
- params[:create_bucket_configuration][:location_constraint] ||= region
25
+ unless params[:create_bucket_configuration][:location]
26
+ params[:create_bucket_configuration][:location_constraint] ||= region
27
+ end
26
28
  end
27
29
 
28
30
  end
@@ -22,9 +22,12 @@ module Aws
22
22
  CHUNK_SIZE = 1 * 1024 * 1024 # one MB
23
23
 
24
24
  def call(context)
25
- body = context.http_request.body
26
- if body.size > 0
27
- context.http_request.headers['Content-Md5'] ||= md5(body)
25
+ if !context[:checksum_algorithms] && # skip in favor of flexible checksum
26
+ !context[:s3_express_endpoint] # s3 express endpoints do not support md5
27
+ body = context.http_request.body
28
+ if body.respond_to?(:size) && body.size > 0
29
+ context.http_request.headers['Content-Md5'] ||= md5(body)
30
+ end
28
31
  end
29
32
  @handler.call(context)
30
33
  end
@@ -5,26 +5,13 @@ require 'aws-sigv4'
5
5
  module Aws
6
6
  module S3
7
7
  module Plugins
8
- # This plugin is an implementation detail and may be modified.
8
+ # This plugin used to have a V4 signer but it was removed in favor of
9
+ # generic Sign plugin that uses endpoint auth scheme.
10
+ #
9
11
  # @api private
10
12
  class S3Signer < Seahorse::Client::Plugin
11
13
  option(:signature_version, 'v4')
12
14
 
13
- option(:sigv4_signer) do |cfg|
14
- S3Signer.build_v4_signer(
15
- service: 's3',
16
- region: cfg.sigv4_region,
17
- credentials: cfg.credentials
18
- )
19
- end
20
-
21
- option(:sigv4_region) do |cfg|
22
- # S3 removes core's signature_v4 plugin that checks for this
23
- raise Aws::Errors::MissingRegionError if cfg.region.nil?
24
-
25
- Aws::Partitions::EndpointProvider.signing_region(cfg.region, 's3')
26
- end
27
-
28
15
  def add_handlers(handlers, cfg)
29
16
  case cfg.signature_version
30
17
  when 'v4' then add_v4_handlers(handlers)
@@ -37,11 +24,11 @@ module Aws
37
24
 
38
25
  def add_v4_handlers(handlers)
39
26
  handlers.add(CachedBucketRegionHandler, step: :sign, priority: 60)
40
- handlers.add(V4Handler, step: :sign)
41
27
  handlers.add(BucketRegionErrorHandler, step: :sign, priority: 40)
42
28
  end
43
29
 
44
30
  def add_legacy_handler(handlers)
31
+ # generic Sign plugin will be skipped if it sees sigv2
45
32
  handlers.add(LegacyHandler, step: :sign)
46
33
  end
47
34
 
@@ -52,47 +39,6 @@ module Aws
52
39
  end
53
40
  end
54
41
 
55
- class V4Handler < Seahorse::Client::Handler
56
- def call(context)
57
- Aws::Plugins::SignatureV4.apply_signature(
58
- context: context,
59
- signer: sigv4_signer(context)
60
- )
61
- @handler.call(context)
62
- end
63
-
64
- private
65
-
66
- def sigv4_signer(context)
67
- # If the client was configured with the wrong region,
68
- # we have to build a new signer.
69
- if context[:cached_sigv4_region] &&
70
- context[:cached_sigv4_region] != context.config.sigv4_signer.region
71
- S3Signer.build_v4_signer(
72
- service: 's3',
73
- region: context[:cached_sigv4_region],
74
- credentials: context.config.credentials
75
- )
76
- else
77
- resolved_region, arn = ARN.resolve_arn!(
78
- context.params[:bucket],
79
- context.config.sigv4_signer.region,
80
- context.config.s3_use_arn_region
81
- )
82
-
83
- if arn
84
- S3Signer.build_v4_signer(
85
- service: arn.service,
86
- region: resolved_region,
87
- credentials: context.config.credentials
88
- )
89
- else
90
- context.config.sigv4_signer
91
- end
92
- end
93
- end
94
- end
95
-
96
42
  # This handler will update the http endpoint when the bucket region
97
43
  # is known/cached.
98
44
  class CachedBucketRegionHandler < Seahorse::Client::Handler
@@ -106,11 +52,13 @@ module Aws
106
52
 
107
53
  def check_for_cached_region(context, bucket)
108
54
  cached_region = S3::BUCKET_REGIONS[bucket]
109
- if cached_region && cached_region != context.config.region
55
+ if cached_region &&
56
+ cached_region != context.config.region &&
57
+ !S3Signer.custom_endpoint?(context)
110
58
  context.http_request.endpoint.host = S3Signer.new_hostname(
111
59
  context, cached_region
112
60
  )
113
- context[:cached_sigv4_region] = cached_region
61
+ context[:sigv4_region] = cached_region # Sign plugin will use this
114
62
  end
115
63
  end
116
64
  end
@@ -118,7 +66,8 @@ module Aws
118
66
  # This handler detects when a request fails because of a mismatched bucket
119
67
  # region. It follows up by making a request to determine the correct
120
68
  # region, then finally a version 4 signed request against the correct
121
- # regional endpoint.
69
+ # regional endpoint. This is intended for s3's global endpoint which
70
+ # will return 400 if the bucket is not in region.
122
71
  class BucketRegionErrorHandler < Seahorse::Client::Handler
123
72
  def call(context)
124
73
  response = @handler.call(context)
@@ -130,7 +79,8 @@ module Aws
130
79
  def handle_region_errors(response)
131
80
  if wrong_sigv4_region?(response) &&
132
81
  !fips_region?(response) &&
133
- !custom_endpoint?(response)
82
+ !S3Signer.custom_endpoint?(response.context) &&
83
+ !expired_credentials?(response)
134
84
  get_region_and_retry(response.context)
135
85
  else
136
86
  response
@@ -151,14 +101,11 @@ module Aws
151
101
  end
152
102
 
153
103
  def fips_region?(resp)
154
- resp.context.http_request.endpoint.host.include?('fips')
104
+ resp.context.http_request.endpoint.host.include?('s3-fips.')
155
105
  end
156
106
 
157
- def custom_endpoint?(resp)
158
- resolved_suffix = Aws::Partitions::EndpointProvider.dns_suffix_for(
159
- resp.context.config.region
160
- )
161
- !resp.context.http_request.endpoint.hostname.include?(resolved_suffix)
107
+ def expired_credentials?(resp)
108
+ resp.context.http_response.body_contents.match(/<Code>ExpiredToken<\/Code>/)
162
109
  end
163
110
 
164
111
  def wrong_sigv4_region?(resp)
@@ -173,14 +120,14 @@ module Aws
173
120
  context, actual_region
174
121
  )
175
122
  context.metadata[:redirect_region] = actual_region
176
- Aws::Plugins::SignatureV4.apply_signature(
177
- context: context,
178
- signer: S3Signer.build_v4_signer(
179
- service: 's3',
180
- region: actual_region,
181
- credentials: context.config.credentials
182
- )
123
+
124
+ signer = Aws::Plugins::Sign.signer_for(
125
+ context[:auth_scheme],
126
+ context.config,
127
+ actual_region
183
128
  )
129
+
130
+ signer.sign(context)
184
131
  end
185
132
 
186
133
  def region_from_body(body)
@@ -206,36 +153,22 @@ module Aws
206
153
  end
207
154
 
208
155
  class << self
209
- # @option options [required, String] :region
210
- # @option options [required, #credentials] :credentials
211
- # @api private
212
- def build_v4_signer(options = {})
213
- Aws::Sigv4::Signer.new(
214
- service: options[:service],
215
- region: options[:region],
216
- credentials_provider: options[:credentials],
217
- uri_escape_path: false,
218
- unsigned_headers: ['content-length', 'x-amzn-trace-id']
219
- )
156
+ def new_hostname(context, region)
157
+ endpoint_params = context[:endpoint_params].dup
158
+ endpoint_params.region = region
159
+ endpoint_params.endpoint = nil
160
+ endpoint =
161
+ context.config.endpoint_provider.resolve_endpoint(endpoint_params)
162
+ URI(endpoint.url).host
220
163
  end
221
164
 
222
- def new_hostname(context, region)
223
- # Check to see if the bucket is actually an ARN and resolve it
224
- # Otherwise it will retry with the ARN as the bucket name.
225
- resolved_region, arn = ARN.resolve_arn!(
226
- context.params[:bucket],
227
- region,
228
- context.config.s3_use_arn_region
229
- )
230
- uri = URI.parse(
231
- Aws::Partitions::EndpointProvider.resolve(resolved_region, 's3')
232
- )
165
+ def custom_endpoint?(context)
166
+ region = context.config.region
167
+ partition = Aws::Endpoints::Matchers.aws_partition(region)
168
+ endpoint = context.http_request.endpoint
233
169
 
234
- if arn
235
- ARN.resolve_url!(uri, arn).host
236
- else
237
- "#{context.params[:bucket]}.#{uri.host}"
238
- end
170
+ !endpoint.hostname.include?(partition['dnsSuffix']) &&
171
+ !endpoint.hostname.include?(partition['dualStackDnsSuffix'])
239
172
  end
240
173
  end
241
174
  end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module S3
5
+ module Plugins
6
+
7
+ # S3 GetObject results for whole Multipart Objects contain a checksum
8
+ # that cannot be validated. These should be skipped by the
9
+ # ChecksumAlgorithm plugin.
10
+ class SkipWholeMultipartGetChecksums < Seahorse::Client::Plugin
11
+
12
+ class Handler < Seahorse::Client::Handler
13
+
14
+ def call(context)
15
+ context[:http_checksum] ||= {}
16
+ context[:http_checksum][:skip_on_suffix] = true
17
+
18
+ @handler.call(context)
19
+ end
20
+
21
+ end
22
+
23
+ handler(
24
+ Handler,
25
+ step: :initialize,
26
+ operations: [:get_object]
27
+ )
28
+ end
29
+ end
30
+ end
31
+ end
@@ -36,6 +36,17 @@ module Aws
36
36
  def rewind; end
37
37
  end
38
38
 
39
+ class NonRetryableStreamingError < StandardError
40
+
41
+ def initialize(error)
42
+ super('Unable to retry request - retry could result in processing duplicated chunks.')
43
+ set_backtrace(error.backtrace)
44
+ @original_error = error
45
+ end
46
+
47
+ attr_reader :original_error
48
+ end
49
+
39
50
  # This handler works with the ResponseTarget plugin to provide smart
40
51
  # retries of S3 streaming operations that support the range parameter
41
52
  # (currently only: get_object). When a 200 OK with a TruncatedBodyError
@@ -84,8 +95,18 @@ module Aws
84
95
  end
85
96
 
86
97
  context.http_response.on_error do |error|
87
- if retryable_body?(context) && truncated_body?(error)
88
- context.http_request.headers[:range] = "bytes=#{context.http_response.body.size}-"
98
+ if retryable_body?(context)
99
+ if truncated_body?(error)
100
+ context.http_request.headers[:range] = "bytes=#{context.http_response.body.size}-"
101
+ else
102
+ case context.http_response.body
103
+ when RetryableManagedFile
104
+ # call rewind on the underlying file
105
+ context.http_response.body.instance_variable_get(:@file).rewind
106
+ else
107
+ raise NonRetryableStreamingError, error
108
+ end
109
+ end
89
110
  end
90
111
  end
91
112
  end