From 82b6ebd6f1b223dab60557430e3bd571c1dec138 Mon Sep 17 00:00:00 2001 From: liwei Date: Tue, 30 Apr 2024 17:36:50 +0800 Subject: [PATCH] feat: support proxy from system env --- go.mod | 1 + go.sum | 2 + internal/controller/controller.go | 6 +- internal/protocol/bt/fetcher.go | 2 +- internal/protocol/bt/fetcher_test.go | 2 +- internal/protocol/http/fetcher.go | 3 +- internal/protocol/http/fetcher_test.go | 7 +- internal/test/httptest.go | 5 ++ pkg/base/model.go | 86 ++++++++++++++++++++++++ pkg/download/downloader.go | 10 +-- pkg/download/downloader_test.go | 71 ++++++++++++------- pkg/download/engine/engine.go | 6 +- pkg/download/engine/inject/xhr/module.go | 15 +++-- pkg/download/extension.go | 4 +- pkg/download/model.go | 44 +----------- pkg/rest/api.go | 4 +- pkg/rest/server_test.go | 4 +- 17 files changed, 175 insertions(+), 97 deletions(-) diff --git a/go.mod b/go.mod index 0c25a2b6..c4965679 100644 --- a/go.mod +++ b/go.mod @@ -69,6 +69,7 @@ require ( github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-ieproxy v0.0.11 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mschoch/smat v0.2.0 // indirect github.com/pion/datachannel v1.5.5 // indirect diff --git a/go.sum b/go.sum index ae4980b3..66aceab3 100644 --- a/go.sum +++ b/go.sum @@ -270,6 +270,8 @@ github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A= github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-ieproxy v0.0.11 h1:MQ/5BuGSgDAHZOJe6YY80IF2UVCfGkwfo6AeD7HtHYo= +github.com/mattn/go-ieproxy v0.0.11/go.mod h1:/NsJd+kxZBmjMc5hrJCKMbP57B84rvq9BiDRbtO9AS0= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= diff --git a/internal/controller/controller.go b/internal/controller/controller.go index ded1ea2d..15eb299d 100644 --- a/internal/controller/controller.go +++ b/internal/controller/controller.go @@ -1,14 +1,14 @@ package controller import ( - "net/url" + "github.com/GopeedLab/gopeed/pkg/base" "os" "path/filepath" ) type Controller struct { - GetConfig func(v any) bool - ProxyUrl *url.URL + GetConfig func(v any) bool + ProxyConfig *base.DownloaderProxyConfig FileController //ContextDialer() (proxy.Dialer, error) } diff --git a/internal/protocol/bt/fetcher.go b/internal/protocol/bt/fetcher.go index c494a87e..75f8e3a0 100644 --- a/internal/protocol/bt/fetcher.go +++ b/internal/protocol/bt/fetcher.go @@ -68,7 +68,7 @@ func (f *Fetcher) initClient() (err error) { cfg.Bep20 = fmt.Sprintf("-GP%s-", parseBep20()) cfg.ExtendedHandshakeClientVersion = fmt.Sprintf("Gopeed %s", base.Version) cfg.ListenPort = f.config.ListenPort - cfg.HTTPProxy = util.ProxyUrlToHandler(f.ctl.ProxyUrl) + cfg.HTTPProxy = f.ctl.ProxyConfig.ToHandler() cfg.DefaultStorage = newFileOpts(newFileClientOpts{ ClientBaseDir: cfg.DataDir, HandleFileTorrent: func(infoHash metainfo.Hash, ft *fileTorrentImpl) { diff --git a/internal/protocol/bt/fetcher_test.go b/internal/protocol/bt/fetcher_test.go index b0bff548..09f3d483 100644 --- a/internal/protocol/bt/fetcher_test.go +++ b/internal/protocol/bt/fetcher_test.go @@ -114,7 +114,7 @@ func buildConfigFetcher(proxyUrl *url.URL) fetcher.Fetcher { } return true } - newController.ProxyUrl = proxyUrl + newController.ToUrl = proxyUrl fetcher.Setup(newController) return fetcher } diff --git a/internal/protocol/http/fetcher.go b/internal/protocol/http/fetcher.go index 46417b5d..5369bc1b 100644 --- a/internal/protocol/http/fetcher.go +++ b/internal/protocol/http/fetcher.go @@ -9,7 +9,6 @@ import ( "github.com/GopeedLab/gopeed/internal/fetcher" "github.com/GopeedLab/gopeed/pkg/base" fhttp "github.com/GopeedLab/gopeed/pkg/protocol/http" - "github.com/GopeedLab/gopeed/pkg/util" "github.com/xiaoqidun/setft" "golang.org/x/sync/errgroup" "io" @@ -455,7 +454,7 @@ func (f *Fetcher) buildClient() *http.Client { transport := &http.Transport{} // Cookie handle jar, _ := cookiejar.New(nil) - transport.Proxy = util.ProxyUrlToHandler(f.ctl.ProxyUrl) + transport.Proxy = f.ctl.ProxyConfig.ToHandler() return &http.Client{ Transport: transport, Jar: jar, diff --git a/internal/protocol/http/fetcher_test.go b/internal/protocol/http/fetcher_test.go index b65e3a3b..6c76a0de 100644 --- a/internal/protocol/http/fetcher_test.go +++ b/internal/protocol/http/fetcher_test.go @@ -8,7 +8,6 @@ import ( "github.com/GopeedLab/gopeed/internal/test" "github.com/GopeedLab/gopeed/pkg/base" "github.com/GopeedLab/gopeed/pkg/protocol/http" - "github.com/GopeedLab/gopeed/pkg/util" "net" "testing" "time" @@ -338,7 +337,11 @@ func downloadResume(listener net.Listener, connections int, t *testing.T) { func downloadWithProxy(httpListener net.Listener, proxyListener net.Listener, t *testing.T) { fetcher := downloadReady(httpListener, 4, t) ctl := controller.NewController() - ctl.ProxyUrl = util.BuildProxyUrl("socks5", proxyListener.Addr().String(), "", "") + ctl.ProxyConfig = &base.DownloaderProxyConfig{ + Enable: true, + Scheme: "socks5", + Host: proxyListener.Addr().String(), + } fetcher.Setup(ctl) err := fetcher.Start() if err != nil { diff --git a/internal/test/httptest.go b/internal/test/httptest.go index 18cc3069..fb3c38e5 100644 --- a/internal/test/httptest.go +++ b/internal/test/httptest.go @@ -24,6 +24,11 @@ const ( Dir = "./" BuildFile = Dir + BuildName + ExternalDownloadUrl = "https://raw.githubusercontent.com/GopeedLab/gopeed/v1.5.6/_docs/img/banner.png" + ExternalDownloadName = "banner.png" + ExternalDownloadSize = 26416 + //ExternalDownloadMd5 = "c67c6e3cae79a95342485676571e8a5c" + DownloadName = "download.data" DownloadRename = "download (1).data" DownloadFile = Dir + DownloadName diff --git a/pkg/base/model.go b/pkg/base/model.go index f0b7ff04..d0630b8e 100644 --- a/pkg/base/model.go +++ b/pkg/base/model.go @@ -3,7 +3,10 @@ package base import ( "fmt" "github.com/GopeedLab/gopeed/pkg/util" + "github.com/mattn/go-ieproxy" "golang.org/x/exp/slices" + "net/http" + "net/url" "time" ) @@ -128,3 +131,86 @@ func ParseOptsExtra[E any](opts *Options) error { opts.Extra = &t return nil } + +// DownloaderStoreConfig is the config that can restore the downloader. +type DownloaderStoreConfig struct { + FirstLoad bool `json:"-"` // FirstLoad is the flag that the config is first time init and not from store + + DownloadDir string `json:"downloadDir"` // DownloadDir is the default directory to save the downloaded files + MaxRunning int `json:"maxRunning"` // MaxRunning is the max running download count + ProtocolConfig map[string]any `json:"protocolConfig"` // ProtocolConfig is special config for each protocol + Extra map[string]any `json:"extra"` + Proxy *DownloaderProxyConfig `json:"proxy"` +} + +func (cfg *DownloaderStoreConfig) Init() *DownloaderStoreConfig { + if cfg.MaxRunning == 0 { + cfg.MaxRunning = 5 + } + if cfg.Proxy == nil { + cfg.Proxy = &DownloaderProxyConfig{} + } + return cfg +} + +type DownloaderProxyConfig struct { + Enable bool `json:"enable"` + // System is the flag that use system proxy + System bool `json:"system"` + Scheme string `json:"scheme"` + Host string `json:"host"` + Usr string `json:"usr"` + Pwd string `json:"pwd"` +} + +func (cfg *DownloaderProxyConfig) ToHandler() func(r *http.Request) (*url.URL, error) { + if cfg == nil || cfg.Enable == false { + return nil + } + if cfg.System { + return ieproxy.GetProxyFunc() + } + if cfg.Scheme == "" || cfg.Host == "" { + return nil + } + return http.ProxyURL(util.BuildProxyUrl(cfg.Scheme, cfg.Host, cfg.Usr, cfg.Pwd)) +} + +// ToUrl returns the proxy url, just for git clone +func (cfg *DownloaderProxyConfig) ToUrl() *url.URL { + if cfg == nil || cfg.Enable == false { + return nil + } + if cfg.System { + static := ieproxy.GetConf().Static + if static.Active && len(static.Protocols) > 0 { + // If only one protocol, use it + if len(static.Protocols) == 1 { + for _, v := range static.Protocols { + return parseUrlSafe(v) + } + } + // Check https + if v, ok := static.Protocols["https"]; ok { + return parseUrlSafe(v) + } + // Check http + if v, ok := static.Protocols["http"]; ok { + return parseUrlSafe(v) + } + } + return nil + } + if cfg.Scheme == "" || cfg.Host == "" { + return nil + } + return util.BuildProxyUrl(cfg.Scheme, cfg.Host, cfg.Usr, cfg.Pwd) +} + +func parseUrlSafe(rawUrl string) *url.URL { + u, err := url.Parse(rawUrl) + if err != nil { + return nil + } + return u +} diff --git a/pkg/download/downloader.go b/pkg/download/downloader.go index 5d7faeb9..59dfecdb 100644 --- a/pkg/download/downloader.go +++ b/pkg/download/downloader.go @@ -110,7 +110,7 @@ func (d *Downloader) Setup() error { return err } // load config from storage - var cfg DownloaderStoreConfig + var cfg base.DownloaderStoreConfig exist, err := d.storage.Get(bucketConfig, "config", &cfg) if err != nil { return err @@ -118,7 +118,7 @@ func (d *Downloader) Setup() error { if exist { d.cfg.DownloaderStoreConfig = &cfg } else { - d.cfg.DownloaderStoreConfig = &DownloaderStoreConfig{ + d.cfg.DownloaderStoreConfig = &base.DownloaderStoreConfig{ FirstLoad: true, } } @@ -225,7 +225,7 @@ func (d *Downloader) setupFetcher(fetcher fetcher.Fetcher) { ctl.GetConfig = func(v any) bool { return d.getProtocolConfig(fetcher.Name(), v) } - ctl.ProxyUrl = d.cfg.ProxyUrl() + ctl.ProxyConfig = d.cfg.Proxy fetcher.Setup(ctl) } @@ -603,11 +603,11 @@ func (d *Downloader) GetTasksByStatues(statues []base.Status) []*Task { return tasks } -func (d *Downloader) GetConfig() (*DownloaderStoreConfig, error) { +func (d *Downloader) GetConfig() (*base.DownloaderStoreConfig, error) { return d.cfg.DownloaderStoreConfig, nil } -func (d *Downloader) PutConfig(v *DownloaderStoreConfig) error { +func (d *Downloader) PutConfig(v *base.DownloaderStoreConfig) error { d.cfg.DownloaderStoreConfig = v return d.storage.Put(bucketConfig, "config", v) } diff --git a/pkg/download/downloader_test.go b/pkg/download/downloader_test.go index 193da864..3d9e3a29 100644 --- a/pkg/download/downloader_test.go +++ b/pkg/download/downloader_test.go @@ -4,6 +4,7 @@ import ( "github.com/GopeedLab/gopeed/internal/test" "github.com/GopeedLab/gopeed/pkg/base" "github.com/GopeedLab/gopeed/pkg/protocol/http" + "os" "sync" "testing" "time" @@ -85,42 +86,58 @@ func TestDownloader_Create(t *testing.T) { func TestDownloader_CreateWithProxy(t *testing.T) { // No proxy - doTestDownloaderCreateWithProxy(t, false, func(proxyCfg *DownloaderProxyConfig) *DownloaderProxyConfig { + doTestDownloaderCreateWithProxy(t, false, func(proxyCfg *base.DownloaderProxyConfig) *base.DownloaderProxyConfig { return nil - }) + }, nil) // Disable proxy - doTestDownloaderCreateWithProxy(t, false, func(proxyCfg *DownloaderProxyConfig) *DownloaderProxyConfig { + doTestDownloaderCreateWithProxy(t, false, func(proxyCfg *base.DownloaderProxyConfig) *base.DownloaderProxyConfig { proxyCfg.Enable = false return proxyCfg - }) - // System proxy - doTestDownloaderCreateWithProxy(t, false, func(proxyCfg *DownloaderProxyConfig) *DownloaderProxyConfig { - proxyCfg.Scheme = "system" + }, nil) + // Enable system proxy but not set proxy environment variable + doTestDownloaderCreateWithProxy(t, false, func(proxyCfg *base.DownloaderProxyConfig) *base.DownloaderProxyConfig { + proxyCfg.System = true return proxyCfg + }, nil) + // Enable proxy but error proxy environment variable + doTestDownloaderCreateWithProxy(t, false, func(proxyCfg *base.DownloaderProxyConfig) *base.DownloaderProxyConfig { + os.Setenv("HTTP_PROXY", "http://127.0.0.1:1234") + os.Setenv("HTTPS_PROXY", "http://127.0.0.1:1234") + proxyCfg.System = true + return proxyCfg + }, func(err error) { + if err == nil { + t.Fatal("doTestDownloaderCreateWithProxy() got = nil, want error") + } }) + // Enable system proxy and set proxy environment variable + doTestDownloaderCreateWithProxy(t, false, func(proxyCfg *base.DownloaderProxyConfig) *base.DownloaderProxyConfig { + os.Setenv("HTTP_PROXY", proxyCfg.ToUrl().String()) + os.Setenv("HTTPS_PROXY", proxyCfg.ToUrl().String()) + proxyCfg.System = true + return proxyCfg + }, nil) // Invalid proxy scheme - doTestDownloaderCreateWithProxy(t, false, func(proxyCfg *DownloaderProxyConfig) *DownloaderProxyConfig { + doTestDownloaderCreateWithProxy(t, false, func(proxyCfg *base.DownloaderProxyConfig) *base.DownloaderProxyConfig { proxyCfg.Scheme = "" return proxyCfg - }) + }, nil) // Invalid proxy host - doTestDownloaderCreateWithProxy(t, false, func(proxyCfg *DownloaderProxyConfig) *DownloaderProxyConfig { + doTestDownloaderCreateWithProxy(t, false, func(proxyCfg *base.DownloaderProxyConfig) *base.DownloaderProxyConfig { proxyCfg.Host = "" return proxyCfg - }) + }, nil) // Use proxy without auth - doTestDownloaderCreateWithProxy(t, false, func(proxyCfg *DownloaderProxyConfig) *DownloaderProxyConfig { + doTestDownloaderCreateWithProxy(t, false, func(proxyCfg *base.DownloaderProxyConfig) *base.DownloaderProxyConfig { return proxyCfg - }) + }, nil) // Use proxy with auth - doTestDownloaderCreateWithProxy(t, true, func(proxyCfg *DownloaderProxyConfig) *DownloaderProxyConfig { + doTestDownloaderCreateWithProxy(t, true, func(proxyCfg *base.DownloaderProxyConfig) *base.DownloaderProxyConfig { return proxyCfg - }) + }, nil) } -func doTestDownloaderCreateWithProxy(t *testing.T, auth bool, buildProxyConfig func(proxyCfg *DownloaderProxyConfig) *DownloaderProxyConfig) { - httpListener := test.StartTestFileServer() - defer httpListener.Close() +func doTestDownloaderCreateWithProxy(t *testing.T, auth bool, buildProxyConfig func(proxyCfg *base.DownloaderProxyConfig) *base.DownloaderProxyConfig, errHandler func(err error)) { usr, pwd := "", "" if auth { usr, pwd = "admin", "123" @@ -133,7 +150,7 @@ func doTestDownloaderCreateWithProxy(t *testing.T, auth bool, buildProxyConfig f t.Fatal(err) } defer downloader.Clear() - downloader.cfg.DownloaderStoreConfig.Proxy = buildProxyConfig(&DownloaderProxyConfig{ + downloader.cfg.DownloaderStoreConfig.Proxy = buildProxyConfig(&base.DownloaderProxyConfig{ Enable: true, Scheme: "socks5", Host: proxyListener.Addr().String(), @@ -142,20 +159,24 @@ func doTestDownloaderCreateWithProxy(t *testing.T, auth bool, buildProxyConfig f }) req := &base.Request{ - URL: "http://" + httpListener.Addr().String() + "/" + test.BuildName, + URL: test.ExternalDownloadUrl, } rr, err := downloader.Resolve(req) if err != nil { - t.Fatal(err) + if errHandler == nil { + t.Fatal(err) + } + errHandler(err) + return } want := &base.Resource{ - Size: test.BuildSize, + Size: test.ExternalDownloadSize, Range: true, Files: []*base.FileInfo{ { - Name: test.BuildName, + Name: test.ExternalDownloadName, Path: "", - Size: test.BuildSize, + Size: test.ExternalDownloadSize, }, }, } @@ -290,7 +311,7 @@ func TestDownloader_Protocol_Config(t *testing.T) { t.Errorf("getProtocolConfig() got = %v, want %v", exits, false) } - storeCfg := &DownloaderStoreConfig{ + storeCfg := &base.DownloaderStoreConfig{ DownloadDir: "./downloads", ProtocolConfig: map[string]any{ "http": map[string]any{ diff --git a/pkg/download/engine/engine.go b/pkg/download/engine/engine.go index 969a5cef..ac0db488 100644 --- a/pkg/download/engine/engine.go +++ b/pkg/download/engine/engine.go @@ -3,6 +3,7 @@ package engine import ( _ "embed" "errors" + "github.com/GopeedLab/gopeed/pkg/base" gojaerror "github.com/GopeedLab/gopeed/pkg/download/engine/inject/error" "github.com/GopeedLab/gopeed/pkg/download/engine/inject/file" "github.com/GopeedLab/gopeed/pkg/download/engine/inject/formdata" @@ -11,7 +12,6 @@ import ( "github.com/dop251/goja" "github.com/dop251/goja_nodejs/eventloop" gojaurl "github.com/dop251/goja_nodejs/url" - "net/url" "time" ) @@ -110,7 +110,7 @@ func (e *Engine) Close() { } type Config struct { - ProxyURL *url.URL + ProxyConfig *base.DownloaderProxyConfig } func NewEngine(cfg *Config) *Engine { @@ -135,7 +135,7 @@ func NewEngine(cfg *Config) *Engine { if err := formdata.Enable(runtime); err != nil { return } - if err := xhr.Enable(runtime, cfg.ProxyURL); err != nil { + if err := xhr.Enable(runtime, cfg.ProxyConfig.ToHandler()); err != nil { return } if _, err := runtime.RunString(polyfillScript); err != nil { diff --git a/pkg/download/engine/inject/xhr/module.go b/pkg/download/engine/inject/xhr/module.go index 0eedb3a7..d43491a2 100644 --- a/pkg/download/engine/inject/xhr/module.go +++ b/pkg/download/engine/inject/xhr/module.go @@ -6,7 +6,6 @@ import ( "github.com/GopeedLab/gopeed/pkg/download/engine/inject/file" "github.com/GopeedLab/gopeed/pkg/download/engine/inject/formdata" "github.com/GopeedLab/gopeed/pkg/download/engine/util" - urlUtil "github.com/GopeedLab/gopeed/pkg/util" "github.com/dop251/goja" "io" "mime/multipart" @@ -122,7 +121,7 @@ type XMLHttpRequest struct { requestHeaders map[string]string responseHeaders map[string]string aborted bool - proxyUrl *url.URL + proxyHandler func(r *http.Request) (*url.URL, error) Upload *XMLHttpRequestUpload `json:"upload"` Timeout int `json:"timeout"` @@ -204,8 +203,12 @@ func (xhr *XMLHttpRequest) Send(data goja.Value) { for k, v := range xhr.requestHeaders { req.Header.Set(k, v) } - transport := &http.Transport{} - transport.Proxy = urlUtil.ProxyUrlToHandler(xhr.proxyUrl) + var transport *http.Transport + if xhr.proxyHandler != nil { + transport = &http.Transport{ + Proxy: xhr.proxyHandler, + } + } client := &http.Client{ Transport: transport, Timeout: time.Duration(xhr.Timeout) * time.Millisecond, @@ -314,7 +317,7 @@ func (xhr *XMLHttpRequest) parseData(data goja.Value) any { return data.String() } -func Enable(runtime *goja.Runtime, proxyUrl *url.URL) error { +func Enable(runtime *goja.Runtime, proxyHandler func(r *http.Request) (*url.URL, error)) error { progressEvent := runtime.ToValue(func(call goja.ConstructorCall) *goja.Object { if len(call.Arguments) < 1 { util.ThrowTypeError(runtime, "Failed to construct 'ProgressEvent': 1 argument required, but only 0 present.") @@ -328,7 +331,7 @@ func Enable(runtime *goja.Runtime, proxyUrl *url.URL) error { }) xhr := runtime.ToValue(func(call goja.ConstructorCall) *goja.Object { instance := &XMLHttpRequest{ - proxyUrl: proxyUrl, + proxyHandler: proxyHandler, Upload: &XMLHttpRequestUpload{ EventProp: &EventProp{ eventListeners: make(map[string]func(event *ProgressEvent)), diff --git a/pkg/download/extension.go b/pkg/download/extension.go index 262bc559..83955aaa 100644 --- a/pkg/download/extension.go +++ b/pkg/download/extension.go @@ -199,7 +199,7 @@ func (d *Downloader) fetchExtensionByGit(url string, handler func(tempExtPath st return nil, err } proxyOptions := transport.ProxyOptions{} - proxyUrl := d.cfg.ProxyUrl() + proxyUrl := d.cfg.DownloaderStoreConfig.Proxy.ToUrl() if proxyUrl != nil { proxyOptions.URL = proxyUrl.Scheme + "://" + proxyUrl.Host proxyOptions.Username = proxyUrl.User.Username() @@ -341,7 +341,7 @@ func doTrigger[T any](d *Downloader, event ActivationEvent, req *base.Request, c req.Labels = make(map[string]string) } engine := engine.NewEngine(&engine.Config{ - ProxyURL: d.cfg.ProxyUrl(), + ProxyConfig: d.cfg.Proxy, }) defer engine.Close() err = engine.Runtime.Set("gopeed", gopeed) diff --git a/pkg/download/model.go b/pkg/download/model.go index d5e91c9c..4fbc5b9d 100644 --- a/pkg/download/model.go +++ b/pkg/download/model.go @@ -7,9 +7,7 @@ import ( "github.com/GopeedLab/gopeed/internal/protocol/http" "github.com/GopeedLab/gopeed/pkg/base" "github.com/GopeedLab/gopeed/pkg/util" - gonanoid "github.com/matoous/go-nanoid/v2" - "net/url" "sync" "time" ) @@ -87,7 +85,7 @@ type DownloaderConfig struct { ProductionMode bool - *DownloaderStoreConfig + *base.DownloaderStoreConfig } func (cfg *DownloaderConfig) Init() *DownloaderConfig { @@ -108,43 +106,3 @@ func (cfg *DownloaderConfig) Init() *DownloaderConfig { } return cfg } - -// DownloaderStoreConfig is the config that can restore the downloader. -type DownloaderStoreConfig struct { - FirstLoad bool `json:"-"` // FirstLoad is the flag that the config is first time init and not from store - - DownloadDir string `json:"downloadDir"` // DownloadDir is the default directory to save the downloaded files - MaxRunning int `json:"maxRunning"` // MaxRunning is the max running download count - ProtocolConfig map[string]any `json:"protocolConfig"` // ProtocolConfig is special config for each protocol - Extra map[string]any `json:"extra"` - Proxy *DownloaderProxyConfig `json:"proxy"` -} - -func (cfg *DownloaderStoreConfig) Init() *DownloaderStoreConfig { - if cfg.MaxRunning == 0 { - cfg.MaxRunning = 5 - } - if cfg.Proxy == nil { - cfg.Proxy = &DownloaderProxyConfig{} - } - return cfg -} - -func (cfg *DownloaderStoreConfig) ProxyUrl() *url.URL { - if cfg.Proxy == nil { - return nil - } - if cfg.Proxy.Enable == false || cfg.Proxy.Scheme == "" || cfg.Proxy.Host == "" { - return nil - } - return util.BuildProxyUrl(cfg.Proxy.Scheme, cfg.Proxy.Host, cfg.Proxy.Usr, cfg.Proxy.Pwd) -} - -type DownloaderProxyConfig struct { - Enable bool `json:"enable"` - // Scheme is the proxy scheme, e.g. http, https, socks5, but there is a special scheme "system" that means use system proxy - Scheme string `json:"scheme"` - Host string `json:"host"` - Usr string `json:"usr"` - Pwd string `json:"pwd"` -} diff --git a/pkg/rest/api.go b/pkg/rest/api.go index d95964dd..8a0ae75b 100644 --- a/pkg/rest/api.go +++ b/pkg/rest/api.go @@ -142,7 +142,7 @@ func GetConfig(w http.ResponseWriter, r *http.Request) { } func PutConfig(w http.ResponseWriter, r *http.Request) { - var cfg download.DownloaderStoreConfig + var cfg base.DownloaderStoreConfig if ReadJson(r, w, &cfg) { if err := Downloader.PutConfig(&cfg); err != nil { WriteJson(w, model.NewErrorResult(err.Error())) @@ -309,7 +309,7 @@ func writeError(w http.ResponseWriter, msg string) { w.Write([]byte(msg)) } -func getServerConfig() *download.DownloaderStoreConfig { +func getServerConfig() *base.DownloaderStoreConfig { cfg, _ := Downloader.GetConfig() return cfg } diff --git a/pkg/rest/server_test.go b/pkg/rest/server_test.go index 7b001def..ef6b8605 100644 --- a/pkg/rest/server_test.go +++ b/pkg/rest/server_test.go @@ -324,7 +324,7 @@ func TestGetTasks(t *testing.T) { func TestGetAndPutConfig(t *testing.T) { doTest(func() { - cfg := httpRequestCheckOk[*download.DownloaderStoreConfig](http.MethodGet, "/api/v1/config", nil) + cfg := httpRequestCheckOk[*base.DownloaderStoreConfig](http.MethodGet, "/api/v1/config", nil) cfg.DownloadDir = "./download" cfg.Extra = map[string]any{ "serverConfig": &Config{ @@ -335,7 +335,7 @@ func TestGetAndPutConfig(t *testing.T) { } httpRequestCheckOk[any](http.MethodPut, "/api/v1/config", cfg) - newCfg := httpRequestCheckOk[*download.DownloaderStoreConfig](http.MethodGet, "/api/v1/config", nil) + newCfg := httpRequestCheckOk[*base.DownloaderStoreConfig](http.MethodGet, "/api/v1/config", nil) if !test.JsonEqual(cfg, newCfg) { t.Errorf("GetAndPutConfig() got = %v, want %v", test.ToJson(newCfg), test.ToJson(cfg)) }