Skip to content

Commit

Permalink
Add X-Forwarded-Host by default
Browse files Browse the repository at this point in the history
  • Loading branch information
francislavoie committed Jan 20, 2022
1 parent 10ff29a commit 14649e2
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 3 deletions.
6 changes: 6 additions & 0 deletions modules/caddyhttp/reverseproxy/caddyfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -602,9 +602,15 @@ func (h *Handler) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
if strings.EqualFold(args[0], "host") && (args[1] == "{hostport}" || args[1] == "{http.request.hostport}") {
log.Printf("[WARNING] Unnecessary header_up ('Host' field): the reverse proxy's default behavior is to pass headers to the upstream")
}
if strings.EqualFold(args[0], "x-forwarded-for") && (args[1] == "{remote}" || args[1] == "{http.request.remote}" || args[1] == "{remote_host}" || args[1] == "{http.request.remote.host}") {
log.Printf("[WARNING] Unnecessary header_up ('X-Forwarded-For' field): the reverse proxy's default behavior is to pass headers to the upstream")
}
if strings.EqualFold(args[0], "x-forwarded-proto") && (args[1] == "{scheme}" || args[1] == "{http.request.scheme}") {
log.Printf("[WARNING] Unnecessary header_up ('X-Forwarded-Proto' field): the reverse proxy's default behavior is to pass headers to the upstream")
}
if strings.EqualFold(args[0], "x-forwarded-host") && (args[1] == "{host}" || args[1] == "{http.request.host}" || args[1] == "{hostport}" || args[1] == "{http.request.hostport}") {
log.Printf("[WARNING] Unnecessary header_up ('X-Forwarded-Host' field): the reverse proxy's default behavior is to pass headers to the upstream")
}
err = headers.CaddyfileHeaderOp(h.Headers.Request, args[0], args[1], "")
case 3:
err = headers.CaddyfileHeaderOp(h.Headers.Request, args[0], args[1], args[2])
Expand Down
26 changes: 23 additions & 3 deletions modules/caddyhttp/reverseproxy/reverseproxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ type Handler struct {
// By default, all headers are passed-thru without changes,
// with the exceptions of special hop-by-hop headers.
//
// X-Forwarded-For and X-Forwarded-Proto are also set implicitly.
// X-Forwarded-For, X-Forwarded-Proto and X-Forwarded-Host
// are also set implicitly.
Headers *headers.Handler `json:"headers,omitempty"`

// If true, the entire request body will be read and buffered
Expand Down Expand Up @@ -595,6 +596,7 @@ func (h Handler) addForwardedHeaders(req *http.Request) error {
// potentially trusting a header that came from the client
req.Header.Del("X-Forwarded-For")
req.Header.Del("X-Forwarded-Proto")
req.Header.Del("X-Forwarded-Host")
return nil
}

Expand Down Expand Up @@ -624,12 +626,13 @@ func (h Handler) addForwardedHeaders(req *http.Request) error {
req.Header.Set("X-Forwarded-For", clientIP)
}

// Set X-Forwarded-Proto; many backend apps expect this too
// Set X-Forwarded-Proto; many backend apps expect this,
// so that they can properly craft URLs with the right
// scheme to match the original request
proto := "https"
if req.TLS == nil {
proto = "http"
}

prior, ok = req.Header["X-Forwarded-Proto"]
omit = ok && prior == nil
if trusted && len(prior) > 0 {
Expand All @@ -639,6 +642,23 @@ func (h Handler) addForwardedHeaders(req *http.Request) error {
req.Header.Set("X-Forwarded-Proto", proto)
}

// Set X-Forwarded-Host; often this is redundant because
// we pass through the request Host as-is, but in situations
// where we proxy over HTTPS, the user may need to override
// Host themselves, so it's helpful to send the original too.
host, _, err := net.SplitHostPort(req.Host)
if err != nil {
host = req.Host // OK; there probably was no port
}
prior, ok = req.Header["X-Forwarded-Host"]
omit = ok && prior == nil
if trusted && len(prior) > 0 {
host = prior[0]
}
if !omit {
req.Header.Set("X-Forwarded-Host", host)
}

return nil
}

Expand Down

0 comments on commit 14649e2

Please sign in to comment.