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.`
This commit is contained in:
Francis Lavoie 2020-05-11 18:50:49 -04:00 committed by GitHub
parent ef6e53bb5f
commit ea7e4b4024
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 92 additions and 24 deletions

View file

@ -18,6 +18,7 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"reflect" "reflect"
"regexp"
"sort" "sort"
"strconv" "strconv"
"strings" "strings"
@ -71,7 +72,6 @@ func (st ServerType) Setup(inputServerBlocks []caddyfile.ServerBlock,
return nil, warnings, err return nil, warnings, err
} }
for _, sb := range originalServerBlocks {
// replace shorthand placeholders (which are // replace shorthand placeholders (which are
// convenient when writing a Caddyfile) with // convenient when writing a Caddyfile) with
// their actual placeholder identifiers or // their actual placeholder identifiers or
@ -81,6 +81,7 @@ func (st ServerType) Setup(inputServerBlocks []caddyfile.ServerBlock,
"{file}", "{http.request.uri.path.file}", "{file}", "{http.request.uri.path.file}",
"{host}", "{http.request.host}", "{host}", "{http.request.host}",
"{hostport}", "{http.request.hostport}", "{hostport}", "{http.request.hostport}",
"{port}", "{http.request.port}",
"{method}", "{http.request.method}", "{method}", "{http.request.method}",
"{path}", "{http.request.uri.path}", "{path}", "{http.request.uri.path}",
"{query}", "{http.request.uri.query}", "{query}", "{http.request.uri.query}",
@ -96,9 +97,30 @@ func (st ServerType) Setup(inputServerBlocks []caddyfile.ServerBlock,
"{tls_client_serial}", "{http.request.tls.client.serial}", "{tls_client_serial}", "{http.request.tls.client.serial}",
"{tls_client_subject}", "{http.request.tls.client.subject}", "{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 {
for _, segment := range sb.block.Segments { for _, segment := range sb.block.Segments {
for i := 0; i < len(segment); i++ { for i := 0; i < len(segment); i++ {
// simple string replacements
segment[i].Text = replacer.Replace(segment[i].Text) 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)
}
} }
} }

View file

@ -539,3 +539,49 @@ func TestLogRollDays(t *testing.T) {
} }
}`) }`)
} }
func TestShorthandParameterizedPlaceholders(t *testing.T) {
caddytest.AssertAdapt(t, `
localhost:80
respond * "{header.content-type} {labels.0} {query.p} {path.0} {re.name.0}"
`, "caddyfile", `{
"apps": {
"http": {
"servers": {
"srv0": {
"listen": [
":80"
],
"routes": [
{
"match": [
{
"host": [
"localhost"
]
}
],
"handle": [
{
"handler": "subroute",
"routes": [
{
"handle": [
{
"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}",
"handler": "static_response"
}
]
}
]
}
],
"terminal": true
}
]
}
}
}
}
}`)
}