Skip to content

Corrupted contents when downloading on top of wrong file #21

@glyn

Description

@glyn

Grab looked like a good fit for a project I'm working on so I gave it a spin. I found that it downloaded a file perfectly and when asked to download the same file again managed to avoid downloading all the bytes again, which was just what I was looking for.

I then overwrote the downloaded file with completely different contents and then downloaded again using grab. The message:

  206 Partial Content

was emitted and the download was apparently successful. The downloaded file even had the same number of bytes as the original, but unfortunately the contents were corrupted.

Fortunately, this problem is easily reproduced using the example program in the README:

$ go run main.go
Downloading http://www.golang-book.com/public/pdf/gobook.pdf...
  200 OK
Download saved to ./gobook.pdf
$ mv gobook.pdf gobook.pdf.good
$ cp main.go gobook.pdf
$ go run main.go
Downloading http://www.golang-book.com/public/pdf/gobook.pdf...
  206 Partial Content
Download saved to ./gobook.pdf
$ diff gobook.pdf gobook.pdf.good
Binary files gobook.pdf and gobook.pdf.good differ
$ ls -l
total 11320
-rw-r--r--  1 gnormington  staff  2893557  1 Jan  1970 gobook.pdf
-rw-r--r--  1 gnormington  staff  2893557  1 Jan  1970 gobook.pdf.good
-rw-r--r--  1 gnormington  staff     1139  3 Nov 11:10 main.go

The environment is go version go1.9.2 darwin/amd64 on macOS 10.13.1.

In case the README changes, the contents of main.go above is:

package main

import (
	"fmt"
	"os"
	"time"

	"github.com/cavaliercoder/grab"
)

func main() {
	// create client
	client := grab.NewClient()
	req, _ := grab.NewRequest(".", "http://www.golang-book.com/public/pdf/gobook.pdf")

	// start download
	fmt.Printf("Downloading %v...\n", req.URL())
	resp := client.Do(req)
	fmt.Printf("  %v\n", resp.HTTPResponse.Status)

	// start UI loop
	t := time.NewTicker(500 * time.Millisecond)
	defer t.Stop()

Loop:
	for {
		select {
		case <-t.C:
			fmt.Printf("  transferred %v / %v bytes (%.2f%%)\n",
				resp.BytesComplete(),
				resp.Size,
				100*resp.Progress())

		case <-resp.Done:
			// download is complete
			break Loop
		}
	}

	// check for errors
	if err := resp.Err(); err != nil {
		fmt.Fprintf(os.Stderr, "Download failed: %v\n", err)
		os.Exit(1)
	}

	fmt.Printf("Download saved to ./%v \n", resp.Filename)

	// Output:
	// Downloading http://www.golang-book.com/public/pdf/gobook.pdf...
	//   200 OK
	//   transferred 42970 / 2893557 bytes (1.49%)
	//   transferred 1207474 / 2893557 bytes (41.73%)
	//   transferred 2758210 / 2893557 bytes (95.32%)
	// Download saved to ./gobook.pdf
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions