From 8a0e69f17d2216e9791b337e08a3e2ff66a27125 Mon Sep 17 00:00:00 2001 From: Chikage Date: Tue, 6 Sep 2022 15:09:40 +0800 Subject: [PATCH 1/3] add proxy --- cmd/root.go | 12 ++++++++++++ http/client.go | 16 ++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/cmd/root.go b/cmd/root.go index e2987bc..0380139 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -21,6 +21,7 @@ func init() { rootCmd.Flags().String("host", "api.modrinth.com", "Labrinth host") rootCmd.Flags().String("server-dir", "mc", "Server directory path") rootCmd.Flags().String("server-file", "", "Server jar file name") + rootCmd.Flags().String("proxy", "", "Use a proxy to download") } var rootCmd = &cobra.Command{ @@ -41,6 +42,17 @@ var rootCmd = &cobra.Command{ log.Fatalln(err) } + proxy, err := cmd.Flags().GetString("proxy") + if err != nil { + log.Fatalln(err) + } + if proxy != "" { + err := http.Instance.SetProxy(proxy) + if err != nil { + log.Fatalln(err) + } + } + input := args[0] version := "" if len(args) > 1 { diff --git a/http/client.go b/http/client.go index e5b5c83..d745a50 100644 --- a/http/client.go +++ b/http/client.go @@ -7,6 +7,7 @@ import ( "io" "log" "net/http" + "net/url" "os" "path" "regexp" @@ -38,6 +39,21 @@ func init() { } } +func (client *Client) SetProxy(CustomProxy string) error { + proxy := func(_ *http.Request) (*url.URL, error) { + return url.Parse(CustomProxy) + } + + httpTransport := &http.Transport{ + Proxy: proxy, + } + + client.HTTPClient = &http.Client{ + Transport: httpTransport, + } + return nil +} + func (client *Client) GetJson(url string, respModel interface{}, errModel ErrorModel) error { request, err := http.NewRequest(http.MethodGet, url, nil) if err != nil { From 60d570009015484f77165ce95cb3d5718cc391b3 Mon Sep 17 00:00:00 2001 From: Chikage Date: Tue, 6 Sep 2022 17:02:28 +0800 Subject: [PATCH 2/3] add proxy check --- http/client.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/http/client.go b/http/client.go index d745a50..535855f 100644 --- a/http/client.go +++ b/http/client.go @@ -51,6 +51,15 @@ func (client *Client) SetProxy(CustomProxy string) error { client.HTTPClient = &http.Client{ Transport: httpTransport, } + + httpUrl := "https://api.modrinth.com/" + response, err := client.HTTPClient.Get(httpUrl) + if err != nil { + return err + } + if response.StatusCode != http.StatusOK { + return err + } return nil } From 22997e12eb95cb583571bced850236a0b9cd9bfa Mon Sep 17 00:00:00 2001 From: Chikage Date: Tue, 6 Sep 2022 19:32:42 +0800 Subject: [PATCH 3/3] refactor client --- http/client.go | 50 ++----------------- http/http_client.go | 115 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+), 47 deletions(-) create mode 100644 http/http_client.go diff --git a/http/client.go b/http/client.go index 535855f..01d35ff 100644 --- a/http/client.go +++ b/http/client.go @@ -7,11 +7,9 @@ import ( "io" "log" "net/http" - "net/url" "os" "path" "regexp" - "runtime/debug" "strconv" ) @@ -19,49 +17,7 @@ type ErrorModel interface { String() string } -type Client struct { - UserAgent string - HTTPClient *http.Client -} - -// TODO: global lookup map host -> ratelimit hits left and sleep wait strategy - -var Instance *Client = nil - -func init() { - Instance = &Client{ - UserAgent: "mrpack-install", - HTTPClient: &http.Client{}, - } - info, ok := debug.ReadBuildInfo() - if ok && info.Main.Path != "" { - Instance.UserAgent = info.Main.Path + "/" + info.Main.Version - } -} - -func (client *Client) SetProxy(CustomProxy string) error { - proxy := func(_ *http.Request) (*url.URL, error) { - return url.Parse(CustomProxy) - } - - httpTransport := &http.Transport{ - Proxy: proxy, - } - - client.HTTPClient = &http.Client{ - Transport: httpTransport, - } - - httpUrl := "https://api.modrinth.com/" - response, err := client.HTTPClient.Get(httpUrl) - if err != nil { - return err - } - if response.StatusCode != http.StatusOK { - return err - } - return nil -} +var Instance = NewHTTPClient() func (client *Client) GetJson(url string, respModel interface{}, errModel ErrorModel) error { request, err := http.NewRequest(http.MethodGet, url, nil) @@ -74,7 +30,7 @@ func (client *Client) GetJson(url string, respModel interface{}, errModel ErrorM request.Close = true - response, err := client.HTTPClient.Do(request) + response, err := client.Do(request) if err != nil { return err } @@ -111,7 +67,7 @@ func (client *Client) DownloadFile(url string, downloadDir string, fileName stri request.Header.Set("User-Agent", client.UserAgent) request.Close = true - response, err := client.HTTPClient.Do(request) + response, err := client.Do(request) if err != nil { return "", err } diff --git a/http/http_client.go b/http/http_client.go new file mode 100644 index 0000000..dd5d6ac --- /dev/null +++ b/http/http_client.go @@ -0,0 +1,115 @@ +package http + +import ( + "crypto/tls" + "net/http" + "net/http/cookiejar" + "net/url" + "runtime/debug" + "time" +) + +type Client struct { + http.Client + insecureSkipVerify bool + UserAgent string + transport *http.Transport +} + +// TODO: global lookup map host -> ratelimit hits left and sleep wait strategy + +func NewHTTPClient() *Client { + client := &Client{ + Client: http.Client{}, + UserAgent: "mrpack-install", + } + client.Client.Jar, _ = cookiejar.New(nil) + info, ok := debug.ReadBuildInfo() + if ok && info.Main.Path != "" { + client.UserAgent = info.Main.Path + "/" + info.Main.Version + } + return client +} + +func (client *Client) lazyInit() { + if client.transport == nil { + client.transport = &http.Transport{ + Proxy: http.ProxyFromEnvironment, + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: false, + }, + TLSHandshakeTimeout: 20 * time.Second, + DisableKeepAlives: false, + DisableCompression: false, // gzip + MaxIdleConns: 100, + IdleConnTimeout: 90 * time.Second, + ResponseHeaderTimeout: 25 * time.Second, + ExpectContinueTimeout: 10 * time.Second, + } + client.Client.Transport = client.transport + } +} + +func (client *Client) SetUserAgent(ua string) { + client.UserAgent = ua +} + +func (client *Client) SetCookiejar(jar http.CookieJar) { + client.Client.Jar = jar +} + +func (client *Client) ResetCookiejar() { + client.Jar, _ = cookiejar.New(nil) +} + +func (client *Client) SetProxy(CustomProxy string) error { + client.lazyInit() + proxy, err := url.Parse(CustomProxy) + if err != nil { + return err + } + + client.transport.Proxy = http.ProxyURL(proxy) + + // Test proxy + httpUrl := "https://api.modrinth.com/" + response, err := client.Get(httpUrl) + if err != nil { + return err + } + if response.StatusCode != http.StatusOK { + return err + } + return nil +} + +func (client *Client) SetInsecureSkipVerify(b bool) { + client.lazyInit() + client.transport.TLSClientConfig = &tls.Config{ + InsecureSkipVerify: b, + } +} + +func (client *Client) SetKeepAlive(b bool) { + client.lazyInit() + client.transport.DisableKeepAlives = !b +} + +func (client *Client) SetGzip(b bool) { + client.lazyInit() + client.transport.DisableCompression = !b +} + +func (client *Client) SetResponseHeaderTimeout(t time.Duration) { + client.lazyInit() + client.transport.ResponseHeaderTimeout = t +} + +func (client *Client) SetTLSHandshakeTimeout(t time.Duration) { + client.lazyInit() + client.transport.TLSHandshakeTimeout = t +} + +func (client *Client) SetTimeout(t time.Duration) { + client.Client.Timeout = t +}