@marcel91200 / caddy Mirror · read-only / commits / e338648f
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 13, 13:00 UTC

reverseproxy: Support repeated --to flags in command (#4693)

* feat: Multiple 'to' upstreams in reverse-proxy cmd * Repeat --to for multiple upstreams, rather than comma-separating in a single flag Co-authored-by: Matt Holt <mholt@users.noreply.github.com>

Isaac Parker committed Sep 15, 2022 at 12:35 UTC e338648fed3263200dfd6abc9f8100c6f1c0eb67
1 file changed +32 -8
modules/caddyhttp/reverseproxy/command.go
+32 -8
@@ -41,6 +41,7 @@ A simple but production-ready reverse proxy. Useful for quick deployments,
41 demos, and development.
42
43 Simply shuttles HTTP(S) traffic from the --from address to the --to address.
44 +Multiple --to addresses may be specified by repeating the flag.
45
46 Unless otherwise specified in the addresses, the --from address will be
47 assumed to be HTTPS if a hostname is given, and the --to address will be
@@ -57,7 +58,7 @@ default, all incoming headers are passed through unmodified.)
58 Flags: func() *flag.FlagSet {
59 fs := flag.NewFlagSet("reverse-proxy", flag.ExitOnError)
60 fs.String("from", "localhost", "Address on which to receive traffic")
60 - fs.String("to", "", "Upstream address to which traffic should be sent")
61 + fs.Var(&reverseProxyCmdTo, "to", "Upstream address(es) to which traffic should be sent")
62 fs.Bool("change-host-header", false, "Set upstream Host header to address of upstream")
63 fs.Bool("insecure", false, "Disable TLS verification (WARNING: DISABLES SECURITY BY NOT VERIFYING SSL CERTIFICATES!)")
64 fs.Bool("internal-certs", false, "Use internal CA for issuing certs")
@@ -70,7 +71,6 @@ func cmdReverseProxy(fs caddycmd.Flags) (int, error) {
71 caddy.TrapSignals()
72
73 from := fs.String("from")
73 - to := fs.String("to")
74 changeHost := fs.Bool("change-host-header")
75 insecure := fs.Bool("insecure")
76 internalCerts := fs.Bool("internal-certs")
@@ -78,7 +78,7 @@ func cmdReverseProxy(fs caddycmd.Flags) (int, error) {
78 httpPort := strconv.Itoa(caddyhttp.DefaultHTTPPort)
79 httpsPort := strconv.Itoa(caddyhttp.DefaultHTTPSPort)
80
81 - if to == "" {
81 + if len(reverseProxyCmdTo) == 0 {
82 return caddy.ExitCodeFailedStartup, fmt.Errorf("--to is required")
83 }
84
@@ -106,9 +106,18 @@ func cmdReverseProxy(fs caddycmd.Flags) (int, error) {
106 }
107
108 // set up the upstream address; assume missing information from given parts
109 - toAddr, toScheme, err := parseUpstreamDialAddress(to)
110 - if err != nil {
111 - return caddy.ExitCodeFailedStartup, fmt.Errorf("invalid upstream address %s: %v", to, err)
109 + // mixing schemes isn't supported, so use first defined (if available)
110 + toAddresses := make([]string, len(reverseProxyCmdTo))
111 + var toScheme string
112 + for i, toLoc := range reverseProxyCmdTo {
113 + addr, scheme, err := parseUpstreamDialAddress(toLoc)
114 + if err != nil {
115 + return caddy.ExitCodeFailedStartup, fmt.Errorf("invalid upstream address %s: %v", toLoc, err)
116 + }
117 + if scheme != "" && toScheme != "" {
118 + toScheme = scheme
119 + }
120 + toAddresses[i] = addr
121 }
122
123 // proceed to build the handler and server
@@ -120,9 +129,16 @@ func cmdReverseProxy(fs caddycmd.Flags) (int, error) {
129 }
130 }
131
132 + upstreamPool := UpstreamPool{}
133 + for _, toAddr := range toAddresses {
134 + upstreamPool = append(upstreamPool, &Upstream{
135 + Dial: toAddr,
136 + })
137 + }
138 +
139 handler := Handler{
140 TransportRaw: caddyconfig.JSONModuleObject(ht, "protocol", "http", nil),
125 - Upstreams: UpstreamPool{{Dial: toAddr}},
141 + Upstreams: upstreamPool,
142 }
143
144 if changeHost {
@@ -187,7 +203,15 @@ func cmdReverseProxy(fs caddycmd.Flags) (int, error) {
203 return caddy.ExitCodeFailedStartup, err
204 }
205
190 - fmt.Printf("Caddy proxying %s -> %s\n", fromAddr.String(), toAddr)
206 + for _, to := range toAddresses {
207 + fmt.Printf("Caddy proxying %s -> %s\n", fromAddr.String(), to)
208 + }
209 + if len(toAddresses) > 1 {
210 + fmt.Println("Load balancing policy: random")
211 + }
212
213 select {}
214 }
215 +
216 +// reverseProxyCmdTo holds the parsed values from repeated use of the --to flag.
217 +var reverseProxyCmdTo caddycmd.StringSlice