aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJustin Angel <[email protected]>2024-03-18 00:07:25 -0400
committerGitHub <[email protected]>2024-03-18 04:07:25 +0000
commita9768d2fdefeae8050f1d328e7133e312acd253f (patch)
treee7e5d890e81546a8762737e7609471b3ab61263d
parent52822a41cb94fcc9669cd7ba8ac1a0513e4d55f9 (diff)
downloadcaddy-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.go7
-rw-r--r--modules/caddyhttp/reverseproxy/httptransport.go32
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),