@marcel91200 / caddy Mirror · read-only
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 11, 01:00 UTC

master
go 107 lines 3.05 KB
Raw
1 // Copyright 2015 Matthew Holt and The Caddy Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 package push
16
17 import (
18 "github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile"
19 "github.com/caddyserver/caddy/v2/modules/caddyhttp"
20 "github.com/caddyserver/caddy/v2/modules/caddyhttp/headers"
21 )
22
23 func init() {
24 httpcaddyfile.RegisterHandlerDirective("push", parseCaddyfile)
25 }
26
27 // parseCaddyfile sets up the push handler. Syntax:
28 //
29 // push [<matcher>] [<resource>] {
30 // [GET|HEAD] <resource>
31 // headers {
32 // [+]<field> [<value|regexp> [<replacement>]]
33 // -<field>
34 // }
35 // }
36 //
37 // A single resource can be specified inline without opening a
38 // block for the most common/simple case. Or, a block can be
39 // opened and multiple resources can be specified, one per
40 // line, optionally preceded by the method. The headers
41 // subdirective can be used to customize the headers that
42 // are set on each (synthetic) push request, using the same
43 // syntax as the 'header' directive for request headers.
44 // Placeholders are accepted in resource and header field
45 // name and value and replacement tokens.
46 func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error) {
47 h.Next() // consume directive name
48
49 handler := new(Handler)
50
51 // inline resources
52 if h.NextArg() {
53 handler.Resources = append(handler.Resources, Resource{Target: h.Val()})
54 }
55
56 // optional block
57 for h.NextBlock(0) {
58 switch h.Val() {
59 case "headers":
60 if h.NextArg() {
61 return nil, h.ArgErr()
62 }
63 for nesting := h.Nesting(); h.NextBlock(nesting); {
64 var err error
65
66 // include current token, which we treat as an argument here
67 // nolint:prealloc
68 args := []string{h.Val()}
69 args = append(args, h.RemainingArgs()...)
70
71 if handler.Headers == nil {
72 handler.Headers = new(HeaderConfig)
73 }
74
75 switch len(args) {
76 case 1:
77 err = headers.CaddyfileHeaderOp(&handler.Headers.HeaderOps, args[0], "", nil)
78 case 2:
79 err = headers.CaddyfileHeaderOp(&handler.Headers.HeaderOps, args[0], args[1], nil)
80 case 3:
81 err = headers.CaddyfileHeaderOp(&handler.Headers.HeaderOps, args[0], args[1], &args[2])
82 default:
83 return nil, h.ArgErr()
84 }
85
86 if err != nil {
87 return nil, h.Err(err.Error())
88 }
89 }
90
91 case "GET", "HEAD":
92 method := h.Val()
93 if !h.NextArg() {
94 return nil, h.ArgErr()
95 }
96 target := h.Val()
97 handler.Resources = append(handler.Resources, Resource{
98 Method: method,
99 Target: target,
100 })
101
102 default:
103 handler.Resources = append(handler.Resources, Resource{Target: h.Val()})
104 }
105 }
106 return handler, nil
107 }