From ea7e4b4024f34fd53f8b8f7b5effb353b36cf8e8 Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Mon, 11 May 2020 18:50:49 -0400 Subject: 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.` --- caddyconfig/httpcaddyfile/httptype.go | 70 +++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 24 deletions(-) (limited to 'caddyconfig/httpcaddyfile') diff --git a/caddyconfig/httpcaddyfile/httptype.go b/caddyconfig/httpcaddyfile/httptype.go index 378289c..8e1ca74 100644 --- a/caddyconfig/httpcaddyfile/httptype.go +++ b/caddyconfig/httpcaddyfile/httptype.go @@ -18,6 +18,7 @@ import ( "encoding/json" "fmt" "reflect" + "regexp" "sort" "strconv" "strings" @@ -71,34 +72,55 @@ func (st ServerType) Setup(inputServerBlocks []caddyfile.ServerBlock, return nil, warnings, err } + // replace shorthand placeholders (which are + // convenient when writing a Caddyfile) with + // their actual placeholder identifiers or + // variable names + replacer := strings.NewReplacer( + "{dir}", "{http.request.uri.path.dir}", + "{file}", "{http.request.uri.path.file}", + "{host}", "{http.request.host}", + "{hostport}", "{http.request.hostport}", + "{port}", "{http.request.port}", + "{method}", "{http.request.method}", + "{path}", "{http.request.uri.path}", + "{query}", "{http.request.uri.query}", + "{remote}", "{http.request.remote}", + "{remote_host}", "{http.request.remote.host}", + "{remote_port}", "{http.request.remote.port}", + "{scheme}", "{http.request.scheme}", + "{uri}", "{http.request.uri}", + "{tls_cipher}", "{http.request.tls.cipher_suite}", + "{tls_version}", "{http.request.tls.version}", + "{tls_client_fingerprint}", "{http.request.tls.client.fingerprint}", + "{tls_client_issuer}", "{http.request.tls.client.issuer}", + "{tls_client_serial}", "{http.request.tls.client.serial}", + "{tls_client_subject}", "{http.request.tls.client.subject}", + ) + + // these are placeholders that allow a user-defined final + // parameters, but we still want to provide a shorthand + // for those, so we use a regexp to replace + regexpReplacements := []struct { + search *regexp.Regexp + replace string + }{ + {regexp.MustCompile(`{query\.([\w-]*)}`), "{http.request.uri.query.$1}"}, + {regexp.MustCompile(`{labels\.([\w-]*)}`), "{http.request.host.labels.$1}"}, + {regexp.MustCompile(`{header\.([\w-]*)}`), "{http.request.header.$1}"}, + {regexp.MustCompile(`{path\.([\w-]*)}`), "{http.request.uri.path.$1}"}, + {regexp.MustCompile(`{re\.([\w-]*)\.([\w-]*)}`), "{http.regexp.$1.$2}"}, + } + for _, sb := range originalServerBlocks { - // replace shorthand placeholders (which are - // convenient when writing a Caddyfile) with - // their actual placeholder identifiers or - // variable names - replacer := strings.NewReplacer( - "{dir}", "{http.request.uri.path.dir}", - "{file}", "{http.request.uri.path.file}", - "{host}", "{http.request.host}", - "{hostport}", "{http.request.hostport}", - "{method}", "{http.request.method}", - "{path}", "{http.request.uri.path}", - "{query}", "{http.request.uri.query}", - "{remote}", "{http.request.remote}", - "{remote_host}", "{http.request.remote.host}", - "{remote_port}", "{http.request.remote.port}", - "{scheme}", "{http.request.scheme}", - "{uri}", "{http.request.uri}", - "{tls_cipher}", "{http.request.tls.cipher_suite}", - "{tls_version}", "{http.request.tls.version}", - "{tls_client_fingerprint}", "{http.request.tls.client.fingerprint}", - "{tls_client_issuer}", "{http.request.tls.client.issuer}", - "{tls_client_serial}", "{http.request.tls.client.serial}", - "{tls_client_subject}", "{http.request.tls.client.subject}", - ) for _, segment := range sb.block.Segments { for i := 0; i < len(segment); i++ { + // simple string replacements segment[i].Text = replacer.Replace(segment[i].Text) + // complex regexp replacements + for _, r := range regexpReplacements { + segment[i].Text = r.search.ReplaceAllString(segment[i].Text, r.replace) + } } } -- cgit v1.2.3