mirror of
https://github.com/caddyserver/caddy.git
synced 2024-12-27 06:03:48 +03:00
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>
This commit is contained in:
parent
9ad0ebc956
commit
e338648fed
1 changed files with 32 additions and 8 deletions
|
@ -41,6 +41,7 @@ A simple but production-ready reverse proxy. Useful for quick deployments,
|
||||||
demos, and development.
|
demos, and development.
|
||||||
|
|
||||||
Simply shuttles HTTP(S) traffic from the --from address to the --to address.
|
Simply shuttles HTTP(S) traffic from the --from address to the --to address.
|
||||||
|
Multiple --to addresses may be specified by repeating the flag.
|
||||||
|
|
||||||
Unless otherwise specified in the addresses, the --from address will be
|
Unless otherwise specified in the addresses, the --from address will be
|
||||||
assumed to be HTTPS if a hostname is given, and the --to address will be
|
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.)
|
||||||
Flags: func() *flag.FlagSet {
|
Flags: func() *flag.FlagSet {
|
||||||
fs := flag.NewFlagSet("reverse-proxy", flag.ExitOnError)
|
fs := flag.NewFlagSet("reverse-proxy", flag.ExitOnError)
|
||||||
fs.String("from", "localhost", "Address on which to receive traffic")
|
fs.String("from", "localhost", "Address on which to receive traffic")
|
||||||
fs.String("to", "", "Upstream address to which traffic should be sent")
|
fs.Var(&reverseProxyCmdTo, "to", "Upstream address(es) to which traffic should be sent")
|
||||||
fs.Bool("change-host-header", false, "Set upstream Host header to address of upstream")
|
fs.Bool("change-host-header", false, "Set upstream Host header to address of upstream")
|
||||||
fs.Bool("insecure", false, "Disable TLS verification (WARNING: DISABLES SECURITY BY NOT VERIFYING SSL CERTIFICATES!)")
|
fs.Bool("insecure", false, "Disable TLS verification (WARNING: DISABLES SECURITY BY NOT VERIFYING SSL CERTIFICATES!)")
|
||||||
fs.Bool("internal-certs", false, "Use internal CA for issuing certs")
|
fs.Bool("internal-certs", false, "Use internal CA for issuing certs")
|
||||||
|
@ -70,7 +71,6 @@ func cmdReverseProxy(fs caddycmd.Flags) (int, error) {
|
||||||
caddy.TrapSignals()
|
caddy.TrapSignals()
|
||||||
|
|
||||||
from := fs.String("from")
|
from := fs.String("from")
|
||||||
to := fs.String("to")
|
|
||||||
changeHost := fs.Bool("change-host-header")
|
changeHost := fs.Bool("change-host-header")
|
||||||
insecure := fs.Bool("insecure")
|
insecure := fs.Bool("insecure")
|
||||||
internalCerts := fs.Bool("internal-certs")
|
internalCerts := fs.Bool("internal-certs")
|
||||||
|
@ -78,7 +78,7 @@ func cmdReverseProxy(fs caddycmd.Flags) (int, error) {
|
||||||
httpPort := strconv.Itoa(caddyhttp.DefaultHTTPPort)
|
httpPort := strconv.Itoa(caddyhttp.DefaultHTTPPort)
|
||||||
httpsPort := strconv.Itoa(caddyhttp.DefaultHTTPSPort)
|
httpsPort := strconv.Itoa(caddyhttp.DefaultHTTPSPort)
|
||||||
|
|
||||||
if to == "" {
|
if len(reverseProxyCmdTo) == 0 {
|
||||||
return caddy.ExitCodeFailedStartup, fmt.Errorf("--to is required")
|
return caddy.ExitCodeFailedStartup, fmt.Errorf("--to is required")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,9 +106,18 @@ func cmdReverseProxy(fs caddycmd.Flags) (int, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// set up the upstream address; assume missing information from given parts
|
// set up the upstream address; assume missing information from given parts
|
||||||
toAddr, toScheme, err := parseUpstreamDialAddress(to)
|
// mixing schemes isn't supported, so use first defined (if available)
|
||||||
if err != nil {
|
toAddresses := make([]string, len(reverseProxyCmdTo))
|
||||||
return caddy.ExitCodeFailedStartup, fmt.Errorf("invalid upstream address %s: %v", to, err)
|
var toScheme string
|
||||||
|
for i, toLoc := range reverseProxyCmdTo {
|
||||||
|
addr, scheme, err := parseUpstreamDialAddress(toLoc)
|
||||||
|
if err != nil {
|
||||||
|
return caddy.ExitCodeFailedStartup, fmt.Errorf("invalid upstream address %s: %v", toLoc, err)
|
||||||
|
}
|
||||||
|
if scheme != "" && toScheme != "" {
|
||||||
|
toScheme = scheme
|
||||||
|
}
|
||||||
|
toAddresses[i] = addr
|
||||||
}
|
}
|
||||||
|
|
||||||
// proceed to build the handler and server
|
// proceed to build the handler and server
|
||||||
|
@ -120,9 +129,16 @@ func cmdReverseProxy(fs caddycmd.Flags) (int, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
upstreamPool := UpstreamPool{}
|
||||||
|
for _, toAddr := range toAddresses {
|
||||||
|
upstreamPool = append(upstreamPool, &Upstream{
|
||||||
|
Dial: toAddr,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
handler := Handler{
|
handler := Handler{
|
||||||
TransportRaw: caddyconfig.JSONModuleObject(ht, "protocol", "http", nil),
|
TransportRaw: caddyconfig.JSONModuleObject(ht, "protocol", "http", nil),
|
||||||
Upstreams: UpstreamPool{{Dial: toAddr}},
|
Upstreams: upstreamPool,
|
||||||
}
|
}
|
||||||
|
|
||||||
if changeHost {
|
if changeHost {
|
||||||
|
@ -187,7 +203,15 @@ func cmdReverseProxy(fs caddycmd.Flags) (int, error) {
|
||||||
return caddy.ExitCodeFailedStartup, err
|
return caddy.ExitCodeFailedStartup, err
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("Caddy proxying %s -> %s\n", fromAddr.String(), toAddr)
|
for _, to := range toAddresses {
|
||||||
|
fmt.Printf("Caddy proxying %s -> %s\n", fromAddr.String(), to)
|
||||||
|
}
|
||||||
|
if len(toAddresses) > 1 {
|
||||||
|
fmt.Println("Load balancing policy: random")
|
||||||
|
}
|
||||||
|
|
||||||
select {}
|
select {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reverseProxyCmdTo holds the parsed values from repeated use of the --to flag.
|
||||||
|
var reverseProxyCmdTo caddycmd.StringSlice
|
||||||
|
|
Loading…
Reference in a new issue