@marcel91200 / caddy Mirror · read-only / commits / 95c03506
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 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 +}