@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 114 lines 3.3 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 maphandler
16
17 import (
18 "strings"
19
20 "github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile"
21 "github.com/caddyserver/caddy/v2/modules/caddyhttp"
22 )
23
24 func init() {
25 httpcaddyfile.RegisterHandlerDirective("map", parseCaddyfile)
26 }
27
28 // parseCaddyfile sets up the map handler from Caddyfile tokens. Syntax:
29 //
30 // map [<matcher>] <source> <destinations...> {
31 // [~]<input> <outputs...>
32 // default <defaults...>
33 // }
34 //
35 // If the input value is prefixed with a tilde (~), then the input will be parsed as a
36 // regular expression.
37 //
38 // The Caddyfile adapter treats outputs that are a literal hyphen (-) as a null/nil
39 // value. This is useful if you want to fall back to default for that particular output.
40 //
41 // The number of outputs for each mapping must not be more than the number of destinations.
42 // However, for convenience, there may be fewer outputs than destinations and any missing
43 // outputs will be filled in implicitly.
44 func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error) {
45 h.Next() // consume directive name
46
47 var handler Handler
48
49 // source
50 if !h.NextArg() {
51 return nil, h.ArgErr()
52 }
53 handler.Source = h.Val()
54
55 // destinations
56 handler.Destinations = h.RemainingArgs()
57 if len(handler.Destinations) == 0 {
58 return nil, h.Err("missing destination argument(s)")
59 }
60 for _, dest := range handler.Destinations {
61 if shorthand := httpcaddyfile.WasReplacedPlaceholderShorthand(dest); shorthand != "" {
62 return nil, h.Errf("destination %s conflicts with a Caddyfile placeholder shorthand", shorthand)
63 }
64 }
65
66 // mappings
67 for h.NextBlock(0) {
68 // defaults are a special case
69 if h.Val() == "default" {
70 if len(handler.Defaults) > 0 {
71 return nil, h.Err("defaults already defined")
72 }
73 handler.Defaults = h.RemainingArgs()
74 for len(handler.Defaults) < len(handler.Destinations) {
75 handler.Defaults = append(handler.Defaults, "")
76 }
77 continue
78 }
79
80 // every line maps an input value to one or more outputs
81 in := h.Val()
82 var outs []any
83 for h.NextArg() {
84 val := h.ScalarVal()
85 if val == "-" {
86 outs = append(outs, nil)
87 } else {
88 outs = append(outs, val)
89 }
90 }
91
92 // cannot have more outputs than destinations
93 if len(outs) > len(handler.Destinations) {
94 return nil, h.Err("too many outputs")
95 }
96
97 // for convenience, can have fewer outputs than destinations, but the
98 // underlying handler won't accept that, so we fill in nil values
99 for len(outs) < len(handler.Destinations) {
100 outs = append(outs, nil)
101 }
102
103 // create the mapping
104 mapping := Mapping{Outputs: outs}
105 if strings.HasPrefix(in, "~") {
106 mapping.InputRegexp = in[1:]
107 } else {
108 mapping.Input = in
109 }
110
111 handler.Mappings = append(handler.Mappings, mapping)
112 }
113 return handler, nil
114 }