caddyhttp: Allow header replacement with empty string (#6163)

This commit is contained in:
Francis Lavoie 2024-03-21 13:29:32 -04:00 committed by GitHub
parent d13258423d
commit 97a56d860a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 27 additions and 20 deletions

View file

@ -68,12 +68,14 @@ func parseCaddyfile(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error)
if h.NextArg() { if h.NextArg() {
hasArgs = true hasArgs = true
field := h.Val() field := h.Val()
var value, replacement string var value string
var replacement *string
if h.NextArg() { if h.NextArg() {
value = h.Val() value = h.Val()
} }
if h.NextArg() { if h.NextArg() {
replacement = h.Val() arg := h.Val()
replacement = &arg
} }
err := applyHeaderOp( err := applyHeaderOp(
handler.Response.HeaderOps, handler.Response.HeaderOps,
@ -106,12 +108,14 @@ func parseCaddyfile(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error)
// https://caddy.community/t/v2-reverse-proxy-please-add-cors-example-to-the-docs/7349/19 // https://caddy.community/t/v2-reverse-proxy-please-add-cors-example-to-the-docs/7349/19
field = strings.TrimSuffix(field, ":") field = strings.TrimSuffix(field, ":")
var value, replacement string var value string
var replacement *string
if h.NextArg() { if h.NextArg() {
value = h.Val() value = h.Val()
} }
if h.NextArg() { if h.NextArg() {
replacement = h.Val() arg := h.Val()
replacement = &arg
} }
handlerToUse := handler handlerToUse := handler
@ -170,12 +174,14 @@ func parseReqHdrCaddyfile(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue,
// https://caddy.community/t/v2-reverse-proxy-please-add-cors-example-to-the-docs/7349/19 // https://caddy.community/t/v2-reverse-proxy-please-add-cors-example-to-the-docs/7349/19
field = strings.TrimSuffix(field, ":") field = strings.TrimSuffix(field, ":")
var value, replacement string var value string
var replacement *string
if h.NextArg() { if h.NextArg() {
value = h.Val() value = h.Val()
} }
if h.NextArg() { if h.NextArg() {
replacement = h.Val() arg := h.Val()
replacement = &arg
if h.NextArg() { if h.NextArg() {
return nil, h.ArgErr() return nil, h.ArgErr()
} }
@ -200,15 +206,15 @@ func parseReqHdrCaddyfile(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue,
// field, value, and replacement. The field can be prefixed with // field, value, and replacement. The field can be prefixed with
// "+" or "-" to specify adding or removing; otherwise, the value // "+" or "-" to specify adding or removing; otherwise, the value
// will be set (overriding any previous value). If replacement is // will be set (overriding any previous value). If replacement is
// non-empty, value will be treated as a regular expression which // non-nil, value will be treated as a regular expression which
// will be used to search and then replacement will be used to // will be used to search and then replacement will be used to
// complete the substring replacement; in that case, any + or - // complete the substring replacement; in that case, any + or -
// prefix to field will be ignored. // prefix to field will be ignored.
func CaddyfileHeaderOp(ops *HeaderOps, field, value, replacement string) error { func CaddyfileHeaderOp(ops *HeaderOps, field, value string, replacement *string) error {
return applyHeaderOp(ops, nil, field, value, replacement) return applyHeaderOp(ops, nil, field, value, replacement)
} }
func applyHeaderOp(ops *HeaderOps, respHeaderOps *RespHeaderOps, field, value, replacement string) error { func applyHeaderOp(ops *HeaderOps, respHeaderOps *RespHeaderOps, field, value string, replacement *string) error {
switch { switch {
case strings.HasPrefix(field, "+"): // append case strings.HasPrefix(field, "+"): // append
if ops.Add == nil { if ops.Add == nil {
@ -238,7 +244,7 @@ func applyHeaderOp(ops *HeaderOps, respHeaderOps *RespHeaderOps, field, value, r
} }
respHeaderOps.Set.Set(field, value) respHeaderOps.Set.Set(field, value)
case replacement != "": // replace case replacement != nil: // replace
// allow defer shortcut for replace syntax // allow defer shortcut for replace syntax
if strings.HasPrefix(field, ">") && respHeaderOps != nil { if strings.HasPrefix(field, ">") && respHeaderOps != nil {
respHeaderOps.Deferred = true respHeaderOps.Deferred = true
@ -251,7 +257,7 @@ func applyHeaderOp(ops *HeaderOps, respHeaderOps *RespHeaderOps, field, value, r
ops.Replace[field], ops.Replace[field],
Replacement{ Replacement{
SearchRegexp: value, SearchRegexp: value,
Replace: replacement, Replace: *replacement,
}, },
) )

View file

@ -73,11 +73,11 @@ func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error)
switch len(args) { switch len(args) {
case 1: case 1:
err = headers.CaddyfileHeaderOp(&handler.Headers.HeaderOps, args[0], "", "") err = headers.CaddyfileHeaderOp(&handler.Headers.HeaderOps, args[0], "", nil)
case 2: case 2:
err = headers.CaddyfileHeaderOp(&handler.Headers.HeaderOps, args[0], args[1], "") err = headers.CaddyfileHeaderOp(&handler.Headers.HeaderOps, args[0], args[1], nil)
case 3: case 3:
err = headers.CaddyfileHeaderOp(&handler.Headers.HeaderOps, args[0], args[1], args[2]) err = headers.CaddyfileHeaderOp(&handler.Headers.HeaderOps, args[0], args[1], &args[2])
default: default:
return nil, h.ArgErr() return nil, h.ArgErr()
} }

View file

@ -683,7 +683,7 @@ func (h *Handler) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
switch len(args) { switch len(args) {
case 1: case 1:
err = headers.CaddyfileHeaderOp(h.Headers.Request, args[0], "", "") err = headers.CaddyfileHeaderOp(h.Headers.Request, args[0], "", nil)
case 2: case 2:
// some lint checks, I guess // some lint checks, I guess
if strings.EqualFold(args[0], "host") && (args[1] == "{hostport}" || args[1] == "{http.request.hostport}") { if strings.EqualFold(args[0], "host") && (args[1] == "{hostport}" || args[1] == "{http.request.hostport}") {
@ -698,9 +698,9 @@ func (h *Handler) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
if strings.EqualFold(args[0], "x-forwarded-host") && (args[1] == "{host}" || args[1] == "{http.request.host}" || args[1] == "{hostport}" || args[1] == "{http.request.hostport}") { if strings.EqualFold(args[0], "x-forwarded-host") && (args[1] == "{host}" || args[1] == "{http.request.host}" || args[1] == "{hostport}" || args[1] == "{http.request.hostport}") {
caddy.Log().Named("caddyfile").Warn("Unnecessary header_up X-Forwarded-Host: the reverse proxy's default behavior is to pass headers to the upstream") caddy.Log().Named("caddyfile").Warn("Unnecessary header_up X-Forwarded-Host: the reverse proxy's default behavior is to pass headers to the upstream")
} }
err = headers.CaddyfileHeaderOp(h.Headers.Request, args[0], args[1], "") err = headers.CaddyfileHeaderOp(h.Headers.Request, args[0], args[1], nil)
case 3: case 3:
err = headers.CaddyfileHeaderOp(h.Headers.Request, args[0], args[1], args[2]) err = headers.CaddyfileHeaderOp(h.Headers.Request, args[0], args[1], &args[2])
default: default:
return d.ArgErr() return d.ArgErr()
} }
@ -721,13 +721,14 @@ func (h *Handler) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
} }
} }
args := d.RemainingArgs() args := d.RemainingArgs()
switch len(args) { switch len(args) {
case 1: case 1:
err = headers.CaddyfileHeaderOp(h.Headers.Response.HeaderOps, args[0], "", "") err = headers.CaddyfileHeaderOp(h.Headers.Response.HeaderOps, args[0], "", nil)
case 2: case 2:
err = headers.CaddyfileHeaderOp(h.Headers.Response.HeaderOps, args[0], args[1], "") err = headers.CaddyfileHeaderOp(h.Headers.Response.HeaderOps, args[0], args[1], nil)
case 3: case 3:
err = headers.CaddyfileHeaderOp(h.Headers.Response.HeaderOps, args[0], args[1], args[2]) err = headers.CaddyfileHeaderOp(h.Headers.Response.HeaderOps, args[0], args[1], &args[2])
default: default:
return d.ArgErr() return d.ArgErr()
} }