summaryrefslogtreecommitdiff
path: root/modules/caddyhttp/push/caddyfile.go
diff options
context:
space:
mode:
authorMatt Holt <mholt@users.noreply.github.com>2020-07-20 12:28:40 -0600
committerGitHub <noreply@github.com>2020-07-20 12:28:40 -0600
commit6cea1f239d01fc065bc6f4b22d765d89b6db0152 (patch)
tree3ba2664e1beeb1034f400038749845fa7c08e243 /modules/caddyhttp/push/caddyfile.go
parent2ae8c119279826ef81223e3b2155a08779f3ee8b (diff)
push: Implement HTTP/2 server push (#3573)
* push: Implement HTTP/2 server push (close #3551) * push: Abstract header ops by embedding into new struct type This will allow us to add more fields to customize headers in push-specific ways in the future. * push: Ensure Link resources are pushed before response is written * Change header name from X-Caddy-Push to Caddy-Push
Diffstat (limited to 'modules/caddyhttp/push/caddyfile.go')
-rw-r--r--modules/caddyhttp/push/caddyfile.go99
1 files changed, 99 insertions, 0 deletions
diff --git a/modules/caddyhttp/push/caddyfile.go b/modules/caddyhttp/push/caddyfile.go
new file mode 100644
index 0000000..a70d5d5
--- /dev/null
+++ b/modules/caddyhttp/push/caddyfile.go
@@ -0,0 +1,99 @@
+// Copyright 2015 Matthew Holt and The Caddy Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package push
+
+import (
+ "github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile"
+ "github.com/caddyserver/caddy/v2/modules/caddyhttp"
+ "github.com/caddyserver/caddy/v2/modules/caddyhttp/headers"
+)
+
+func init() {
+ httpcaddyfile.RegisterHandlerDirective("push", parseCaddyfile)
+}
+
+// parseCaddyfile sets up the push handler. Syntax:
+//
+// push [<matcher>] [<resource>] {
+// [GET|HEAD] <resource>
+// headers {
+// [+]<field> [<value|regexp> [<replacement>]]
+// -<field>
+// }
+// }
+//
+// A single resource can be specified inline without opening a
+// block for the most common/simple case. Or, a block can be
+// opened and multiple resources can be specified, one per
+// line, optionally preceded by the method. The headers
+// subdirective can be used to customize the headers that
+// are set on each (synthetic) push request, using the same
+// syntax as the 'header' directive for request headers.
+// Placeholders are accepted in resource and header field
+// name and value and replacement tokens.
+func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error) {
+ handler := new(Handler)
+
+ for h.Next() {
+ if h.NextArg() {
+ handler.Resources = append(handler.Resources, Resource{Target: h.Val()})
+ }
+
+ // optional block
+ for outerNesting := h.Nesting(); h.NextBlock(outerNesting); {
+ switch h.Val() {
+ case "headers":
+ if h.NextArg() {
+ return nil, h.ArgErr()
+ }
+ for innerNesting := h.Nesting(); h.NextBlock(innerNesting); {
+ // include current token, which we treat as an argument here
+ args := []string{h.Val()}
+ args = append(args, h.RemainingArgs()...)
+
+ if handler.Headers == nil {
+ handler.Headers = new(HeaderConfig)
+ }
+ switch len(args) {
+ case 1:
+ headers.CaddyfileHeaderOp(&handler.Headers.HeaderOps, args[0], "", "")
+ case 2:
+ headers.CaddyfileHeaderOp(&handler.Headers.HeaderOps, args[0], args[1], "")
+ case 3:
+ headers.CaddyfileHeaderOp(&handler.Headers.HeaderOps, args[0], args[1], args[2])
+ default:
+ return nil, h.ArgErr()
+ }
+ }
+
+ case "GET", "HEAD":
+ method := h.Val()
+ if !h.NextArg() {
+ return nil, h.ArgErr()
+ }
+ target := h.Val()
+ handler.Resources = append(handler.Resources, Resource{
+ Method: method,
+ Target: target,
+ })
+
+ default:
+ handler.Resources = append(handler.Resources, Resource{Target: h.Val()})
+ }
+ }
+ }
+
+ return handler, nil
+}