@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 130 lines 3.54 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 encode
16
17 import (
18 "strconv"
19
20 "github.com/caddyserver/caddy/v2"
21 "github.com/caddyserver/caddy/v2/caddyconfig"
22 "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
23 "github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile"
24 "github.com/caddyserver/caddy/v2/modules/caddyhttp"
25 )
26
27 func init() {
28 httpcaddyfile.RegisterHandlerDirective("encode", parseCaddyfile)
29 }
30
31 func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error) {
32 enc := new(Encode)
33 err := enc.UnmarshalCaddyfile(h.Dispenser)
34 if err != nil {
35 return nil, err
36 }
37 return enc, nil
38 }
39
40 // UnmarshalCaddyfile sets up the handler from Caddyfile tokens. Syntax:
41 //
42 // encode [<matcher>] <formats...> {
43 // gzip [<level>]
44 // zstd [<level>] {
45 // level <level>
46 // disable_checksum
47 // }
48 // minimum_length <length>
49 // # response matcher block
50 // match {
51 // status <code...>
52 // header <field> [<value>]
53 // }
54 // # or response matcher single line syntax
55 // match [header <field> [<value>]] | [status <code...>]
56 // }
57 //
58 // Specifying the formats on the first line will use those formats' defaults.
59 func (enc *Encode) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
60 d.Next() // consume directive name
61
62 prefer := []string{}
63 remainingArgs := d.RemainingArgs()
64
65 responseMatchers := make(map[string]caddyhttp.ResponseMatcher)
66 for d.NextBlock(0) {
67 switch d.Val() {
68 case "minimum_length":
69 if !d.NextArg() {
70 return d.ArgErr()
71 }
72 minLength, err := strconv.Atoi(d.Val())
73 if err != nil {
74 return err
75 }
76 enc.MinLength = minLength
77 case "match":
78 err := caddyhttp.ParseNamedResponseMatcher(d.NewFromNextSegment(), responseMatchers)
79 if err != nil {
80 return err
81 }
82 matcher := responseMatchers["match"]
83 enc.Matcher = &matcher
84 default:
85 name := d.Val()
86 modID := "http.encoders." + name
87 unm, err := caddyfile.UnmarshalModule(d, modID)
88 if err != nil {
89 return err
90 }
91 encoding, ok := unm.(Encoding)
92 if !ok {
93 return d.Errf("module %s is not an HTTP encoding; is %T", modID, unm)
94 }
95 if enc.EncodingsRaw == nil {
96 enc.EncodingsRaw = make(caddy.ModuleMap)
97 }
98 enc.EncodingsRaw[name] = caddyconfig.JSON(encoding, nil)
99 prefer = append(prefer, name)
100 }
101 }
102
103 if len(prefer) == 0 && len(remainingArgs) == 0 {
104 remainingArgs = []string{"zstd", "gzip"}
105 }
106
107 for _, arg := range remainingArgs {
108 mod, err := caddy.GetModule("http.encoders." + arg)
109 if err != nil {
110 return d.Errf("finding encoder module '%s': %v", mod, err)
111 }
112 encoding, ok := mod.New().(Encoding)
113 if !ok {
114 return d.Errf("module %s is not an HTTP encoding", mod)
115 }
116 if enc.EncodingsRaw == nil {
117 enc.EncodingsRaw = make(caddy.ModuleMap)
118 }
119 enc.EncodingsRaw[arg] = caddyconfig.JSON(encoding, nil)
120 prefer = append(prefer, arg)
121 }
122
123 // use the order in which the encoders were defined.
124 enc.Prefer = prefer
125
126 return nil
127 }
128
129 // Interface guard
130 var _ caddyfile.Unmarshaler = (*Encode)(nil)