@@ -30,37 +30,47 @@ const (
3030 defaultMaxRetry = 2
3131)
3232
33- // downloadFile is an internal helper that downloads a file to the provided file path
34- func DownloadFile (filepath string , url string , timeout time.Duration ) error {
35- var (
36- resp * http.Response
37- err error
38- _timeout time.Duration = timeout
39- )
40-
41- if _timeout == 0 {
42- _timeout = defaultTimeout
33+ func DownloadFile (filepath string , url string , timeout time.Duration ) (err error ) {
34+ if timeout == 0 {
35+ timeout = defaultTimeout
4336 }
4437
45- client := & http.Client {Timeout : _timeout }
38+ client := & http.Client {Timeout : timeout }
4639
47- resp , err = client . Get ( url )
40+ file , err := os . Create ( filepath )
4841 if err != nil {
49- for retry := 0 ; retry < defaultMaxRetry && os .IsTimeout (err ); retry ++ {
50- resp , err = client .Get (url )
51- }
42+ return err
43+ }
44+ defer file .Close ()
45+
46+ err = downloadFile (client , url , file )
47+
48+ for retry := 0 ; retry < defaultMaxRetry && os .IsTimeout (err ); retry ++ {
49+ _ , err = file .Seek (0 , io .SeekStart )
5250 if err != nil {
5351 return err
5452 }
53+
54+ err = downloadFile (client , url , file )
5555 }
56- defer resp .Body .Close ()
5756
58- out , err := os .Create (filepath )
57+ return
58+ }
59+
60+ // client.Get returns on receiving HTTP headers and we stream the HTTP data to the output file.
61+ // A timeout will interrupt io.Copy.
62+ func downloadFile (client * http.Client , url string , file * os.File ) (err error ) {
63+ var (
64+ resp * http.Response
65+ )
66+
67+ resp , err = client .Get (url )
5968 if err != nil {
6069 return err
6170 }
62- defer out .Close ()
71+ defer resp .Body .Close ()
72+
73+ _ , err = io .Copy (file , resp .Body )
6374
64- _ , err = io .Copy (out , resp .Body )
65- return err
75+ return
6676}
0 commit comments