diff options
author | Justin Angel <[email protected]> | 2024-03-18 00:07:25 -0400 |
---|---|---|
committer | GitHub <[email protected]> | 2024-03-18 04:07:25 +0000 |
commit | a9768d2fdefeae8050f1d328e7133e312acd253f (patch) | |
tree | e7e5d890e81546a8762737e7609471b3ab61263d | |
parent | 52822a41cb94fcc9669cd7ba8ac1a0513e4d55f9 (diff) | |
download | caddy-a9768d2fdefeae8050f1d328e7133e312acd253f.tar.gz caddy-a9768d2fdefeae8050f1d328e7133e312acd253f.zip |
reverseproxy: Configurable forward proxy URL (#6114)
Co-authored-by: WeidiDeng <[email protected]>
-rw-r--r-- | modules/caddyhttp/reverseproxy/caddyfile.go | 7 | ||||
-rw-r--r-- | modules/caddyhttp/reverseproxy/httptransport.go | 32 |
2 files changed, 38 insertions, 1 deletions
diff --git a/modules/caddyhttp/reverseproxy/caddyfile.go b/modules/caddyhttp/reverseproxy/caddyfile.go index 42fd6f99d..66bbcbcd4 100644 --- a/modules/caddyhttp/reverseproxy/caddyfile.go +++ b/modules/caddyhttp/reverseproxy/caddyfile.go @@ -907,6 +907,7 @@ func (h *Handler) FinalizeUnmarshalCaddyfile(helper httpcaddyfile.Helper) error // read_buffer <size> // write_buffer <size> // max_response_header <size> +// forward_proxy_url <url> // dial_timeout <duration> // dial_fallback_delay <duration> // response_header_timeout <duration> @@ -994,6 +995,12 @@ func (h *HTTPTransport) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { return d.Errf("invalid proxy protocol version '%s'", proxyProtocol) } + case "forward_proxy_url": + if !d.NextArg() { + return d.ArgErr() + } + h.ForwardProxyURL = d.Val() + case "dial_timeout": if !d.NextArg() { return d.ArgErr() diff --git a/modules/caddyhttp/reverseproxy/httptransport.go b/modules/caddyhttp/reverseproxy/httptransport.go index 0a803a83a..dd8ece251 100644 --- a/modules/caddyhttp/reverseproxy/httptransport.go +++ b/modules/caddyhttp/reverseproxy/httptransport.go @@ -23,6 +23,7 @@ import ( weakrand "math/rand" "net" "net/http" + "net/url" "os" "reflect" "strings" @@ -71,6 +72,22 @@ type HTTPTransport struct { // connecting to an upstream. Default: off. ProxyProtocol string `json:"proxy_protocol,omitempty"` + // URL to the server that the HTTP transport will use to proxy + // requests to the upstream. See http.Transport.Proxy for + // information regarding supported protocols. This value takes + // precedence over `HTTP_PROXY`, etc. + // + // Providing a value to this parameter results in + // requests flowing through the reverse_proxy in the following + // way: + // + // User Agent -> + // reverse_proxy -> + // forward_proxy_url -> upstream + // + // Default: http.ProxyFromEnvironment + ForwardProxyURL string `json:"forward_proxy_url,omitempty"` + // How long to wait before timing out trying to connect to // an upstream. Default: `3s`. DialTimeout caddy.Duration `json:"dial_timeout,omitempty"` @@ -265,8 +282,21 @@ func (h *HTTPTransport) NewTransport(caddyCtx caddy.Context) (*http.Transport, e return conn, nil } + // negotiate any HTTP/SOCKS proxy for the HTTP transport + var proxy func(*http.Request) (*url.URL, error) + if h.ForwardProxyURL != "" { + pUrl, err := url.Parse(h.ForwardProxyURL) + if err != nil { + return nil, fmt.Errorf("failed to parse transport proxy url: %v", err) + } + caddyCtx.Logger().Info("setting transport proxy url", zap.String("url", h.ForwardProxyURL)) + proxy = http.ProxyURL(pUrl) + } else { + proxy = http.ProxyFromEnvironment + } + rt := &http.Transport{ - Proxy: http.ProxyFromEnvironment, + Proxy: proxy, DialContext: dialContext, MaxConnsPerHost: h.MaxConnsPerHost, ResponseHeaderTimeout: time.Duration(h.ResponseHeaderTimeout), |