Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS
Mirrored from https://github.com/Slazee/caddy.git
Synced Nov 12, 15:45 UTC
reverseproxy: Configurable forward proxy URL (#6114)
Co-authored-by: WeidiDeng <weidi_deng@icloud.com>
Justin Angel committed
Mar 18, 2024 at 00:07 UTC
a9768d2fdefeae8050f1d328e7133e312acd253f
2 files changed
+38
-1
modules/caddyhttp/reverseproxy/caddyfile.go
+7
@@ -907,6 +907,7 @@ func (h *Handler) FinalizeUnmarshalCaddyfile(helper httpcaddyfile.Helper) error
907
// read_buffer <size>
908
// write_buffer <size>
909
// max_response_header <size>
910
+// forward_proxy_url <url>
911
// dial_timeout <duration>
912
// dial_fallback_delay <duration>
913
// response_header_timeout <duration>
@@ -994,6 +995,12 @@ func (h *HTTPTransport) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
995
return d.Errf("invalid proxy protocol version '%s'", proxyProtocol)
996
}
997
998
+ case "forward_proxy_url":
999
+ if !d.NextArg() {
1000
+ return d.ArgErr()
1001
+ }
1002
+ h.ForwardProxyURL = d.Val()
1003
+
1004
case "dial_timeout":
1005
if !d.NextArg() {
1006
return d.ArgErr()
modules/caddyhttp/reverseproxy/httptransport.go
+31
-1
@@ -23,6 +23,7 @@ import (
23
weakrand "math/rand"
24
"net"
25
"net/http"
26
+ "net/url"
27
"os"
28
"reflect"
29
"strings"
@@ -71,6 +72,22 @@ type HTTPTransport struct {
72
// connecting to an upstream. Default: off.
73
ProxyProtocol string `json:"proxy_protocol,omitempty"`
74
75
+ // URL to the server that the HTTP transport will use to proxy
76
+ // requests to the upstream. See http.Transport.Proxy for
77
+ // information regarding supported protocols. This value takes
78
+ // precedence over `HTTP_PROXY`, etc.
79
+ //
80
+ // Providing a value to this parameter results in
81
+ // requests flowing through the reverse_proxy in the following
82
+ // way:
83
+ //
84
+ // User Agent ->
85
+ // reverse_proxy ->
86
+ // forward_proxy_url -> upstream
87
+ //
88
+ // Default: http.ProxyFromEnvironment
89
+ ForwardProxyURL string `json:"forward_proxy_url,omitempty"`
90
+
91
// How long to wait before timing out trying to connect to
92
// an upstream. Default: `3s`.
93
DialTimeout caddy.Duration `json:"dial_timeout,omitempty"`
@@ -265,8 +282,21 @@ func (h *HTTPTransport) NewTransport(caddyCtx caddy.Context) (*http.Transport, e
282
return conn, nil
283
}
284
285
+ // negotiate any HTTP/SOCKS proxy for the HTTP transport
286
+ var proxy func(*http.Request) (*url.URL, error)
287
+ if h.ForwardProxyURL != "" {
288
+ pUrl, err := url.Parse(h.ForwardProxyURL)
289
+ if err != nil {
290
+ return nil, fmt.Errorf("failed to parse transport proxy url: %v", err)
291
+ }
292
+ caddyCtx.Logger().Info("setting transport proxy url", zap.String("url", h.ForwardProxyURL))
293
+ proxy = http.ProxyURL(pUrl)
294
+ } else {
295
+ proxy = http.ProxyFromEnvironment
296
+ }
297
+
298
rt := &http.Transport{
269
- Proxy: http.ProxyFromEnvironment,
299
+ Proxy: proxy,
300
DialContext: dialContext,
301
MaxConnsPerHost: h.MaxConnsPerHost,
302
ResponseHeaderTimeout: time.Duration(h.ResponseHeaderTimeout),