@marcel91200 / caddy Mirror · read-only / commits / 95d94461
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

Export Replacer and use concrete type instead of interface

The interface was only making things difficult; a concrete pointer is probably best.

Matthew Holt committed Dec 29, 2019 at 13:12 UTC 95d944613bffce1cee3783568ae229e116168ba4
19 files changed +128 -134
modules/caddyhttp/caddyauth/caddyauth.go
+1 -1
@@ -76,7 +76,7 @@ func (a Authentication) ServeHTTP(w http.ResponseWriter, r *http.Request, next c
76 return caddyhttp.Error(http.StatusUnauthorized, fmt.Errorf("not authenticated"))
77 }
78
79 - repl := r.Context().Value(caddy.ReplacerCtxKey).(caddy.Replacer)
79 + repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
80 repl.Set("http.authentication.user.id", user.ID)
81
82 return next.ServeHTTP(w, r)
modules/caddyhttp/fileserver/browse.go
+2 -2
@@ -52,7 +52,7 @@ func (fsrv *FileServer) serveBrowse(dirPath string, w http.ResponseWriter, r *ht
52 }
53 defer dir.Close()
54
55 - repl := r.Context().Value(caddy.ReplacerCtxKey).(caddy.Replacer)
55 + repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
56
57 // calling path.Clean here prevents weird breadcrumbs when URL paths are sketchy like /%2e%2e%2f
58 listing, err := fsrv.loadDirectoryContents(dir, path.Clean(r.URL.Path), repl)
@@ -87,7 +87,7 @@ func (fsrv *FileServer) serveBrowse(dirPath string, w http.ResponseWriter, r *ht
87 return nil
88 }
89
90 -func (fsrv *FileServer) loadDirectoryContents(dir *os.File, urlPath string, repl caddy.Replacer) (browseListing, error) {
90 +func (fsrv *FileServer) loadDirectoryContents(dir *os.File, urlPath string, repl *caddy.Replacer) (browseListing, error) {
91 files, err := dir.Readdir(-1)
92 if err != nil {
93 return browseListing{}, err
modules/caddyhttp/fileserver/browselisting.go
+1 -1
@@ -27,7 +27,7 @@ import (
27 "github.com/dustin/go-humanize"
28 )
29
30 -func (fsrv *FileServer) directoryListing(files []os.FileInfo, canGoUp bool, urlPath string, repl caddy.Replacer) browseListing {
30 +func (fsrv *FileServer) directoryListing(files []os.FileInfo, canGoUp bool, urlPath string, repl *caddy.Replacer) browseListing {
31 filesToHide := fsrv.transformHidePaths(repl)
32
33 var (
modules/caddyhttp/fileserver/matcher.go
+2 -2
@@ -126,7 +126,7 @@ func (m MatchFile) Validate() error {
126 // - http.matchers.file.relative
127 // - http.matchers.file.absolute
128 func (m MatchFile) Match(r *http.Request) bool {
129 - repl := r.Context().Value(caddy.ReplacerCtxKey).(caddy.Replacer)
129 + repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
130 rel, abs, matched := m.selectFile(r)
131 if matched {
132 repl.Set("http.matchers.file.relative", rel)
@@ -140,7 +140,7 @@ func (m MatchFile) Match(r *http.Request) bool {
140 // It returns the root-relative path to the matched file, the full
141 // or absolute path, and whether a match was made.
142 func (m MatchFile) selectFile(r *http.Request) (rel, abs string, matched bool) {
143 - repl := r.Context().Value(caddy.ReplacerCtxKey).(caddy.Replacer)
143 + repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
144
145 root := repl.ReplaceAll(m.Root, ".")
146
modules/caddyhttp/fileserver/staticfiles.go
+2 -2
@@ -106,7 +106,7 @@ func (fsrv *FileServer) Provision(ctx caddy.Context) error {
106 }
107
108 func (fsrv *FileServer) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error {
109 - repl := r.Context().Value(caddy.ReplacerCtxKey).(caddy.Replacer)
109 + repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
110
111 filesToHide := fsrv.transformHidePaths(repl)
112
@@ -293,7 +293,7 @@ func mapDirOpenError(originalErr error, name string) error {
293
294 // transformHidePaths performs replacements for all the elements of
295 // fsrv.Hide and returns a new list of the transformed values.
296 -func (fsrv *FileServer) transformHidePaths(repl caddy.Replacer) []string {
296 +func (fsrv *FileServer) transformHidePaths(repl *caddy.Replacer) []string {
297 hide := make([]string, len(fsrv.Hide))
298 for i := range fsrv.Hide {
299 hide[i] = repl.ReplaceAll(fsrv.Hide[i], "")
modules/caddyhttp/headers/headers.go
+4 -4
@@ -88,7 +88,7 @@ func (h Handler) Validate() error {
88 }
89
90 func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error {
91 - repl := r.Context().Value(caddy.ReplacerCtxKey).(caddy.Replacer)
91 + repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
92
93 if h.Request != nil {
94 h.Request.ApplyToRequest(r)
@@ -182,7 +182,7 @@ type RespHeaderOps struct {
182 }
183
184 // ApplyTo applies ops to hdr using repl.
185 -func (ops HeaderOps) ApplyTo(hdr http.Header, repl caddy.Replacer) {
185 +func (ops HeaderOps) ApplyTo(hdr http.Header, repl *caddy.Replacer) {
186 // add
187 for fieldName, vals := range ops.Add {
188 fieldName = repl.ReplaceAll(fieldName, "")
@@ -249,7 +249,7 @@ func (ops HeaderOps) ApplyTo(hdr http.Header, repl caddy.Replacer) {
249 // header which the standard library does not include with the
250 // header map with all the others. This method mutates r.Host.
251 func (ops HeaderOps) ApplyToRequest(r *http.Request) {
252 - repl := r.Context().Value(caddy.ReplacerCtxKey).(caddy.Replacer)
252 + repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
253
254 // capture the current Host header so we can
255 // reset to it when we're done
@@ -285,7 +285,7 @@ func (ops HeaderOps) ApplyToRequest(r *http.Request) {
285 // operations until WriteHeader is called.
286 type responseWriterWrapper struct {
287 *caddyhttp.ResponseWriterWrapper
288 - replacer caddy.Replacer
288 + replacer *caddy.Replacer
289 require *caddyhttp.ResponseMatcher
290 headerOps *HeaderOps
291 wroteHeader bool
modules/caddyhttp/matchers.go
+5 -7
@@ -118,7 +118,7 @@ func (m MatchHost) Match(r *http.Request) bool {
118 reqHost = strings.TrimSuffix(reqHost, "]")
119 }
120
121 - repl := r.Context().Value(caddy.ReplacerCtxKey).(caddy.Replacer)
121 + repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
122
123 outer:
124 for _, host := range m {
@@ -223,7 +223,7 @@ func (MatchPathRE) CaddyModule() caddy.ModuleInfo {
223
224 // Match returns true if r matches m.
225 func (m MatchPathRE) Match(r *http.Request) bool {
226 - repl := r.Context().Value(caddy.ReplacerCtxKey).(caddy.Replacer)
226 + repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
227 return m.MatchRegexp.Match(r.URL.Path, repl)
228 }
229
@@ -380,7 +380,7 @@ func (m *MatchHeaderRE) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
380 // Match returns true if r matches m.
381 func (m MatchHeaderRE) Match(r *http.Request) bool {
382 for field, rm := range m {
383 - repl := r.Context().Value(caddy.ReplacerCtxKey).(caddy.Replacer)
383 + repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
384 match := rm.Match(r.Header.Get(field), repl)
385 if !match {
386 return false
@@ -652,10 +652,8 @@ func (mre *MatchRegexp) Validate() error {
652 // Match returns true if input matches the compiled regular
653 // expression in mre. It sets values on the replacer repl
654 // associated with capture groups, using the given scope
655 -// (namespace). Capture groups stored to repl will take on
656 -// the name "http.matchers.<scope>.<mre.Name>.<N>" where
657 -// <N> is the name or number of the capture group.
658 -func (mre *MatchRegexp) Match(input string, repl caddy.Replacer) bool {
655 +// (namespace).
656 +func (mre *MatchRegexp) Match(input string, repl *caddy.Replacer) bool {
657 matches := mre.compiled.FindStringSubmatch(input)
658 if matches == nil {
659 return false
modules/caddyhttp/replacer.go
+1 -1
@@ -26,7 +26,7 @@ import (
26 "github.com/caddyserver/caddy/v2"
27 )
28
29 -func addHTTPVarsToReplacer(repl caddy.Replacer, req *http.Request, w http.ResponseWriter) {
29 +func addHTTPVarsToReplacer(repl *caddy.Replacer, req *http.Request, w http.ResponseWriter) {
30 httpVars := func(key string) (string, bool) {
31 if req != nil {
32 // query string parameters
modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go
+1 -1
@@ -148,7 +148,7 @@ func (t Transport) RoundTrip(r *http.Request) (*http.Response, error) {
148
149 // buildEnv returns a set of CGI environment variables for the request.
150 func (t Transport) buildEnv(r *http.Request) (map[string]string, error) {
151 - repl := r.Context().Value(caddy.ReplacerCtxKey).(caddy.Replacer)
151 + repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
152
153 var env map[string]string
154
modules/caddyhttp/reverseproxy/hosts.go
+1 -1
@@ -204,7 +204,7 @@ func (di DialInfo) String() string {
204
205 // fillDialInfo returns a filled DialInfo for the given upstream, using
206 // the given Replacer. Note that the returned value is not a pointer.
207 -func fillDialInfo(upstream *Upstream, repl caddy.Replacer) (DialInfo, error) {
207 +func fillDialInfo(upstream *Upstream, repl *caddy.Replacer) (DialInfo, error) {
208 dial := repl.ReplaceAll(upstream.Dial, "")
209 addr, err := caddy.ParseNetworkAddress(dial)
210 if err != nil {
modules/caddyhttp/reverseproxy/reverseproxy.go
+2 -2
@@ -263,7 +263,7 @@ func (h *Handler) Cleanup() error {
263 }
264
265 func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error {
266 - repl := r.Context().Value(caddy.ReplacerCtxKey).(caddy.Replacer)
266 + repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
267
268 // if enabled, buffer client request;
269 // this should only be enabled if the
@@ -507,7 +507,7 @@ func (h *Handler) reverseProxy(rw http.ResponseWriter, req *http.Request, di Dia
507 if h.Headers != nil && h.Headers.Response != nil {
508 if h.Headers.Response.Require == nil ||
509 h.Headers.Response.Require.Match(res.StatusCode, rw.Header()) {
510 - repl := req.Context().Value(caddy.ReplacerCtxKey).(caddy.Replacer)
510 + repl := req.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
511 h.Headers.Response.ApplyTo(rw.Header(), repl)
512 }
513 }
modules/caddyhttp/rewrite/rewrite.go
+3 -3
@@ -91,7 +91,7 @@ func (rewr Rewrite) Validate() error {
91 }
92
93 func (rewr Rewrite) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error {
94 - repl := r.Context().Value(caddy.ReplacerCtxKey).(caddy.Replacer)
94 + repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
95
96 logger := rewr.logger.With(
97 zap.Object("request", caddyhttp.LoggableHTTPRequest{Request: r}),
@@ -124,7 +124,7 @@ func (rewr Rewrite) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddy
124 // rewrite performs the rewrites on r using repl, which
125 // should have been obtained from r, but is passed in for
126 // efficiency. It returns true if any changes were made to r.
127 -func (rewr Rewrite) rewrite(r *http.Request, repl caddy.Replacer, logger *zap.Logger) bool {
127 +func (rewr Rewrite) rewrite(r *http.Request, repl *caddy.Replacer, logger *zap.Logger) bool {
128 oldMethod := r.Method
129 oldURI := r.RequestURI
130
@@ -209,7 +209,7 @@ type replacer struct {
209 }
210
211 // do performs the replacement on r and returns true if any changes were made.
212 -func (rep replacer) do(r *http.Request, repl caddy.Replacer) bool {
212 +func (rep replacer) do(r *http.Request, repl *caddy.Replacer) bool {
213 if rep.Find == "" || rep.Replace == "" {
214 return false
215 }
modules/caddyhttp/server.go
+1 -1
@@ -451,7 +451,7 @@ func (*HTTPErrorConfig) WithError(r *http.Request, err error) *http.Request {
451 r = r.WithContext(c)
452
453 // add error values to the replacer
454 - repl := r.Context().Value(caddy.ReplacerCtxKey).(caddy.Replacer)
454 + repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
455 repl.Set("http.error", err.Error())
456 if handlerErr, ok := err.(HandlerError); ok {
457 repl.Set("http.error.status_code", strconv.Itoa(handlerErr.StatusCode))
modules/caddyhttp/staticerror.go
+1 -1
@@ -51,7 +51,7 @@ func (StaticError) CaddyModule() caddy.ModuleInfo {
51 }
52
53 func (e StaticError) ServeHTTP(w http.ResponseWriter, r *http.Request, _ Handler) error {
54 - repl := r.Context().Value(caddy.ReplacerCtxKey).(caddy.Replacer)
54 + repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
55
56 statusCode := http.StatusInternalServerError
57 if codeStr := e.StatusCode.String(); codeStr != "" {
modules/caddyhttp/staticresp.go
+1 -1
@@ -86,7 +86,7 @@ func (s *StaticResponse) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
86 }
87
88 func (s StaticResponse) ServeHTTP(w http.ResponseWriter, r *http.Request, _ Handler) error {
89 - repl := r.Context().Value(caddy.ReplacerCtxKey).(caddy.Replacer)
89 + repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
90
91 // close the connection after responding
92 r.Close = s.Close
modules/caddyhttp/templates/templates.go
+1 -1
@@ -122,7 +122,7 @@ func (t *Templates) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddy
122 func (t *Templates) executeTemplate(rr caddyhttp.ResponseRecorder, r *http.Request) error {
123 var fs http.FileSystem
124 if t.FileRoot != "" {
125 - repl := r.Context().Value(caddy.ReplacerCtxKey).(caddy.Replacer)
125 + repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
126 fs = http.Dir(repl.ReplaceAll(t.FileRoot, "."))
127 }
128
modules/caddyhttp/vars.go
+2 -2
@@ -40,7 +40,7 @@ func (VarsMiddleware) CaddyModule() caddy.ModuleInfo {
40
41 func (t VarsMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request, next Handler) error {
42 vars := r.Context().Value(VarsCtxKey).(map[string]interface{})
43 - repl := r.Context().Value(caddy.ReplacerCtxKey).(caddy.Replacer)
43 + repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
44 for k, v := range t {
45 keyExpanded := repl.ReplaceAll(k, "")
46 valExpanded := repl.ReplaceAll(v, "")
@@ -64,7 +64,7 @@ func (VarsMatcher) CaddyModule() caddy.ModuleInfo {
64 // Match matches a request based on variables in the context.
65 func (m VarsMatcher) Match(r *http.Request) bool {
66 vars := r.Context().Value(VarsCtxKey).(map[string]string)
67 - repl := r.Context().Value(caddy.ReplacerCtxKey).(caddy.Replacer)
67 + repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
68 for k, v := range m {
69 keyExpanded := repl.ReplaceAll(k, "")
70 valExpanded := repl.ReplaceAll(v, "")
replacer.go
+54 -54
@@ -23,20 +23,9 @@ import (
23 "time"
24 )
25
26 -// Replacer can replace values in strings.
27 -type Replacer interface {
28 - Set(variable, value string)
29 - Delete(variable string)
30 - Map(ReplacerFunc)
31 - ReplaceAll(input, empty string) string
32 - ReplaceKnown(input, empty string) string
33 - ReplaceOrErr(input string, errOnEmpty, errOnUnknown bool) (string, error)
34 - ReplaceFunc(input string, f ReplacementFunc) (string, error)
35 -}
36 -
26 // NewReplacer returns a new Replacer.
38 -func NewReplacer() Replacer {
39 - rep := &replacer{
27 +func NewReplacer() *Replacer {
28 + rep := &Replacer{
29 static: make(map[string]string),
30 }
31 rep.providers = []ReplacerFunc{
@@ -46,30 +35,44 @@ func NewReplacer() Replacer {
35 return rep
36 }
37
49 -type replacer struct {
38 +// Replacer can replace values in strings.
39 +// A default/empty Replacer is not valid;
40 +// use NewReplacer to make one.
41 +type Replacer struct {
42 providers []ReplacerFunc
43 static map[string]string
44 }
45
46 // Map adds mapFunc to the list of value providers.
47 // mapFunc will be executed only at replace-time.
56 -func (r *replacer) Map(mapFunc ReplacerFunc) {
48 +func (r *Replacer) Map(mapFunc ReplacerFunc) {
49 r.providers = append(r.providers, mapFunc)
50 }
51
52 // Set sets a custom variable to a static value.
61 -func (r *replacer) Set(variable, value string) {
53 +func (r *Replacer) Set(variable, value string) {
54 r.static[variable] = value
55 }
56
57 +// Get gets a value from the replacer. It returns
58 +// the value and whether the variable was known.
59 +func (r *Replacer) Get(variable string) (string, bool) {
60 + for _, mapFunc := range r.providers {
61 + if val, ok := mapFunc(variable); ok {
62 + return val, true
63 + }
64 + }
65 + return "", false
66 +}
67 +
68 // Delete removes a variable with a static value
69 // that was created using Set.
67 -func (r *replacer) Delete(variable string) {
70 +func (r *Replacer) Delete(variable string) {
71 delete(r.static, variable)
72 }
73
74 // fromStatic provides values from r.static.
72 -func (r *replacer) fromStatic(key string) (val string, ok bool) {
75 +func (r *Replacer) fromStatic(key string) (val string, ok bool) {
76 val, ok = r.static[key]
77 return
78 }
@@ -77,14 +80,14 @@ func (r *replacer) fromStatic(key string) (val string, ok bool) {
80 // ReplaceOrErr is like ReplaceAll, but any placeholders
81 // that are empty or not recognized will cause an error to
82 // be returned.
80 -func (r *replacer) ReplaceOrErr(input string, errOnEmpty, errOnUnknown bool) (string, error) {
83 +func (r *Replacer) ReplaceOrErr(input string, errOnEmpty, errOnUnknown bool) (string, error) {
84 return r.replace(input, "", false, errOnEmpty, errOnUnknown, nil)
85 }
86
87 // ReplaceKnown is like ReplaceAll but only replaces
88 // placeholders that are known (recognized). Unrecognized
89 // placeholders will remain in the output.
87 -func (r *replacer) ReplaceKnown(input, empty string) string {
90 +func (r *Replacer) ReplaceKnown(input, empty string) string {
91 out, _ := r.replace(input, empty, false, false, false, nil)
92 return out
93 }
@@ -93,7 +96,7 @@ func (r *replacer) ReplaceKnown(input, empty string) string {
96 // their values. All placeholders are replaced in the output
97 // whether they are recognized or not. Values that are empty
98 // string will be substituted with empty.
96 -func (r *replacer) ReplaceAll(input, empty string) string {
99 +func (r *Replacer) ReplaceAll(input, empty string) string {
100 out, _ := r.replace(input, empty, true, false, false, nil)
101 return out
102 }
@@ -102,11 +105,11 @@ func (r *replacer) ReplaceAll(input, empty string) string {
105 // their values. All placeholders are replaced in the output
106 // whether they are recognized or not. Values that are empty
107 // string will be substituted with empty.
105 -func (r *replacer) ReplaceFunc(input string, f ReplacementFunc) (string, error) {
108 +func (r *Replacer) ReplaceFunc(input string, f ReplacementFunc) (string, error) {
109 return r.replace(input, "", true, false, false, f)
110 }
111
109 -func (r *replacer) replace(input, empty string,
112 +func (r *Replacer) replace(input, empty string,
113 treatUnknownAsEmpty, errOnEmpty, errOnUnknown bool,
114 f ReplacementFunc) (string, error) {
115 if !strings.Contains(input, string(phOpen)) {
@@ -138,48 +141,45 @@ func (r *replacer) replace(input, empty string,
141 // trim opening bracket
142 key := input[i+1 : end]
143
141 - // try to get a value for this key,
142 - // handle empty values accordingly
143 - var found bool
144 - for _, mapFunc := range r.providers {
145 - if val, ok := mapFunc(key); ok {
146 - found = true
147 - if f != nil {
148 - var err error
149 - val, err = f(key, val)
150 - if err != nil {
151 - return "", err
152 - }
153 - }
154 - if val == "" {
155 - if errOnEmpty {
156 - return "", fmt.Errorf("evaluated placeholder %s%s%s is empty",
157 - string(phOpen), key, string(phClose))
158 - } else if empty != "" {
159 - sb.WriteString(empty)
160 - }
161 - } else {
162 - sb.WriteString(val)
163 - }
164 - break
165 - }
166 - }
144 + // try to get a value for this key, handle empty values accordingly
145 + val, found := r.Get(key)
146 if !found {
168 - // placeholder is unknown (unrecognized), handle accordingly
169 - switch {
170 - case errOnUnknown:
147 + // placeholder is unknown (unrecognized); handle accordingly
148 + if errOnUnknown {
149 return "", fmt.Errorf("unrecognized placeholder %s%s%s",
150 string(phOpen), key, string(phClose))
173 - case treatUnknownAsEmpty:
151 + } else if treatUnknownAsEmpty {
152 if empty != "" {
153 sb.WriteString(empty)
154 }
177 - default:
155 + } else {
156 lastWriteCursor = i
157 continue
158 }
159 }
160
161 + // apply any transformations
162 + if f != nil {
163 + var err error
164 + val, err = f(key, val)
165 + if err != nil {
166 + return "", err
167 + }
168 + }
169 +
170 + // write the value; if it's empty, either return
171 + // an error or write a default value
172 + if val == "" {
173 + if errOnEmpty {
174 + return "", fmt.Errorf("evaluated placeholder %s%s%s is empty",
175 + string(phOpen), key, string(phClose))
176 + } else if empty != "" {
177 + sb.WriteString(empty)
178 + }
179 + } else {
180 + sb.WriteString(val)
181 + }
182 +
183 // advance cursor to end of placeholder
184 i = end
185 lastWriteCursor = i + 1
replacer_test.go
+43 -47
@@ -132,7 +132,7 @@ func TestReplacerSet(t *testing.T) {
132 }
133
134 func TestReplacerReplaceKnown(t *testing.T) {
135 - rep := replacer{
135 + rep := Replacer{
136 providers: []ReplacerFunc{
137 // split our possible vars to two functions (to test if both functions are called)
138 func(key string) (val string, ok bool) {
@@ -204,7 +204,7 @@ func TestReplacerReplaceKnown(t *testing.T) {
204 }
205
206 func TestReplacerDelete(t *testing.T) {
207 - rep := replacer{
207 + rep := Replacer{
208 static: map[string]string{
209 "key1": "val1",
210 "key2": "val2",
@@ -264,59 +264,55 @@ func TestReplacerMap(t *testing.T) {
264 }
265
266 func TestReplacerNew(t *testing.T) {
267 - var tc = NewReplacer()
267 + rep := NewReplacer()
268
269 - rep, ok := tc.(*replacer)
270 - if ok {
271 - if len(rep.providers) != 2 {
272 - t.Errorf("Expected providers length '%v' got length '%v'", 2, len(rep.providers))
273 - } else {
274 - // test if default global replacements are added as the first provider
275 - hostname, _ := os.Hostname()
276 - os.Setenv("CADDY_REPLACER_TEST", "envtest")
277 - defer os.Setenv("CADDY_REPLACER_TEST", "")
269 + if len(rep.providers) != 2 {
270 + t.Errorf("Expected providers length '%v' got length '%v'", 2, len(rep.providers))
271 + } else {
272 + // test if default global replacements are added as the first provider
273 + hostname, _ := os.Hostname()
274 + os.Setenv("CADDY_REPLACER_TEST", "envtest")
275 + defer os.Setenv("CADDY_REPLACER_TEST", "")
276
279 - for _, tc := range []struct {
280 - variable string
281 - value string
282 - }{
283 - {
284 - variable: "system.hostname",
285 - value: hostname,
286 - },
287 - {
288 - variable: "system.slash",
289 - value: string(filepath.Separator),
290 - },
291 - {
292 - variable: "system.os",
293 - value: runtime.GOOS,
294 - },
295 - {
296 - variable: "system.arch",
297 - value: runtime.GOARCH,
298 - },
299 - {
300 - variable: "env.CADDY_REPLACER_TEST",
301 - value: "envtest",
302 - },
303 - } {
304 - if val, ok := rep.providers[0](tc.variable); ok {
305 - if val != tc.value {
306 - t.Errorf("Expected value '%s' for key '%s' got '%s'", tc.value, tc.variable, val)
307 - }
308 - } else {
309 - t.Errorf("Expected key '%s' to be recognized by first provider", tc.variable)
277 + for _, tc := range []struct {
278 + variable string
279 + value string
280 + }{
281 + {
282 + variable: "system.hostname",
283 + value: hostname,
284 + },
285 + {
286 + variable: "system.slash",
287 + value: string(filepath.Separator),
288 + },
289 + {
290 + variable: "system.os",
291 + value: runtime.GOOS,
292 + },
293 + {
294 + variable: "system.arch",
295 + value: runtime.GOARCH,
296 + },
297 + {
298 + variable: "env.CADDY_REPLACER_TEST",
299 + value: "envtest",
300 + },
301 + } {
302 + if val, ok := rep.providers[0](tc.variable); ok {
303 + if val != tc.value {
304 + t.Errorf("Expected value '%s' for key '%s' got '%s'", tc.value, tc.variable, val)
305 }
306 + } else {
307 + t.Errorf("Expected key '%s' to be recognized by first provider", tc.variable)
308 }
309 }
313 - } else {
314 - t.Errorf("Expected type of replacer %T got %T ", &replacer{}, tc)
310 }
311 +
312 }
313
318 -func testReplacer() replacer {
319 - return replacer{
314 +func testReplacer() Replacer {
315 + return Replacer{
316 providers: make([]ReplacerFunc, 0),
317 static: make(map[string]string),
318 }