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
}