@marcel91200 / caddy Mirror · read-only / commits / ea7e4b40
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, 05:15 UTC

httpcaddyfile: Shorthands for parameterized placeholders (#3305)

* httpcaddyfile: Add shorthands for parameterized placeholders httpcaddyfile: Now with regexp instead httpcaddyfile: Allow dashes, gofmt httpcaddyfile: Compile regexp only once httpcaddyfile: Cleanup struct httpcaddyfile: Optimize the replacers, pull out of the loop httpcaddyfile: Add `{port}` shorthand * httpcaddyfile: Switch `r.` to `re.`

Francis Lavoie committed May 11, 2020 at 18:50 UTC ea7e4b4024f34fd53f8b8f7b5effb353b36cf8e8
2 files changed +92 -24
caddyconfig/httpcaddyfile/httptype.go
+46 -24
@@ -18,6 +18,7 @@ import (
18 "encoding/json"
19 "fmt"
20 "reflect"
21 + "regexp"
22 "sort"
23 "strconv"
24 "strings"
@@ -71,34 +72,55 @@ func (st ServerType) Setup(inputServerBlocks []caddyfile.ServerBlock,
72 return nil, warnings, err
73 }
74
75 + // replace shorthand placeholders (which are
76 + // convenient when writing a Caddyfile) with
77 + // their actual placeholder identifiers or
78 + // variable names
79 + replacer := strings.NewReplacer(
80 + "{dir}", "{http.request.uri.path.dir}",
81 + "{file}", "{http.request.uri.path.file}",
82 + "{host}", "{http.request.host}",
83 + "{hostport}", "{http.request.hostport}",
84 + "{port}", "{http.request.port}",
85 + "{method}", "{http.request.method}",
86 + "{path}", "{http.request.uri.path}",
87 + "{query}", "{http.request.uri.query}",
88 + "{remote}", "{http.request.remote}",
89 + "{remote_host}", "{http.request.remote.host}",
90 + "{remote_port}", "{http.request.remote.port}",
91 + "{scheme}", "{http.request.scheme}",
92 + "{uri}", "{http.request.uri}",
93 + "{tls_cipher}", "{http.request.tls.cipher_suite}",
94 + "{tls_version}", "{http.request.tls.version}",
95 + "{tls_client_fingerprint}", "{http.request.tls.client.fingerprint}",
96 + "{tls_client_issuer}", "{http.request.tls.client.issuer}",
97 + "{tls_client_serial}", "{http.request.tls.client.serial}",
98 + "{tls_client_subject}", "{http.request.tls.client.subject}",
99 + )
100 +
101 + // these are placeholders that allow a user-defined final
102 + // parameters, but we still want to provide a shorthand
103 + // for those, so we use a regexp to replace
104 + regexpReplacements := []struct {
105 + search *regexp.Regexp
106 + replace string
107 + }{
108 + {regexp.MustCompile(`{query\.([\w-]*)}`), "{http.request.uri.query.$1}"},
109 + {regexp.MustCompile(`{labels\.([\w-]*)}`), "{http.request.host.labels.$1}"},
110 + {regexp.MustCompile(`{header\.([\w-]*)}`), "{http.request.header.$1}"},
111 + {regexp.MustCompile(`{path\.([\w-]*)}`), "{http.request.uri.path.$1}"},
112 + {regexp.MustCompile(`{re\.([\w-]*)\.([\w-]*)}`), "{http.regexp.$1.$2}"},
113 + }
114 +
115 for _, sb := range originalServerBlocks {
75 - // replace shorthand placeholders (which are
76 - // convenient when writing a Caddyfile) with
77 - // their actual placeholder identifiers or
78 - // variable names
79 - replacer := strings.NewReplacer(
80 - "{dir}", "{http.request.uri.path.dir}",
81 - "{file}", "{http.request.uri.path.file}",
82 - "{host}", "{http.request.host}",
83 - "{hostport}", "{http.request.hostport}",
84 - "{method}", "{http.request.method}",
85 - "{path}", "{http.request.uri.path}",
86 - "{query}", "{http.request.uri.query}",
87 - "{remote}", "{http.request.remote}",
88 - "{remote_host}", "{http.request.remote.host}",
89 - "{remote_port}", "{http.request.remote.port}",
90 - "{scheme}", "{http.request.scheme}",
91 - "{uri}", "{http.request.uri}",
92 - "{tls_cipher}", "{http.request.tls.cipher_suite}",
93 - "{tls_version}", "{http.request.tls.version}",
94 - "{tls_client_fingerprint}", "{http.request.tls.client.fingerprint}",
95 - "{tls_client_issuer}", "{http.request.tls.client.issuer}",
96 - "{tls_client_serial}", "{http.request.tls.client.serial}",
97 - "{tls_client_subject}", "{http.request.tls.client.subject}",
98 - )
116 for _, segment := range sb.block.Segments {
117 for i := 0; i < len(segment); i++ {
118 + // simple string replacements
119 segment[i].Text = replacer.Replace(segment[i].Text)
120 + // complex regexp replacements
121 + for _, r := range regexpReplacements {
122 + segment[i].Text = r.search.ReplaceAllString(segment[i].Text, r.replace)
123 + }
124 }
125 }
126
caddytest/integration/caddyfile_adapt_test.go
+46
@@ -539,3 +539,49 @@ func TestLogRollDays(t *testing.T) {
539 }
540 }`)
541 }
542 +
543 +func TestShorthandParameterizedPlaceholders(t *testing.T) {
544 + caddytest.AssertAdapt(t, `
545 + localhost:80
546 + respond * "{header.content-type} {labels.0} {query.p} {path.0} {re.name.0}"
547 + `, "caddyfile", `{
548 + "apps": {
549 + "http": {
550 + "servers": {
551 + "srv0": {
552 + "listen": [
553 + ":80"
554 + ],
555 + "routes": [
556 + {
557 + "match": [
558 + {
559 + "host": [
560 + "localhost"
561 + ]
562 + }
563 + ],
564 + "handle": [
565 + {
566 + "handler": "subroute",
567 + "routes": [
568 + {
569 + "handle": [
570 + {
571 + "body": "{http.request.header.content-type} {http.request.host.labels.0} {http.request.uri.query.p} {http.request.uri.path.0} {http.regexp.name.0}",
572 + "handler": "static_response"
573 + }
574 + ]
575 + }
576 + ]
577 + }
578 + ],
579 + "terminal": true
580 + }
581 + ]
582 + }
583 + }
584 + }
585 + }
586 +}`)
587 +}