summaryrefslogtreecommitdiff
path: root/modules/caddyhttp/headers
diff options
context:
space:
mode:
Diffstat (limited to 'modules/caddyhttp/headers')
-rw-r--r--modules/caddyhttp/headers/caddyfile.go73
-rw-r--r--modules/caddyhttp/headers/headers.go11
2 files changed, 68 insertions, 16 deletions
diff --git a/modules/caddyhttp/headers/caddyfile.go b/modules/caddyhttp/headers/caddyfile.go
index 12ec8a0..d806005 100644
--- a/modules/caddyhttp/headers/caddyfile.go
+++ b/modules/caddyhttp/headers/caddyfile.go
@@ -24,9 +24,11 @@ import (
func init() {
httpcaddyfile.RegisterHandlerDirective("headers", parseCaddyfile)
+ httpcaddyfile.RegisterHandlerDirective("request_header", parseReqHdrCaddyfile)
}
-// parseCaddyfile sets up the handler from Caddyfile tokens. Syntax:
+// parseCaddyfile sets up the handler for response headers from
+// Caddyfile tokens. Syntax:
//
// headers [<matcher>] [[+|-]<field> <value>] {
// [+][<field>] [<value>]
@@ -43,9 +45,11 @@ func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error)
if h.NextArg() {
hasArgs = true
field := h.Val()
- h.NextArg()
- value := h.Val()
- processCaddyfileLine(hdr, field, value)
+ var value string
+ if h.NextArg() {
+ value = h.Val()
+ }
+ processCaddyfileLineRespHdr(hdr, field, value)
}
// if not, they should be in a block
@@ -58,31 +62,68 @@ func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error)
if h.NextArg() {
value = h.Val()
}
- processCaddyfileLine(hdr, field, value)
+ processCaddyfileLineRespHdr(hdr, field, value)
}
}
return hdr, nil
}
-func processCaddyfileLine(hdr *Headers, field, value string) {
- if strings.HasPrefix(field, "+") {
- if hdr.Response == nil {
- hdr.Response = &RespHeaderOps{HeaderOps: new(HeaderOps)}
+// parseReqHdrCaddyfile sets up the handler for request headers
+// from Caddyfile tokens. Syntax:
+//
+// request_header [<matcher>] [[+|-]<field> <value>]
+//
+func parseReqHdrCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error) {
+ hdr := new(Headers)
+ for h.Next() {
+ if !h.NextArg() {
+ return nil, h.ArgErr()
+ }
+ field := h.Val()
+ var value string
+ if h.NextArg() {
+ value = h.Val()
+ }
+
+ if hdr.Request == nil {
+ hdr.Request = new(HeaderOps)
+ }
+ if strings.HasPrefix(field, "+") {
+ if hdr.Request.Add == nil {
+ hdr.Request.Add = make(http.Header)
+ }
+ hdr.Request.Add.Set(field[1:], value)
+ } else if strings.HasPrefix(field, "-") {
+ hdr.Request.Delete = append(hdr.Request.Delete, field[1:])
+ } else {
+ if hdr.Request.Set == nil {
+ hdr.Request.Set = make(http.Header)
+ }
+ hdr.Request.Set.Set(field, value)
+ }
+
+ if h.NextArg() {
+ return nil, h.ArgErr()
+ }
+ }
+ return hdr, nil
+}
+
+func processCaddyfileLineRespHdr(hdr *Headers, field, value string) {
+ if hdr.Response == nil {
+ hdr.Response = &RespHeaderOps{
+ HeaderOps: new(HeaderOps),
+ Deferred: true,
}
+ }
+ if strings.HasPrefix(field, "+") {
if hdr.Response.Add == nil {
hdr.Response.Add = make(http.Header)
}
hdr.Response.Add.Set(field[1:], value)
} else if strings.HasPrefix(field, "-") {
- if hdr.Response == nil {
- hdr.Response = &RespHeaderOps{HeaderOps: new(HeaderOps)}
- }
hdr.Response.Delete = append(hdr.Response.Delete, field[1:])
- hdr.Response.Deferred = true
} else {
- if hdr.Response == nil {
- hdr.Response = &RespHeaderOps{HeaderOps: new(HeaderOps)}
- }
if hdr.Response.Set == nil {
hdr.Response.Set = make(http.Header)
}
diff --git a/modules/caddyhttp/headers/headers.go b/modules/caddyhttp/headers/headers.go
index e740004..ba9d89d 100644
--- a/modules/caddyhttp/headers/headers.go
+++ b/modules/caddyhttp/headers/headers.go
@@ -58,7 +58,18 @@ type RespHeaderOps struct {
func (h Headers) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error {
repl := r.Context().Value(caddy.ReplacerCtxKey).(caddy.Replacer)
+
apply(h.Request, r.Header, repl)
+
+ // request header's Host is handled specially by the
+ // Go standard library, so if that header was changed,
+ // change it in the Host field since the Header won't
+ // be used
+ if intendedHost := r.Header.Get("Host"); intendedHost != "" {
+ r.Host = intendedHost
+ r.Header.Del("Host")
+ }
+
if h.Response != nil {
if h.Response.Deferred || h.Response.Require != nil {
w = &responseWriterWrapper{