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