diff --git a/lib/google/apis/core/download.rb b/lib/google/apis/core/download.rb index de4f6bf9f..bc4a67423 100644 --- a/lib/google/apis/core/download.rb +++ b/lib/google/apis/core/download.rb @@ -67,12 +67,11 @@ module Google def execute_once(client, &block) request_header = header.dup apply_request_options(request_header) + download_offset = nil - check_if_rewind_needed = false if @offset > 0 logger.debug { sprintf('Resuming download from offset %d', @offset) } request_header[RANGE_HEADER] = sprintf('bytes=%d-', @offset) - check_if_rewind_needed = true end http_res = client.get(url.to_s, @@ -80,17 +79,24 @@ module Google header: request_header, follow_redirect: true) do |res, chunk| status = res.http_header.status_code.to_i - if OK_STATUS.include?(status) - if check_if_rewind_needed && status != 206 - # Oh no! Requested a chunk, but received the entire content - # Attempt to rewind the stream - @download_io.rewind - check_if_rewind_needed = false - end - # logger.debug { sprintf('Writing chunk (%d bytes, %d total)', chunk.length, bytes_read) } - @download_io.write(chunk) - @offset += chunk.length + next unless OK_STATUS.include?(status) + + 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 + chunk_index = @offset - (download_offset - chunk.bytesize) + next_chunk = chunk.byteslice(chunk_index..-1) + next if next_chunk.nil? end + + # logger.debug { sprintf('Writing chunk (%d bytes, %d total)', chunk.length, bytes_read) } + @download_io.write(next_chunk) + + @offset += next_chunk.bytesize end @download_io.flush