@@ -23,6 +23,7 @@ import (
23
23
weakrand "math/rand"
24
24
"net"
25
25
"net/http"
26
+ "net/url"
26
27
"os"
27
28
"reflect"
28
29
"strings"
@@ -71,6 +72,22 @@ type HTTPTransport struct {
71
72
// connecting to an upstream. Default: off.
72
73
ProxyProtocol string `json:"proxy_protocol,omitempty"`
73
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
+
74
91
// How long to wait before timing out trying to connect to
75
92
// an upstream. Default: `3s`.
76
93
DialTimeout caddy.Duration `json:"dial_timeout,omitempty"`
@@ -265,8 +282,21 @@ func (h *HTTPTransport) NewTransport(caddyCtx caddy.Context) (*http.Transport, e
265
282
return conn , nil
266
283
}
267
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
+
268
298
rt := & http.Transport {
269
- Proxy : http . ProxyFromEnvironment ,
299
+ Proxy : proxy ,
270
300
DialContext : dialContext ,
271
301
MaxConnsPerHost : h .MaxConnsPerHost ,
272
302
ResponseHeaderTimeout : time .Duration (h .ResponseHeaderTimeout ),
0 commit comments