diff --git a/kadai3/imura81gt/rget/cmd/rget/main_test.go b/kadai3/imura81gt/rget/cmd/rget/main_test.go new file mode 100644 index 0000000..097f27a --- /dev/null +++ b/kadai3/imura81gt/rget/cmd/rget/main_test.go @@ -0,0 +1,5 @@ +package main + +import "testing" + +func TestMain(t *testing.T) {} diff --git a/kadai3/imura81gt/rget/rget.go b/kadai3/imura81gt/rget/rget.go index 974b904..4f3adcb 100644 --- a/kadai3/imura81gt/rget/rget.go +++ b/kadai3/imura81gt/rget/rget.go @@ -40,7 +40,7 @@ type Units []Unit func Run(option Option) { fmt.Printf("%+v\n", option) - err := option.contentLength() + err := option.checkingHeaders() if err != nil { fmt.Errorf("%s", err) } @@ -66,8 +66,7 @@ func Run(option Option) { } -func (o *Option) contentLength() error { - //resp, err := http.Head(url) +func (o *Option) checkingHeaders() error { resp, err := http.Head(o.URL) if err != nil { return err @@ -77,20 +76,51 @@ func (o *Option) contentLength() error { err := fmt.Errorf("%s URL cannot support Ranges Requests", o.URL) return err } + if resp.Header["Accept-Ranges"][0] == "none" { err := fmt.Errorf("%s cannot support Ranges Requests", o.URL) return err } + if resp.ContentLength == 0 { err := fmt.Errorf("%s size is %s", o.URL, resp.Header["Content-Length"][0]) return err } + redirectURL := resp.Request.URL.String() + if err != nil { + return err + } + o.ContentLength = resp.ContentLength - //return resp.ContentLength, nil + + // keep the redirect URL that accept Ranges Requests because some mirror sites may deny. + // TODO: redirectURL should set by Unit separately. + if o.URL != redirectURL { + o.URL = redirectURL + } + return err } +func (o *Option) acceptRangesHeaderCheck() (string, error) { + resp, err := http.Head(o.URL) + redirectURL := resp.Request.URL.String() + if err != nil { + return redirectURL, err + } + + if resp.Header.Get("Accept-Ranges") == "" { + err := fmt.Errorf("%s URL cannot support Ranges Requests", o.URL) + return redirectURL, err + } + if resp.Header["Accept-Ranges"][0] == "none" { + err := fmt.Errorf("%s cannot support Ranges Requests", o.URL) + return redirectURL, err + } + return redirectURL, nil +} + //func divide(contentLength int64, concurrency int) Units { func (o *Option) divide() { var units []Unit @@ -161,6 +191,8 @@ func (o *Option) downloadWithContext( req.Header.Set("Range", byteRange) client := http.DefaultClient + // TODO: should check resp.StatusCode. + // client.Do cannot seems to return the err when statusCode is 50x etc. resp, err := client.Do(req) if err != nil { fmt.Printf("client err: %s", err)