Skip to content

Commit

Permalink
Remove redundant HEAD request to determine range support, only use get
Browse files Browse the repository at this point in the history
  • Loading branch information
renbou committed Oct 17, 2021
1 parent 847004f commit 1e74d5b
Showing 1 changed file with 17 additions and 51 deletions.
68 changes: 17 additions & 51 deletions download.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,69 +61,43 @@ type (
}
)

// GetInfo returns URL info, and error if any.
func (d Download) GetInfo() (*Info, error) {

req, err := NewRequest(d.ctx, "HEAD", d.URL, d.Header)

if err != nil {
return nil, err
}

if res, err := d.Client.Do(req); err == nil && res.StatusCode == http.StatusOK {

return &Info{
Size: uint64(res.ContentLength),
Name: getNameFromHeader(res.Header.Get("content-disposition")),
Rangeable: res.Header.Get("accept-ranges") == "bytes",
}, nil
}

return &Info{}, nil
}

// getInfoFromGetRequest download the first byte of the file, to get content length in
// case of HEAD request not supported, and if partial content not supported so this will download the
// file in one chunk. it returns *Info, and error if any.
func (d *Download) getInfoFromGetRequest() (*Info, error) {
// Try downloading the first byte of the file using a range request.
// If the server supports range requests, then we'll extract the length info from content-range,
// Otherwise this just downloads the whole file in one go
func (d *Download) GetInfoOrDownload() (*Info, error) {

var (
err error
req *http.Request
res *http.Response
err error
dest *os.File
req *http.Request
res *http.Response
)

if req, err = NewRequest(d.ctx, "GET", d.URL, d.Header); err != nil {
if req, err = NewRequest(d.ctx, "GET", d.URL, append(d.Header, GotHeader{"Range", "bytes=0-0"})); err != nil {
return nil, err
}

req.Header.Set("Range", "bytes=0-1")

if res, err = d.Client.Do(req); err != nil {
return nil, err
}

defer res.Body.Close()

if res.StatusCode >= 300 {
return nil, fmt.Errorf("Response status code is not ok: %d", res.StatusCode)
}

dest, err := os.Create(d.Name())

if err != nil {
if dest, err = os.Create(d.Name()); err != nil {
return nil, err
}

defer dest.Close()

if _, err = io.Copy(dest, io.TeeReader(res.Body, d)); err != nil {
return nil, err
}

// Get content length from content-range response header,
// if content-range exists, that's mean partial content is supported.
if cr := res.Header.Get("content-range"); cr != "" && res.ContentLength == 2 {
// if content-range exists, that means partial content is supported.
if cr := res.Header.Get("content-range"); cr != "" && res.ContentLength == 1 {
l := strings.Split(cr, "/")
if len(l) == 2 {
if length, err := strconv.ParseUint(l[1], 10, 64); err == nil {
Expand Down Expand Up @@ -158,22 +132,14 @@ func (d *Download) Init() (err error) {
d.ctx = context.Background()
}

// Get and set URL size and partial content support state.
if d.info, err = d.GetInfo(); err != nil {
// Get URL info and partial content support state
if d.info, err = d.GetInfoOrDownload(); err != nil {
return err
}

// Maybe partial content not supported 😢!
if d.info.Rangeable == false || d.info.Size == 0 {

if d.info, err = d.getInfoFromGetRequest(); err != nil {
return err
}

// Partial content not supported, and the file downladed.
if d.info.Rangeable == false {
return nil
}
// Partial content not supported, and the file downladed.
if d.info.Rangeable == false {
return nil
}

// Set concurrency default.
Expand Down

0 comments on commit 1e74d5b

Please sign in to comment.