You only have one goroutine downloading chunks.
Line 64:
go download(*download_url, chunks, offset, file)
What you probably want is:
for i := 0; i < *threads; i++ {
go download(*download_url, chunks, offset, file)
}
This will download *threads
chunks at once.
After you have concurrency working, you will probably notice that line 29 doesn't work how you intend. If chunk 1 finishes before chunk 2, the parts will be written out of order. You may want to instead use http://golang.org/pkg/os/#File.WriteAt.
You also have two problems with your Range header.
- You don't download the remainder. If the file size is 3002 and you have 3 threads, it will request 0-1000, 1000-2000, 2000-3000 and the last 2 bytes will never be downloaded.
- Byte ranges are inclusive. that means you are (as you can see in the previous example) downloading some bytes twice. Byte 1000 and 2000 are requested twice. Of course, as long as you write to the correct locations, you shouldn't have too much of a problem.
Number two is easy enough to fix by changing line 19 from
req.Header.Set("Range: ", fmt.Sprintf("bytes=%d-%d", current, current+offset))
to this
req.Header.Set("Range: ", fmt.Sprintf("bytes=%d-%d", current, current+offset-1))
For more information on the Range header, I suggest reading Section 14.35 in RFC2616