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() {
hasArgs = true
field := h.Val()
var value, replacement string
var value string
var replacement *string
if h.NextArg() {
value = h.Val()
}
if h.NextArg() {
replacement = h.Val()
arg := h.Val()
replacement = &arg
}
err := applyHeaderOp(
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
field = strings.TrimSuffix(field, ":")
var value, replacement string
var value string
var replacement *string
if h.NextArg() {
value = h.Val()
}
if h.NextArg() {
replacement = h.Val()
arg := h.Val()
replacement = &arg
}
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
field = strings.TrimSuffix(field, ":")
var value, replacement string
var value string
var replacement *string
if h.NextArg() {
value = h.Val()
}
if h.NextArg() {
replacement = h.Val()
arg := h.Val()
replacement = &arg
if h.NextArg() {
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
// "+" or "-" to specify adding or removing; otherwise, the value
// 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
// complete the substring replacement; in that case, any + or -
// 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)
}
func applyHeaderOp(ops *HeaderOps, respHeaderOps *RespHeaderOps, field, value, replacement string) error {
func applyHeaderOp(ops *HeaderOps, respHeaderOps *RespHeaderOps, field, value string, replacement *string) error {
switch {
case strings.HasPrefix(field, "+"): // append
if ops.Add == nil {
@ -238,7 +244,7 @@ func applyHeaderOp(ops *HeaderOps, respHeaderOps *RespHeaderOps, field, value, r
}
respHeaderOps.Set.Set(field, value)
case replacement != "": // replace
case replacement != nil: // replace
// allow defer shortcut for replace syntax
if strings.HasPrefix(field, ">") && respHeaderOps != nil {
respHeaderOps.Deferred = true
@ -251,7 +257,7 @@ func applyHeaderOp(ops *HeaderOps, respHeaderOps *RespHeaderOps, field, value, r
ops.Replace[field],
Replacement{
SearchRegexp: value,
Replace: replacement,
Replace: *replacement,
},
)

View File

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

View File

@ -683,7 +683,7 @@ func (h *Handler) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
switch len(args) {
case 1:
err = headers.CaddyfileHeaderOp(h.Headers.Request, args[0], "", "")
err = headers.CaddyfileHeaderOp(h.Headers.Request, args[0], "", nil)
case 2:
// some lint checks, I guess
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}") {
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:
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:
return d.ArgErr()
}
@ -721,13 +721,14 @@ func (h *Handler) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
}
}
args := d.RemainingArgs()
switch len(args) {
case 1:
err = headers.CaddyfileHeaderOp(h.Headers.Response.HeaderOps, args[0], "", "")
err = headers.CaddyfileHeaderOp(h.Headers.Response.HeaderOps, args[0], "", nil)
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:
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:
return d.ArgErr()
}