Skip to content

Commit

Permalink
feat: add proxy config
Browse files Browse the repository at this point in the history
  • Loading branch information
ghosind committed Nov 1, 2023
1 parent 2d644e6 commit 4c17cce
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 0 deletions.
39 changes: 39 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package request

import (
"net"
"net/http"
"net/url"
"sync"
Expand All @@ -18,6 +19,8 @@ type Client struct {
Parameters map[string][]string
// ParametersSerializer is a function to charge of serializing the URL query parameters.
ParametersSerializer func(map[string][]string) string
// Proxy is the config of the proxy server.
Proxy *ProxyConfig
// Timeout specifies the time before the request times out.
Timeout int
// UserAgent sets the client's User-Agent field in the request header.
Expand All @@ -44,6 +47,13 @@ type Config struct {
Parameters map[string][]string
// ParametersSerializer is a function to charge of serializing the URL query parameters.
ParametersSerializer func(map[string][]string) string
// Proxy defines the address and the auth credentials of the proxy server, it will be overwritten
// by the request options' proxy config if the proxy config is not empty in the request options.
//
// You can also define the proxy by the `http_proxy` and `https_proxy` environment variables. If
// no proxy config in the request options or the client config, the request will try to get a
// proxy from the environment variables.
Proxy *ProxyConfig
// Timeout is request timeout in milliseconds.
Timeout int
// UserAgent sets the client's User-Agent field in the request header.
Expand Down Expand Up @@ -102,6 +112,7 @@ func New(config ...Config) *Client {
cli.BaseURL = cfg.BaseURL
cli.MaxRedirects = cfg.MaxRedirects
cli.ParametersSerializer = cfg.ParametersSerializer
cli.Proxy = cfg.Proxy
cli.Timeout = cfg.Timeout
cli.UserAgent = cfg.UserAgent
cli.ValidateStatus = cfg.ValidateStatus
Expand Down Expand Up @@ -224,6 +235,7 @@ func (cli *Client) getHTTPClient(opt RequestOptions) *http.Client {
}

httpClient.CheckRedirect = cli.getCheckRedirect(maxRedirects)
httpClient.Transport = cli.getTransport(opt)

return httpClient
}
Expand Down Expand Up @@ -264,3 +276,30 @@ func (cli *Client) defaultCheckRedirect(req *http.Request, via []*http.Request)
func (cli *Client) defaultValidateStatus(status int) bool {
return status >= http.StatusOK && status < http.StatusBadRequest
}

// getTransport gets the transport by the request options.
func (cli *Client) getTransport(opt RequestOptions) http.RoundTripper {
transport := http.Transport{}
transport.Proxy = cli.getProxy(opt)

return &transport
}

// getProxy tries to get a proxy by the proxy config from the request options, and it returns
// `http.ProxyFromEnvironment` if there is no proxy config in the request options.
func (cli *Client) getProxy(opt RequestOptions) func(*http.Request) (*url.URL, error) {
proxy := opt.Proxy
if proxy == nil {
proxy = cli.Proxy
}
if proxy == nil {
return http.ProxyFromEnvironment
}

proxyUrl := new(url.URL)
proxyUrl.Scheme = proxy.Protocol
proxyUrl.Host = net.JoinHostPort(proxy.Host, proxy.Port)
proxyUrl.User = url.UserPassword(proxy.Username, proxy.Password)

return http.ProxyURL(proxyUrl)
}
29 changes: 29 additions & 0 deletions request_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ type RequestOptions struct {
Parameters map[string][]string
// ParametersSerializer is a function to charge of serializing the URL query parameters.
ParametersSerializer func(map[string][]string) string
// Proxy defines the address and the auth credentials of the proxy server, it will overwrite the
// client's proxy config. You can also define the proxy by the `http_proxy` and `https_proxy`
// environment variables. If no proxy config in the request options or the client config, the
// request will try to get a proxy from the environment variables.
Proxy *ProxyConfig
// Timeout specifies the number of milliseconds before the request times out. This value will be
// ignored if the `Content` field in the request options is set. It indicates no time-out
// limitation if the value is -1.
Expand Down Expand Up @@ -130,6 +135,20 @@ type BasicAuthConfig struct {
Password string
}

// ProxyConfig defines the protocol, hostname, port, username, and password of the proxy server.
type ProxyConfig struct {
// Protocol is the protocol of the proxy server, support "http", "https", and "socks5".
Protocol string
// Host is the hostname of the proxy server.
Host string
// Port is the port of the proxy server.
Port string
// Username is the username that is used to connect to the proxy server.
Username string
// Password is the password that is used to connect to the proxy server.
Password string
}

// SetBasicAuth sets the username and the password as the HTTP Basic Auth to the request.
//
// request.Req("http://example.com").
Expand Down Expand Up @@ -441,6 +460,16 @@ func (opt *RequestOptions) SetParametersSerializer(
return opt
}

// Proxy sets the address and the auth credentials of the proxy server, it will overwrite the
// client's proxy config. You can also define the proxy by the `http_proxy` and `https_proxy`
// environment variables. If no proxy config in the request options or the client config, the
// request will try to get a proxy from the environment variables.
func (opt *RequestOptions) SetProxy(proxy ProxyConfig) *RequestOptions {
opt.Proxy = &proxy

return opt
}

// SetTimeout sets the timeout of the request in the milliseconds.
//
// request.Req("http://example.com").
Expand Down

0 comments on commit 4c17cce

Please sign in to comment.