class Aws::S3::Plugins::StreamingRetry::Handler
def add_event_listeners(context, target)
def add_event_listeners(context, target) context.http_response.on_headers(200..299) do case context.http_response.body when Seahorse::Client::BlockIO then context.http_response.body = RetryableBlockIO.new(context.http_response.body) when Seahorse::Client::ManagedFile then context.http_response.body = RetryableManagedFile.new(context.http_response.body) end end context.http_response.on_headers(400..599) do context.http_response.body = StringIO.new # something to write the error to end context.http_response.on_success(200..299) do body = context.http_response.body if body.is_a?(RetryableManagedFile) && body.open? body.close end end context.http_response.on_error do |error| if retryable_body?(context) if truncated_body?(error) context.http_request.headers[:range] = "bytes=#{context.http_response.body.size}-" else case context.http_response.body when RetryableManagedFile # call rewind on the underlying file context.http_response.body.instance_variable_get(:@file).rewind else raise NonRetryableStreamingError, error end end end end end
def call(context)
def call(context) target = context.params[:response_target] || context[:response_target] # retry is only supported when range is NOT set on the initial request if supported_target?(target) && !context.params[:range] add_event_listeners(context, target) end @handler.call(context) end
def retryable_body?(context)
def retryable_body?(context) context.http_response.body.is_a?(RetryableBlockIO) || context.http_response.body.is_a?(RetryableManagedFile) end
def supported_target?(target)
def supported_target?(target) case target when Proc, String, Pathname then true else false end end
def truncated_body?(error)
def truncated_body?(error) error.is_a?(Seahorse::Client::NetworkingError) && error.original_error.is_a?( Seahorse::Client::NetHttp::Handler::TruncatedBodyError ) end