reverseproxy: Fix host and port on requests; fix Caddyfile parser

This commit is contained in:
Matthew Holt 2019-09-11 18:53:44 -06:00
parent b4dce74e59
commit 758269124e
No known key found for this signature in database
GPG key ID: 2A349DD577D586A5
2 changed files with 128 additions and 94 deletions

View file

@ -376,6 +376,7 @@ func (h *Handler) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
// }
//
func (h *HTTPTransport) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
for d.Next() {
for d.NextBlock(0) {
switch d.Val() {
case "read_buffer":
@ -480,6 +481,7 @@ func (h *HTTPTransport) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
return d.Errf("unrecognized subdirective %s", d.Val())
}
}
}
return nil
}

View file

@ -145,6 +145,26 @@ func (h *Handler) Provision(ctx caddy.Context) error {
var allUpstreams []*Upstream
for _, upstream := range h.Upstreams {
// if a port was not specified (and the network type uses
// ports), then maybe we can figure out the default port
netw, host, port, err := caddy.SplitNetworkAddress(upstream.Dial)
if err != nil && port == "" && !strings.Contains(netw, "unix") {
if host == "" {
// assume all that was given was the host, no port
host = upstream.Dial
}
// a port was not specified, but we may be able to
// infer it if we know the standard ports on which
// the transport protocol operates
if ht, ok := h.Transport.(*HTTPTransport); ok {
defaultPort := "80"
if ht.TLS != nil {
defaultPort = "443"
}
upstream.Dial = caddy.JoinNetworkAddress(netw, host, defaultPort)
}
}
// upstreams are allowed to map to only a single host,
// but an upstream's address may semantically represent
// multiple addresses, so make sure to handle each
@ -474,7 +494,19 @@ func (h Handler) tryAgain(start time.Time, proxyErr error) bool {
// given upstream host. It must modify ONLY the request URL.
func (h Handler) directRequest(req *http.Request, upstream *Upstream) {
if req.URL.Host == "" {
req.URL.Host = upstream.dialInfo.Address
// we need a host, so set the upstream's host address
fullHost := upstream.dialInfo.Address
// but if the port matches the scheme, strip the port because
// it's weird to make a request like http://example.com:80/.
host, port, err := net.SplitHostPort(fullHost)
if err == nil &&
(req.URL.Scheme == "http" && port == "80") ||
(req.URL.Scheme == "https" && port == "443") {
fullHost = host
}
req.URL.Host = fullHost
}
}