Skip to content

Commit

Permalink
feat: support to download file with basic auth
Browse files Browse the repository at this point in the history
  • Loading branch information
LinuxSuRen committed Dec 25, 2024
1 parent de7232b commit 81a5912
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 8 deletions.
6 changes: 6 additions & 0 deletions cmd/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ type downloadOption struct {
MaxAttempts int
AcceptPreRelease bool
RoundTripper http.RoundTripper
Username string
Password string
Magnet bool
Force bool
Mod int
Expand Down Expand Up @@ -143,6 +145,8 @@ func (o *downloadOption) addDownloadFlags(flags *pflag.FlagSet) {
flags.IntVarP(&o.Thread, "thread", "t", viper.GetInt("thread"),
`Download file with multi-threads. It only works when its value is bigger than 1`)
flags.BoolVarP(&o.NoProxy, "no-proxy", "", viper.GetBool("no-proxy"), "Indicate no HTTP proxy taken")
flags.StringVarP(&o.Username, "username", "u", "", "The username for the HTTP basic auth")
flags.StringVarP(&o.Password, "password", "p", "", "The password for the HTTP basic auth")
}

func (o *downloadOption) fetch() (err error) {
Expand Down Expand Up @@ -322,6 +326,7 @@ func (o *downloadOption) runE(cmd *cobra.Command, args []string) (err error) {
downloader.WithoutProxy(o.NoProxy).
WithRoundTripper(o.RoundTripper).
WithInsecureSkipVerify(o.SkipTLS).
WithBasicAuth(o.Username, o.Password).
WithTimeout(o.Timeout)
err = downloader.DownloadWithContinue(targetURL, o.Output, o.ContinueAt, -1, 0, o.ShowProgress)
} else {
Expand All @@ -332,6 +337,7 @@ func (o *downloadOption) runE(cmd *cobra.Command, args []string) (err error) {
WithoutProxy(o.NoProxy).
WithRoundTripper(o.RoundTripper).
WithInsecureSkipVerify(o.SkipTLS).
WithBasicAuth(o.Username, o.Password).
WithTimeout(o.Timeout)
err = downloader.Download(targetURL, o.Output, o.Thread)
}
Expand Down
25 changes: 22 additions & 3 deletions pkg/net/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ func DownloadFileWithMultipleThreadKeepParts(targetURL, targetFilePath string, t
type ContinueDownloader struct {
downloader *HTTPDownloader

UserName, Password string
Timeout time.Duration
Context context.Context
roundTripper http.RoundTripper
Expand Down Expand Up @@ -261,6 +262,13 @@ func (c *ContinueDownloader) WithTimeout(timeout time.Duration) *ContinueDownloa
return c
}

// WithBasicAuth sets the basic auth
func (c *ContinueDownloader) WithBasicAuth(username, password string) *ContinueDownloader {
c.UserName = username
c.Password = password
return c
}

// DownloadWithContinue downloads the files continuously
func (c *ContinueDownloader) DownloadWithContinue(targetURL, output string, index, continueAt, end int64, showProgress bool) (err error) {
c.downloader = &HTTPDownloader{
Expand All @@ -270,6 +278,8 @@ func (c *ContinueDownloader) DownloadWithContinue(targetURL, output string, inde
NoProxy: c.noProxy,
RoundTripper: c.roundTripper,
InsecureSkipVerify: c.insecureSkipVerify,
UserName: c.UserName,
Password: c.Password,
Context: c.Context,
Timeout: c.Timeout,
}
Expand All @@ -293,16 +303,18 @@ func (c *ContinueDownloader) DownloadWithContinue(targetURL, output string, inde
return
}

// DetectSizeWithRoundTripper returns the size of target resource
func DetectSizeWithRoundTripper(targetURL, output string, showProgress, noProxy, insecureSkipVerify bool,
roundTripper http.RoundTripper, timeout time.Duration) (total int64, rangeSupport bool, err error) {
// DetectSizeWithRoundTripperAndAuth returns the size of target resource
func DetectSizeWithRoundTripperAndAuth(targetURL, output string, showProgress, noProxy, insecureSkipVerify bool,
roundTripper http.RoundTripper, username, password string, timeout time.Duration) (total int64, rangeSupport bool, err error) {
downloader := HTTPDownloader{
TargetFilePath: output,
URL: targetURL,
ShowProgress: showProgress,
RoundTripper: roundTripper,
NoProxy: false, // below HTTP request does not need proxy
InsecureSkipVerify: insecureSkipVerify,
UserName: username,
Password: password,
Timeout: timeout,
}

Expand Down Expand Up @@ -331,6 +343,13 @@ func DetectSizeWithRoundTripper(targetURL, output string, showProgress, noProxy,
return
}

// DetectSizeWithRoundTripper returns the size of target resource
// Deprecated, use DetectSizeWithRoundTripperAndAuth instead
func DetectSizeWithRoundTripper(targetURL, output string, showProgress, noProxy, insecureSkipVerify bool,
roundTripper http.RoundTripper, timeout time.Duration) (total int64, rangeSupport bool, err error) {
return DetectSizeWithRoundTripperAndAuth(targetURL, output, showProgress, noProxy, insecureSkipVerify, roundTripper, "", "", timeout)
}

// ParseSuggestedFilename parse the filename from resp header,More details from https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition
func ParseSuggestedFilename(header http.Header, filepath string) (filename string) {
if disposition, ok := header["Content-Disposition"]; ok && len(disposition) >= 1 {
Expand Down
20 changes: 15 additions & 5 deletions pkg/net/multi_thread.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ type MultiThreadDownloader struct {
keepParts, showProgress bool
insecureSkipVerify bool

roundTripper http.RoundTripper
suggestedFilename string
timeout time.Duration
username, password string
roundTripper http.RoundTripper
suggestedFilename string
timeout time.Duration
}

// GetSuggestedFilename returns the suggested filename
Expand Down Expand Up @@ -62,13 +63,20 @@ func (d *MultiThreadDownloader) WithRoundTripper(roundTripper http.RoundTripper)
return d
}

// WithBasicAuth sets the basic auth
func (d *MultiThreadDownloader) WithBasicAuth(username, password string) *MultiThreadDownloader {
d.username = username
d.password = password
return d

Check warning on line 70 in pkg/net/multi_thread.go

View check run for this annotation

Codecov / codecov/patch

pkg/net/multi_thread.go#L67-L70

Added lines #L67 - L70 were not covered by tests
}

// Download starts to download the target URL
func (d *MultiThreadDownloader) Download(targetURL, targetFilePath string, thread int) (err error) {
// get the total size of the target file
var total int64
var rangeSupport bool
if total, rangeSupport, err = DetectSizeWithRoundTripper(targetURL, targetFilePath, d.showProgress,
d.noProxy, d.insecureSkipVerify, d.roundTripper, d.timeout); rangeSupport && err != nil {
if total, rangeSupport, err = DetectSizeWithRoundTripperAndAuth(targetURL, targetFilePath, d.showProgress,
d.noProxy, d.insecureSkipVerify, d.roundTripper, d.username, d.password, d.timeout); rangeSupport && err != nil {
return
}

Expand Down Expand Up @@ -120,6 +128,7 @@ func (d *MultiThreadDownloader) Download(targetURL, targetFilePath string, threa
downloader.WithoutProxy(d.noProxy).
WithRoundTripper(d.roundTripper).
WithInsecureSkipVerify(d.insecureSkipVerify).
WithBasicAuth(d.username, d.password).
WithContext(ctx).WithTimeout(d.timeout)
if downloadErr := downloader.DownloadWithContinue(targetURL, output,
int64(index), start, end, d.showProgress); downloadErr != nil {
Expand Down Expand Up @@ -173,6 +182,7 @@ func (d *MultiThreadDownloader) Download(targetURL, targetFilePath string, threa
downloader.WithRoundTripper(d.roundTripper)
downloader.WithInsecureSkipVerify(d.insecureSkipVerify)
downloader.WithTimeout(d.timeout)
downloader.WithBasicAuth(d.username, d.password)
err = downloader.DownloadWithContinue(targetURL, targetFilePath, -1, 0, 0, true)
d.suggestedFilename = downloader.GetSuggestedFilename()
}
Expand Down

0 comments on commit 81a5912

Please sign in to comment.