Merge pull request #593 from janko-m/avoid-rewinding-on-full-response
Recover from non-Ranged responses without rewinding
This commit is contained in:
commit
8e701f7f41
|
@ -67,12 +67,11 @@ module Google
|
||||||
def execute_once(client, &block)
|
def execute_once(client, &block)
|
||||||
request_header = header.dup
|
request_header = header.dup
|
||||||
apply_request_options(request_header)
|
apply_request_options(request_header)
|
||||||
|
download_offset = nil
|
||||||
|
|
||||||
check_if_rewind_needed = false
|
|
||||||
if @offset > 0
|
if @offset > 0
|
||||||
logger.debug { sprintf('Resuming download from offset %d', @offset) }
|
logger.debug { sprintf('Resuming download from offset %d', @offset) }
|
||||||
request_header[RANGE_HEADER] = sprintf('bytes=%d-', @offset)
|
request_header[RANGE_HEADER] = sprintf('bytes=%d-', @offset)
|
||||||
check_if_rewind_needed = true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
http_res = client.get(url.to_s,
|
http_res = client.get(url.to_s,
|
||||||
|
@ -80,17 +79,24 @@ module Google
|
||||||
header: request_header,
|
header: request_header,
|
||||||
follow_redirect: true) do |res, chunk|
|
follow_redirect: true) do |res, chunk|
|
||||||
status = res.http_header.status_code.to_i
|
status = res.http_header.status_code.to_i
|
||||||
if OK_STATUS.include?(status)
|
next unless OK_STATUS.include?(status)
|
||||||
if check_if_rewind_needed && status != 206
|
|
||||||
|
download_offset ||= (status == 206 ? @offset : 0)
|
||||||
|
download_offset += chunk.bytesize
|
||||||
|
|
||||||
|
if download_offset - chunk.bytesize == @offset
|
||||||
|
next_chunk = chunk
|
||||||
|
else
|
||||||
# Oh no! Requested a chunk, but received the entire content
|
# Oh no! Requested a chunk, but received the entire content
|
||||||
# Attempt to rewind the stream
|
chunk_index = @offset - (download_offset - chunk.bytesize)
|
||||||
@download_io.rewind
|
next_chunk = chunk.byteslice(chunk_index..-1)
|
||||||
check_if_rewind_needed = false
|
next if next_chunk.nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
# logger.debug { sprintf('Writing chunk (%d bytes, %d total)', chunk.length, bytes_read) }
|
# logger.debug { sprintf('Writing chunk (%d bytes, %d total)', chunk.length, bytes_read) }
|
||||||
@download_io.write(chunk)
|
@download_io.write(next_chunk)
|
||||||
@offset += chunk.length
|
|
||||||
end
|
@offset += next_chunk.bytesize
|
||||||
end
|
end
|
||||||
|
|
||||||
@download_io.flush
|
@download_io.flush
|
||||||
|
|
Loading…
Reference in New Issue