@marcel91200 / caddy Mirror · read-only
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 11, 01:00 UTC

master
go 105 lines 4.12 KB
Raw
1 package httpcaddyfile
2
3 import (
4 "regexp"
5 "strings"
6
7 "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
8 )
9
10 type ComplexShorthandReplacer struct {
11 search *regexp.Regexp
12 replace string
13 }
14
15 type ShorthandReplacer struct {
16 complex []ComplexShorthandReplacer
17 simple *strings.Replacer
18 }
19
20 func NewShorthandReplacer() ShorthandReplacer {
21 // replace shorthand placeholders (which are convenient
22 // when writing a Caddyfile) with their actual placeholder
23 // identifiers or variable names
24 replacer := strings.NewReplacer(placeholderShorthands()...)
25
26 // these are placeholders that allow a user-defined final
27 // parameters, but we still want to provide a shorthand
28 // for those, so we use a regexp to replace
29 regexpReplacements := []ComplexShorthandReplacer{
30 {regexp.MustCompile(`{header\.([\w-]*)}`), "{http.request.header.$1}"},
31 {regexp.MustCompile(`{cookie\.([\w-]*)}`), "{http.request.cookie.$1}"},
32 {regexp.MustCompile(`{labels\.([\w-]*)}`), "{http.request.host.labels.$1}"},
33 {regexp.MustCompile(`{path\.([\w-]*)}`), "{http.request.uri.path.$1}"},
34 {regexp.MustCompile(`{file\.([\w-]*)}`), "{http.request.uri.path.file.$1}"},
35 {regexp.MustCompile(`{query\.([\w-]*)}`), "{http.request.uri.query.$1}"},
36 {regexp.MustCompile(`{re\.([\w-\.]*)}`), "{http.regexp.$1}"},
37 {regexp.MustCompile(`{vars\.([\w-]*)}`), "{http.vars.$1}"},
38 {regexp.MustCompile(`{rp\.([\w-\.]*)}`), "{http.reverse_proxy.$1}"},
39 {regexp.MustCompile(`{resp\.([\w-\.]*)}`), "{http.intercept.$1}"},
40 {regexp.MustCompile(`{err\.([\w-\.]*)}`), "{http.error.$1}"},
41 {regexp.MustCompile(`{file_match\.([\w-]*)}`), "{http.matchers.file.$1}"},
42 }
43
44 return ShorthandReplacer{
45 complex: regexpReplacements,
46 simple: replacer,
47 }
48 }
49
50 // placeholderShorthands returns a slice of old-new string pairs,
51 // where the left of the pair is a placeholder shorthand that may
52 // be used in the Caddyfile, and the right is the replacement.
53 func placeholderShorthands() []string {
54 return []string{
55 "{host}", "{http.request.host}",
56 "{hostport}", "{http.request.hostport}",
57 "{port}", "{http.request.port}",
58 "{orig_method}", "{http.request.orig_method}",
59 "{orig_uri}", "{http.request.orig_uri}",
60 "{orig_path}", "{http.request.orig_uri.path}",
61 "{orig_dir}", "{http.request.orig_uri.path.dir}",
62 "{orig_file}", "{http.request.orig_uri.path.file}",
63 "{orig_query}", "{http.request.orig_uri.query}",
64 "{orig_?query}", "{http.request.orig_uri.prefixed_query}",
65 "{method}", "{http.request.method}",
66 "{uri}", "{http.request.uri}",
67 "{%uri}", "{http.request.uri_escaped}",
68 "{path}", "{http.request.uri.path}",
69 "{%path}", "{http.request.uri.path_escaped}",
70 "{dir}", "{http.request.uri.path.dir}",
71 "{file}", "{http.request.uri.path.file}",
72 "{query}", "{http.request.uri.query}",
73 "{%query}", "{http.request.uri.query_escaped}",
74 "{?query}", "{http.request.uri.prefixed_query}",
75 "{remote}", "{http.request.remote}",
76 "{remote_host}", "{http.request.remote.host}",
77 "{remote_port}", "{http.request.remote.port}",
78 "{scheme}", "{http.request.scheme}",
79 "{uuid}", "{http.request.uuid}",
80 "{tls_cipher}", "{http.request.tls.cipher_suite}",
81 "{tls_version}", "{http.request.tls.version}",
82 "{tls_client_fingerprint}", "{http.request.tls.client.fingerprint}",
83 "{tls_client_issuer}", "{http.request.tls.client.issuer}",
84 "{tls_client_serial}", "{http.request.tls.client.serial}",
85 "{tls_client_subject}", "{http.request.tls.client.subject}",
86 "{tls_client_certificate_pem}", "{http.request.tls.client.certificate_pem}",
87 "{tls_client_certificate_der_base64}", "{http.request.tls.client.certificate_der_base64}",
88 "{upstream_hostport}", "{http.reverse_proxy.upstream.hostport}",
89 "{client_ip}", "{http.vars.client_ip}",
90 }
91 }
92
93 // ApplyToSegment replaces shorthand placeholder to its full placeholder, understandable by Caddy.
94 func (s ShorthandReplacer) ApplyToSegment(segment *caddyfile.Segment) {
95 if segment != nil {
96 for i := 0; i < len(*segment); i++ {
97 // simple string replacements
98 (*segment)[i].Text = s.simple.Replace((*segment)[i].Text)
99 // complex regexp replacements
100 for _, r := range s.complex {
101 (*segment)[i].Text = r.search.ReplaceAllString((*segment)[i].Text, r.replace)
102 }
103 }
104 }
105 }