@@ -97,8 +97,8 @@ func (h *HTTPDownloader) fetchProxyFromEnv(scheme string) {
9797	}
9898}
9999
100- // DownloadFile download a  file with the progress  
101- func  (h  * HTTPDownloader ) DownloadFile ()  error  {
100+ // DownloadAsStream downloads the  file as stream  
101+ func  (h  * HTTPDownloader ) DownloadAsStream ( writer  io. Writer ) ( err   error )  {
102102	filepath , downloadURL , showProgress  :=  h .TargetFilePath , h .URL , h .ShowProgress 
103103	// Get the data 
104104	if  h .Context  ==  nil  {
@@ -115,7 +115,10 @@ func (h *HTTPDownloader) DownloadFile() error {
115115
116116	if  h .UserName  !=  ""  &&  h .Password  !=  ""  {
117117		req .SetBasicAuth (h .UserName , h .Password )
118+ 	} else  if  h .Password  !=  ""  {
119+ 		req .Header .Set ("Authorization" , "Bearer " + h .Password )
118120	}
121+ 
119122	var  tr  http.RoundTripper 
120123	if  h .RoundTripper  !=  nil  {
121124		tr  =  h .RoundTripper 
@@ -178,22 +181,32 @@ func (h *HTTPDownloader) DownloadFile() error {
178181		}
179182	}
180183
181- 	if  err  :=  os .MkdirAll (path .Dir (filepath ), os .FileMode (0755 )); err  !=  nil  {
182- 		return  err 
184+ 	h .progressIndicator .Writer  =  writer 
185+ 	h .progressIndicator .Init ()
186+ 
187+ 	// Write the body to file 
188+ 	_ , err  =  io .Copy (h .progressIndicator , resp .Body )
189+ 	return 
190+ }
191+ 
192+ // DownloadFile download a file with the progress 
193+ func  (h  * HTTPDownloader ) DownloadFile () (err  error ) {
194+ 	filepath  :=  h .TargetFilePath 
195+ 	if  err  =  os .MkdirAll (path .Dir (filepath ), os .FileMode (0755 )); err  !=  nil  {
196+ 		return 
183197	}
184198
185199	// Create the file 
186- 	out , err  :=  os .Create (filepath )
200+ 	var  out  io.WriteCloser 
201+ 	out , err  =  os .Create (filepath )
187202	if  err  !=  nil  {
188- 		_  =  out .Close ()
189- 		return  err 
203+ 		return 
190204	}
205+ 	defer  func () {
206+ 		_  =  out .Close ()
207+ 	}()
191208
192- 	h .progressIndicator .Writer  =  out 
193- 	h .progressIndicator .Init ()
194- 
195- 	// Write the body to file 
196- 	_ , err  =  io .Copy (h .progressIndicator , resp .Body )
209+ 	err  =  h .DownloadAsStream (out )
197210	return  err 
198211}
199212
@@ -269,6 +282,39 @@ func (c *ContinueDownloader) WithBasicAuth(username, password string) *ContinueD
269282	return  c 
270283}
271284
285+ // DownloadWithContinueAsStream downloads the files continuously 
286+ func  (c  * ContinueDownloader ) DownloadWithContinueAsStream (targetURL  string , output  io.Writer , index , continueAt , end  int64 , showProgress  bool ) (err  error ) {
287+ 	c .downloader  =  & HTTPDownloader {
288+ 		URL :                targetURL ,
289+ 		ShowProgress :       showProgress ,
290+ 		NoProxy :            c .noProxy ,
291+ 		RoundTripper :       c .roundTripper ,
292+ 		InsecureSkipVerify : c .insecureSkipVerify ,
293+ 		UserName :           c .UserName ,
294+ 		Password :           c .Password ,
295+ 		Context :            c .Context ,
296+ 		Timeout :            c .Timeout ,
297+ 	}
298+ 	if  index  >=  0  {
299+ 		c .downloader .Title  =  fmt .Sprintf ("Downloading part %d" , index )
300+ 	}
301+ 
302+ 	if  continueAt  >=  0  {
303+ 		c .downloader .Header  =  make (map [string ]string , 1 )
304+ 
305+ 		if  end  >  continueAt  {
306+ 			c .downloader .Header ["Range" ] =  fmt .Sprintf ("bytes=%d-%d" , continueAt , end )
307+ 		} else  {
308+ 			c .downloader .Header ["Range" ] =  fmt .Sprintf ("bytes=%d-" , continueAt )
309+ 		}
310+ 	}
311+ 
312+ 	if  err  =  c .downloader .DownloadAsStream (output ); err  !=  nil  {
313+ 		err  =  fmt .Errorf ("cannot download from %s, error: %v" , targetURL , err )
314+ 	}
315+ 	return 
316+ }
317+ 
272318// DownloadWithContinue downloads the files continuously 
273319func  (c  * ContinueDownloader ) DownloadWithContinue (targetURL , output  string , index , continueAt , end  int64 , showProgress  bool ) (err  error ) {
274320	c .downloader  =  & HTTPDownloader {
@@ -303,6 +349,45 @@ func (c *ContinueDownloader) DownloadWithContinue(targetURL, output string, inde
303349	return 
304350}
305351
352+ // DetectSizeWithRoundTripperAndAuthStream returns the size of target resource 
353+ func  DetectSizeWithRoundTripperAndAuthStream (targetURL  string , output  io.Writer , showProgress , noProxy , insecureSkipVerify  bool ,
354+ 	roundTripper  http.RoundTripper , username , password  string , timeout  time.Duration ) (total  int64 , rangeSupport  bool , err  error ) {
355+ 	downloader  :=  HTTPDownloader {
356+ 		URL :                targetURL ,
357+ 		ShowProgress :       showProgress ,
358+ 		RoundTripper :       roundTripper ,
359+ 		NoProxy :            false , // below HTTP request does not need proxy 
360+ 		InsecureSkipVerify : insecureSkipVerify ,
361+ 		UserName :           username ,
362+ 		Password :           password ,
363+ 		Timeout :            timeout ,
364+ 	}
365+ 
366+ 	var  detectOffset  int64 
367+ 	var  lenErr  error 
368+ 
369+ 	detectOffset  =  2 
370+ 	downloader .Header  =  make (map [string ]string , 1 )
371+ 	downloader .Header ["Range" ] =  fmt .Sprintf ("bytes=%d-" , detectOffset )
372+ 
373+ 	downloader .PreStart  =  func (resp  * http.Response ) bool  {
374+ 		rangeSupport  =  resp .StatusCode  ==  http .StatusPartialContent 
375+ 		contentLen  :=  resp .Header .Get ("Content-Length" )
376+ 		if  total , lenErr  =  strconv .ParseInt (contentLen , 10 , 0 ); lenErr  ==  nil  {
377+ 			total  +=  detectOffset 
378+ 		} else  {
379+ 			rangeSupport  =  false 
380+ 		}
381+ 		//  always return false because we just want to get the header from response 
382+ 		return  false 
383+ 	}
384+ 
385+ 	if  err  =  downloader .DownloadAsStream (output ); err  !=  nil  ||  lenErr  !=  nil  {
386+ 		err  =  fmt .Errorf ("cannot download from %s, response error: %v, content length error: %v" , targetURL , err , lenErr )
387+ 	}
388+ 	return 
389+ }
390+ 
306391// DetectSizeWithRoundTripperAndAuth returns the size of target resource 
307392func  DetectSizeWithRoundTripperAndAuth (targetURL , output  string , showProgress , noProxy , insecureSkipVerify  bool ,
308393	roundTripper  http.RoundTripper , username , password  string , timeout  time.Duration ) (total  int64 , rangeSupport  bool , err  error ) {
0 commit comments