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, 05:15 UTC
httpcaddyfile: Allow named matchers in `route` blocks (#3632)
Francis Lavoie committed
Aug 5, 2020 at 15:42 UTC
584eba94a4e06af9ce7efc91fb914f84d7a6a48c
3 files changed
+161
-30
caddyconfig/httpcaddyfile/builtins.go
+16
-29
@@ -480,36 +480,23 @@ func parseRespond(h Helper) (caddyhttp.MiddlewareHandler, error) {
480
func parseRoute(h Helper) (caddyhttp.MiddlewareHandler, error) {
481
sr := new(caddyhttp.Subroute)
482
483
- for h.Next() {
484
- for nesting := h.Nesting(); h.NextBlock(nesting); {
485
- dir := h.Val()
486
-
487
- dirFunc, ok := registeredDirectives[dir]
488
- if !ok {
489
- return nil, h.Errf("unrecognized directive: %s", dir)
490
- }
491
-
492
- subHelper := h
493
- subHelper.Dispenser = h.NewFromNextSegment()
483
+ allResults, err := parseSegmentAsConfig(h)
484
+ if err != nil {
485
+ return nil, err
486
+ }
487
495
- results, err := dirFunc(subHelper)
496
- if err != nil {
497
- return nil, h.Errf("parsing caddyfile tokens for '%s': %v", dir, err)
498
- }
499
- for _, result := range results {
500
- switch handler := result.Value.(type) {
501
- case caddyhttp.Route:
502
- sr.Routes = append(sr.Routes, handler)
503
- case caddyhttp.Subroute:
504
- // directives which return a literal subroute instead of a route
505
- // means they intend to keep those handlers together without
506
- // them being reordered; we're doing that anyway since we're in
507
- // the route directive, so just append its handlers
508
- sr.Routes = append(sr.Routes, handler.Routes...)
509
- default:
510
- return nil, h.Errf("%s directive returned something other than an HTTP route or subroute: %#v (only handler directives can be used in routes)", dir, result.Value)
511
- }
512
- }
488
+ for _, result := range allResults {
489
+ switch handler := result.Value.(type) {
490
+ case caddyhttp.Route:
491
+ sr.Routes = append(sr.Routes, handler)
492
+ case caddyhttp.Subroute:
493
+ // directives which return a literal subroute instead of a route
494
+ // means they intend to keep those handlers together without
495
+ // them being reordered; we're doing that anyway since we're in
496
+ // the route directive, so just append its handlers
497
+ sr.Routes = append(sr.Routes, handler.Routes...)
498
+ default:
499
+ return nil, h.Errf("%s directive returned something other than an HTTP route or subroute: %#v (only handler directives can be used in routes)", result.directive, result.Value)
500
}
501
}
502
caddyconfig/httpcaddyfile/directives.go
+13
-1
@@ -269,6 +269,18 @@ func (h Helper) NewBindAddresses(addrs []string) []ConfigValue {
269
// are themselves treated as directives, from which a subroute is built
270
// and returned.
271
func ParseSegmentAsSubroute(h Helper) (caddyhttp.MiddlewareHandler, error) {
272
+ allResults, err := parseSegmentAsConfig(h)
273
+ if err != nil {
274
+ return nil, err
275
+ }
276
+
277
+ return buildSubroute(allResults, h.groupCounter)
278
+}
279
+
280
+// parseSegmentAsConfig parses the segment such that its subdirectives
281
+// are themselves treated as directives, including named matcher definitions,
282
+// and the raw Config structs are returned.
283
+func parseSegmentAsConfig(h Helper) ([]ConfigValue, error) {
284
var allResults []ConfigValue
285
286
for h.Next() {
@@ -319,7 +331,7 @@ func ParseSegmentAsSubroute(h Helper) (caddyhttp.MiddlewareHandler, error) {
331
}
332
}
333
322
- return buildSubroute(allResults, h.groupCounter)
334
+ return allResults, nil
335
}
336
337
// ConfigValue represents a value to be added to the final
caddytest/integration/caddyfile_adapt/php_fastcgi_expanded_form.txt
new
+132
@@ -0,0 +1,132 @@
1
+:8886
2
+
3
+route {
4
+ # Add trailing slash for directory requests
5
+ @canonicalPath {
6
+ file {
7
+ try_files {path}/index.php
8
+ }
9
+ not path */
10
+ }
11
+ redir @canonicalPath {path}/ 308
12
+
13
+ # If the requested file does not exist, try index files
14
+ @indexFiles {
15
+ file {
16
+ try_files {path} {path}/index.php index.php
17
+ split_path .php
18
+ }
19
+ }
20
+ rewrite @indexFiles {http.matchers.file.relative}
21
+
22
+ # Proxy PHP files to the FastCGI responder
23
+ @phpFiles {
24
+ path *.php
25
+ }
26
+ reverse_proxy @phpFiles 127.0.0.1:9000 {
27
+ transport fastcgi {
28
+ split .php
29
+ }
30
+ }
31
+}
32
+----------
33
+{
34
+ "apps": {
35
+ "http": {
36
+ "servers": {
37
+ "srv0": {
38
+ "listen": [
39
+ ":8886"
40
+ ],
41
+ "routes": [
42
+ {
43
+ "handle": [
44
+ {
45
+ "handler": "subroute",
46
+ "routes": [
47
+ {
48
+ "handle": [
49
+ {
50
+ "handler": "static_response",
51
+ "headers": {
52
+ "Location": [
53
+ "{http.request.uri.path}/"
54
+ ]
55
+ },
56
+ "status_code": 308
57
+ }
58
+ ],
59
+ "match": [
60
+ {
61
+ "file": {
62
+ "try_files": [
63
+ "{http.request.uri.path}/index.php"
64
+ ]
65
+ },
66
+ "not": [
67
+ {
68
+ "path": [
69
+ "*/"
70
+ ]
71
+ }
72
+ ]
73
+ }
74
+ ]
75
+ },
76
+ {
77
+ "handle": [
78
+ {
79
+ "handler": "rewrite",
80
+ "uri": "{http.matchers.file.relative}"
81
+ }
82
+ ],
83
+ "match": [
84
+ {
85
+ "file": {
86
+ "split_path": [
87
+ ".php"
88
+ ],
89
+ "try_files": [
90
+ "{http.request.uri.path}",
91
+ "{http.request.uri.path}/index.php",
92
+ "index.php"
93
+ ]
94
+ }
95
+ }
96
+ ]
97
+ },
98
+ {
99
+ "handle": [
100
+ {
101
+ "handler": "reverse_proxy",
102
+ "transport": {
103
+ "protocol": "fastcgi",
104
+ "split_path": [
105
+ ".php"
106
+ ]
107
+ },
108
+ "upstreams": [
109
+ {
110
+ "dial": "127.0.0.1:9000"
111
+ }
112
+ ]
113
+ }
114
+ ],
115
+ "match": [
116
+ {
117
+ "path": [
118
+ "*.php"
119
+ ]
120
+ }
121
+ ]
122
+ }
123
+ ]
124
+ }
125
+ ]
126
+ }
127
+ ]
128
+ }
129
+ }
130
+ }
131
+ }
132
+}
\ No newline at end of file