Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS
Mirrored from https://github.com/Slazee/caddy.git
Synced Nov 14, 01:30 UTC
map: Fix regex mappings
It didn't really make sense how we were doing them before. See https://caddy.community/t/map-directive-and-regular-expressions/13866/6?u=matt
Matthew Holt committed
Oct 13, 2021 at 17:58 UTC
95c035060f66577f52158312c75ca379d7ddc21e
2 files changed
+101
-1
modules/caddyhttp/map/map.go
+5
-1
@@ -136,7 +136,11 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhtt
136
if output := m.Outputs[destIdx]; output == nil {
137
continue
138
} else {
139
- output = m.re.ReplaceAllString(input, m.Outputs[destIdx].(string))
139
+ var result []byte
140
+ for _, submatches := range m.re.FindAllStringSubmatchIndex(input, -1) {
141
+ result = m.re.ExpandString(result, m.Outputs[destIdx].(string), input, submatches)
142
+ }
143
+ output = string(result)
144
return output, true
145
}
146
}
modules/caddyhttp/map/map_test.go
new
+96
@@ -0,0 +1,96 @@
1
+package maphandler
2
+
3
+import (
4
+ "context"
5
+ "net/http"
6
+ "net/http/httptest"
7
+ "reflect"
8
+ "testing"
9
+
10
+ "github.com/caddyserver/caddy/v2"
11
+ "github.com/caddyserver/caddy/v2/modules/caddyhttp"
12
+)
13
+
14
+func TestHandler(t *testing.T) {
15
+ for i, tc := range []struct {
16
+ handler Handler
17
+ reqPath string
18
+ expect map[string]interface{}
19
+ }{
20
+ {
21
+ reqPath: "/foo",
22
+ handler: Handler{
23
+ Source: "{http.request.uri.path}",
24
+ Destinations: []string{"{output}"},
25
+ Mappings: []Mapping{
26
+ {
27
+ Input: "/foo",
28
+ Outputs: []interface{}{"FOO"},
29
+ },
30
+ },
31
+ },
32
+ expect: map[string]interface{}{
33
+ "output": "FOO",
34
+ },
35
+ },
36
+ {
37
+ reqPath: "/abcdef",
38
+ handler: Handler{
39
+ Source: "{http.request.uri.path}",
40
+ Destinations: []string{"{output}"},
41
+ Mappings: []Mapping{
42
+ {
43
+ InputRegexp: "(/abc)",
44
+ Outputs: []interface{}{"ABC"},
45
+ },
46
+ },
47
+ },
48
+ expect: map[string]interface{}{
49
+ "output": "ABC",
50
+ },
51
+ },
52
+ {
53
+ reqPath: "/ABCxyzDEF",
54
+ handler: Handler{
55
+ Source: "{http.request.uri.path}",
56
+ Destinations: []string{"{output}"},
57
+ Mappings: []Mapping{
58
+ {
59
+ InputRegexp: "(xyz)",
60
+ Outputs: []interface{}{"...${1}..."},
61
+ },
62
+ },
63
+ },
64
+ expect: map[string]interface{}{
65
+ "output": "...xyz...",
66
+ },
67
+ },
68
+ } {
69
+ if err := tc.handler.Provision(caddy.Context{}); err != nil {
70
+ t.Fatalf("Test %d: Provisioning handler: %v", i, err)
71
+ }
72
+
73
+ req, err := http.NewRequest(http.MethodGet, tc.reqPath, nil)
74
+ if err != nil {
75
+ t.Fatalf("Test %d: Creating request: %v", i, err)
76
+ }
77
+ repl := caddyhttp.NewTestReplacer(req)
78
+ ctx := context.WithValue(req.Context(), caddy.ReplacerCtxKey, repl)
79
+ req = req.WithContext(ctx)
80
+
81
+ rr := httptest.NewRecorder()
82
+ noop := caddyhttp.HandlerFunc(func(_ http.ResponseWriter, _ *http.Request) error { return nil })
83
+
84
+ if err := tc.handler.ServeHTTP(rr, req, noop); err != nil {
85
+ t.Errorf("Test %d: Handler returned error: %v", i, err)
86
+ continue
87
+ }
88
+
89
+ for key, expected := range tc.expect {
90
+ actual, _ := repl.Get(key)
91
+ if !reflect.DeepEqual(actual, expected) {
92
+ t.Errorf("Test %d: Expected %#v but got %#v for {%s}", i, expected, actual, key)
93
+ }
94
+ }
95
+ }
96
+}