From dd86171d6723f6ebc0ddef39174b2c8d1f911f64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=91=E5=A2=A8=E6=B0=B4=E9=B1=BC?= Date: Tue, 28 Mar 2023 05:05:18 +0800 Subject: headers: Support deleting all headers as first op (#5464) * Delete all existing fields when fieldName is `*` * Rearrange deletion before addition in headers * Revert "Rearrange deletion before addition in headers" This reverts commit 1b50eeeccc92ccd660c7896d8283c7d9e5d1fcb0. * Treat deleting all headers as a special case * Apply suggestions from code review Co-authored-by: Matt Holt --------- Co-authored-by: Matt Holt --- modules/caddyhttp/headers/headers.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'modules/caddyhttp/headers') diff --git a/modules/caddyhttp/headers/headers.go b/modules/caddyhttp/headers/headers.go index f8d3fdc..ac1ab94 100644 --- a/modules/caddyhttp/headers/headers.go +++ b/modules/caddyhttp/headers/headers.go @@ -192,6 +192,19 @@ type RespHeaderOps struct { // ApplyTo applies ops to hdr using repl. func (ops HeaderOps) ApplyTo(hdr http.Header, repl *caddy.Replacer) { + // before manipulating headers in other ways, check if there + // is configuration to delete all headers, and do that first + // because if a header is to be added, we don't want to delete + // it also + for _, fieldName := range ops.Delete { + fieldName = repl.ReplaceKnown(fieldName, "") + if fieldName == "*" { + for existingField := range hdr { + delete(hdr, existingField) + } + } + } + // add for fieldName, vals := range ops.Add { fieldName = repl.ReplaceKnown(fieldName, "") @@ -215,6 +228,9 @@ func (ops HeaderOps) ApplyTo(hdr http.Header, repl *caddy.Replacer) { // delete for _, fieldName := range ops.Delete { fieldName = strings.ToLower(repl.ReplaceKnown(fieldName, "")) + if fieldName == "*" { + continue // handled above + } switch { case strings.HasPrefix(fieldName, "*") && strings.HasSuffix(fieldName, "*"): for existingField := range hdr { -- cgit v1.2.3 From e8352aef38642c20ff528836b6581094f087eb99 Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Tue, 16 May 2023 01:18:13 -0400 Subject: headers: Add > Caddyfile shortcut for enabling defer (#5535) --- modules/caddyhttp/headers/caddyfile.go | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'modules/caddyhttp/headers') diff --git a/modules/caddyhttp/headers/caddyfile.go b/modules/caddyhttp/headers/caddyfile.go index a6bec95..d7e644c 100644 --- a/modules/caddyhttp/headers/caddyfile.go +++ b/modules/caddyhttp/headers/caddyfile.go @@ -32,19 +32,20 @@ func init() { // parseCaddyfile sets up the handler for response headers from // Caddyfile tokens. Syntax: // -// header [] [[+|-|?] [] []] { -// [+] [ []] -// ? -// - -// [defer] +// header [] [[+|-|?|>] [] []] { +// [+] [ []] +// ? +// - +// > +// [defer] // } // // Either a block can be opened or a single header field can be configured // in the first line, but not both in the same directive. Header operations // are deferred to write-time if any headers are being deleted or if the // 'defer' subdirective is used. + appends a header value, - deletes a field, -// and ? conditionally sets a value only if the header field is not already -// set. +// ? conditionally sets a value only if the header field is not already set, +// and > sets a field with defer enabled. func parseCaddyfile(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error) { if !h.Next() { return nil, h.ArgErr() @@ -258,6 +259,15 @@ func applyHeaderOp(ops *HeaderOps, respHeaderOps *RespHeaderOps, field, value, r }, ) + case strings.HasPrefix(field, ">"): // set (overwrite) with defer + if ops.Set == nil { + ops.Set = make(http.Header) + } + ops.Set.Set(field[1:], value) + if respHeaderOps != nil { + respHeaderOps.Deferred = true + } + default: // set (overwrite) if ops.Set == nil { ops.Set = make(http.Header) -- cgit v1.2.3 From 3b19aa2b5a77440f8cb4d11e80937935d187f1cd Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Thu, 15 Jun 2023 19:18:55 -0400 Subject: headers: Allow `>` to defer shortcut for replacements (#5574) --- modules/caddyhttp/headers/caddyfile.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'modules/caddyhttp/headers') diff --git a/modules/caddyhttp/headers/caddyfile.go b/modules/caddyhttp/headers/caddyfile.go index d7e644c..2b06910 100644 --- a/modules/caddyhttp/headers/caddyfile.go +++ b/modules/caddyhttp/headers/caddyfile.go @@ -247,10 +247,14 @@ func applyHeaderOp(ops *HeaderOps, respHeaderOps *RespHeaderOps, field, value, r respHeaderOps.Set.Set(field, value) case replacement != "": // replace + // allow defer shortcut for replace syntax + if strings.HasPrefix(field, ">") && respHeaderOps != nil { + respHeaderOps.Deferred = true + } if ops.Replace == nil { ops.Replace = make(map[string][]Replacement) } - field = strings.TrimLeft(field, "+-?") + field = strings.TrimLeft(field, "+-?>") ops.Replace[field] = append( ops.Replace[field], Replacement{ -- cgit v1.2.3 From cd486c25d168caf58f4b6fe5d3252df9432901ec Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Wed, 2 Aug 2023 16:03:26 -0400 Subject: caddyhttp: Make use of `http.ResponseController` (#5654) * caddyhttp: Make use of http.ResponseController Also syncs the reverseproxy implementation with stdlib's which now uses ResponseController as well https://github.com/golang/go/commit/2449bbb5e614954ce9e99c8a481ea2ee73d72d61 * Enable full-duplex for HTTP/1.1 * Appease linter * Add warning for builds with Go 1.20, so it's less surprising to users * Improved godoc for EnableFullDuplex, copied text from stdlib * Only wrap in encode if not already wrapped --- modules/caddyhttp/headers/headers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'modules/caddyhttp/headers') diff --git a/modules/caddyhttp/headers/headers.go b/modules/caddyhttp/headers/headers.go index ac1ab94..ed503ef 100644 --- a/modules/caddyhttp/headers/headers.go +++ b/modules/caddyhttp/headers/headers.go @@ -371,5 +371,5 @@ func (rww *responseWriterWrapper) Write(d []byte) (int, error) { var ( _ caddy.Provisioner = (*Handler)(nil) _ caddyhttp.MiddlewareHandler = (*Handler)(nil) - _ caddyhttp.HTTPInterfaces = (*responseWriterWrapper)(nil) + _ http.ResponseWriter = (*responseWriterWrapper)(nil) ) -- cgit v1.2.3