Merge pull request #593 from janko-m/avoid-rewinding-on-full-response

Recover from non-Ranged responses without rewinding
This commit is contained in:
Steve Bazyl 2017-08-03 11:49:29 -06:00 committed by GitHub
commit 8e701f7f41
1 changed files with 18 additions and 12 deletions

View File

@ -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