Skip to content

Commit d375e85

Browse files
authored
feat: support to download file with basic auth (#487)
Co-authored-by: Rick <[email protected]>
1 parent de7232b commit d375e85

File tree

3 files changed

+43
-8
lines changed

3 files changed

+43
-8
lines changed

cmd/get.go

+6
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ type downloadOption struct {
100100
MaxAttempts int
101101
AcceptPreRelease bool
102102
RoundTripper http.RoundTripper
103+
Username string
104+
Password string
103105
Magnet bool
104106
Force bool
105107
Mod int
@@ -143,6 +145,8 @@ func (o *downloadOption) addDownloadFlags(flags *pflag.FlagSet) {
143145
flags.IntVarP(&o.Thread, "thread", "t", viper.GetInt("thread"),
144146
`Download file with multi-threads. It only works when its value is bigger than 1`)
145147
flags.BoolVarP(&o.NoProxy, "no-proxy", "", viper.GetBool("no-proxy"), "Indicate no HTTP proxy taken")
148+
flags.StringVarP(&o.Username, "username", "u", "", "The username for the HTTP basic auth")
149+
flags.StringVarP(&o.Password, "password", "p", "", "The password for the HTTP basic auth")
146150
}
147151

148152
func (o *downloadOption) fetch() (err error) {
@@ -322,6 +326,7 @@ func (o *downloadOption) runE(cmd *cobra.Command, args []string) (err error) {
322326
downloader.WithoutProxy(o.NoProxy).
323327
WithRoundTripper(o.RoundTripper).
324328
WithInsecureSkipVerify(o.SkipTLS).
329+
WithBasicAuth(o.Username, o.Password).
325330
WithTimeout(o.Timeout)
326331
err = downloader.DownloadWithContinue(targetURL, o.Output, o.ContinueAt, -1, 0, o.ShowProgress)
327332
} else {
@@ -332,6 +337,7 @@ func (o *downloadOption) runE(cmd *cobra.Command, args []string) (err error) {
332337
WithoutProxy(o.NoProxy).
333338
WithRoundTripper(o.RoundTripper).
334339
WithInsecureSkipVerify(o.SkipTLS).
340+
WithBasicAuth(o.Username, o.Password).
335341
WithTimeout(o.Timeout)
336342
err = downloader.Download(targetURL, o.Output, o.Thread)
337343
}

pkg/net/http.go

+22-3
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ func DownloadFileWithMultipleThreadKeepParts(targetURL, targetFilePath string, t
219219
type ContinueDownloader struct {
220220
downloader *HTTPDownloader
221221

222+
UserName, Password string
222223
Timeout time.Duration
223224
Context context.Context
224225
roundTripper http.RoundTripper
@@ -261,6 +262,13 @@ func (c *ContinueDownloader) WithTimeout(timeout time.Duration) *ContinueDownloa
261262
return c
262263
}
263264

265+
// WithBasicAuth sets the basic auth
266+
func (c *ContinueDownloader) WithBasicAuth(username, password string) *ContinueDownloader {
267+
c.UserName = username
268+
c.Password = password
269+
return c
270+
}
271+
264272
// DownloadWithContinue downloads the files continuously
265273
func (c *ContinueDownloader) DownloadWithContinue(targetURL, output string, index, continueAt, end int64, showProgress bool) (err error) {
266274
c.downloader = &HTTPDownloader{
@@ -270,6 +278,8 @@ func (c *ContinueDownloader) DownloadWithContinue(targetURL, output string, inde
270278
NoProxy: c.noProxy,
271279
RoundTripper: c.roundTripper,
272280
InsecureSkipVerify: c.insecureSkipVerify,
281+
UserName: c.UserName,
282+
Password: c.Password,
273283
Context: c.Context,
274284
Timeout: c.Timeout,
275285
}
@@ -293,16 +303,18 @@ func (c *ContinueDownloader) DownloadWithContinue(targetURL, output string, inde
293303
return
294304
}
295305

296-
// DetectSizeWithRoundTripper returns the size of target resource
297-
func DetectSizeWithRoundTripper(targetURL, output string, showProgress, noProxy, insecureSkipVerify bool,
298-
roundTripper http.RoundTripper, timeout time.Duration) (total int64, rangeSupport bool, err error) {
306+
// DetectSizeWithRoundTripperAndAuth returns the size of target resource
307+
func DetectSizeWithRoundTripperAndAuth(targetURL, output string, showProgress, noProxy, insecureSkipVerify bool,
308+
roundTripper http.RoundTripper, username, password string, timeout time.Duration) (total int64, rangeSupport bool, err error) {
299309
downloader := HTTPDownloader{
300310
TargetFilePath: output,
301311
URL: targetURL,
302312
ShowProgress: showProgress,
303313
RoundTripper: roundTripper,
304314
NoProxy: false, // below HTTP request does not need proxy
305315
InsecureSkipVerify: insecureSkipVerify,
316+
UserName: username,
317+
Password: password,
306318
Timeout: timeout,
307319
}
308320

@@ -331,6 +343,13 @@ func DetectSizeWithRoundTripper(targetURL, output string, showProgress, noProxy,
331343
return
332344
}
333345

346+
// DetectSizeWithRoundTripper returns the size of target resource
347+
// Deprecated, use DetectSizeWithRoundTripperAndAuth instead
348+
func DetectSizeWithRoundTripper(targetURL, output string, showProgress, noProxy, insecureSkipVerify bool,
349+
roundTripper http.RoundTripper, timeout time.Duration) (total int64, rangeSupport bool, err error) {
350+
return DetectSizeWithRoundTripperAndAuth(targetURL, output, showProgress, noProxy, insecureSkipVerify, roundTripper, "", "", timeout)
351+
}
352+
334353
// ParseSuggestedFilename parse the filename from resp header,More details from https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition
335354
func ParseSuggestedFilename(header http.Header, filepath string) (filename string) {
336355
if disposition, ok := header["Content-Disposition"]; ok && len(disposition) >= 1 {

pkg/net/multi_thread.go

+15-5
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@ type MultiThreadDownloader struct {
1616
keepParts, showProgress bool
1717
insecureSkipVerify bool
1818

19-
roundTripper http.RoundTripper
20-
suggestedFilename string
21-
timeout time.Duration
19+
username, password string
20+
roundTripper http.RoundTripper
21+
suggestedFilename string
22+
timeout time.Duration
2223
}
2324

2425
// GetSuggestedFilename returns the suggested filename
@@ -62,13 +63,20 @@ func (d *MultiThreadDownloader) WithRoundTripper(roundTripper http.RoundTripper)
6263
return d
6364
}
6465

66+
// WithBasicAuth sets the basic auth
67+
func (d *MultiThreadDownloader) WithBasicAuth(username, password string) *MultiThreadDownloader {
68+
d.username = username
69+
d.password = password
70+
return d
71+
}
72+
6573
// Download starts to download the target URL
6674
func (d *MultiThreadDownloader) Download(targetURL, targetFilePath string, thread int) (err error) {
6775
// get the total size of the target file
6876
var total int64
6977
var rangeSupport bool
70-
if total, rangeSupport, err = DetectSizeWithRoundTripper(targetURL, targetFilePath, d.showProgress,
71-
d.noProxy, d.insecureSkipVerify, d.roundTripper, d.timeout); rangeSupport && err != nil {
78+
if total, rangeSupport, err = DetectSizeWithRoundTripperAndAuth(targetURL, targetFilePath, d.showProgress,
79+
d.noProxy, d.insecureSkipVerify, d.roundTripper, d.username, d.password, d.timeout); rangeSupport && err != nil {
7280
return
7381
}
7482

@@ -120,6 +128,7 @@ func (d *MultiThreadDownloader) Download(targetURL, targetFilePath string, threa
120128
downloader.WithoutProxy(d.noProxy).
121129
WithRoundTripper(d.roundTripper).
122130
WithInsecureSkipVerify(d.insecureSkipVerify).
131+
WithBasicAuth(d.username, d.password).
123132
WithContext(ctx).WithTimeout(d.timeout)
124133
if downloadErr := downloader.DownloadWithContinue(targetURL, output,
125134
int64(index), start, end, d.showProgress); downloadErr != nil {
@@ -173,6 +182,7 @@ func (d *MultiThreadDownloader) Download(targetURL, targetFilePath string, threa
173182
downloader.WithRoundTripper(d.roundTripper)
174183
downloader.WithInsecureSkipVerify(d.insecureSkipVerify)
175184
downloader.WithTimeout(d.timeout)
185+
downloader.WithBasicAuth(d.username, d.password)
176186
err = downloader.DownloadWithContinue(targetURL, targetFilePath, -1, 0, 0, true)
177187
d.suggestedFilename = downloader.GetSuggestedFilename()
178188
}

0 commit comments

Comments
 (0)