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
templates: Remove context functions implemented by sprig
Matthew Holt committed
Jun 18, 2019 at 15:43 UTC
15647bdfb757ab7b1d1c77446a0707e49f31deb7
2 files changed
-289
modules/caddyhttp/templates/tplcontext.go
-158
@@ -2,20 +2,14 @@ package templates
2
3
import (
4
"bytes"
5
- "crypto/rand"
5
"fmt"
6
"io"
8
- "log"
9
- weakrand "math/rand"
7
"net"
8
"net/http"
9
"path"
10
"strings"
11
"sync"
12
"text/template"
16
- "time"
17
-
18
- "os"
13
14
"github.com/Masterminds/sprig"
15
"github.com/caddyserver/caddy/modules/caddyhttp"
@@ -112,11 +106,6 @@ func (c templateContext) executeTemplateInBuffer(tplName string, buf *bytes.Buff
106
return parsedTpl.Execute(buf, c)
107
}
108
115
-// Now returns the current timestamp.
116
-func (c templateContext) Now() time.Time {
117
- return time.Now()
118
-}
119
-
109
// Cookie gets the value of a cookie with name name.
110
func (c templateContext) Cookie(name string) string {
111
cookies := c.Req.Cookies()
@@ -145,19 +134,6 @@ func (c templateContext) Hostname() string {
134
return hostnameList[0]
135
}
136
148
-// Env gets a map of the environment variables.
149
-func (c templateContext) Env() map[string]string {
150
- osEnv := os.Environ()
151
- envVars := make(map[string]string, len(osEnv))
152
- for _, env := range osEnv {
153
- data := strings.SplitN(env, "=", 2)
154
- if len(data) == 2 && len(data[0]) > 0 {
155
- envVars[data[0]] = data[1]
156
- }
157
- }
158
- return envVars
159
-}
160
-
137
// IP gets the (remote) IP address of the client making the request.
138
func (c templateContext) IP() string {
139
ip, _, err := net.SplitHostPort(c.Req.RemoteAddr)
@@ -181,21 +157,6 @@ func (c templateContext) Host() (string, error) {
157
return host, nil
158
}
159
184
-// Truncate truncates the input string to the given length.
185
-// If length is negative, it returns that many characters
186
-// starting from the end of the string. If the absolute value
187
-// of length is greater than len(input), the whole input is
188
-// returned.
189
-func (c templateContext) Truncate(input string, length int) string {
190
- if length < 0 && len(input)+length > 0 {
191
- return input[len(input)+length:]
192
- }
193
- if length >= 0 && len(input) > length {
194
- return input[:length]
195
- }
196
- return input
197
-}
198
-
160
// StripHTML returns s without HTML tags. It is fairly naive
161
// but works with most valid HTML inputs.
162
func (c templateContext) StripHTML(s string) string {
@@ -234,83 +195,6 @@ func (c templateContext) Markdown(body string) string {
195
return string(blackfriday.Run([]byte(body)))
196
}
197
237
-// Ext returns the suffix beginning at the final dot in the final
238
-// slash-separated element of the pathStr (or in other words, the
239
-// file extension).
240
-func (c templateContext) Ext(pathStr string) string {
241
- return path.Ext(pathStr)
242
-}
243
-
244
-// StripExt returns the input string without the extension,
245
-// which is the suffix starting with the final '.' character
246
-// but not before the final path separator ('/') character.
247
-// If there is no extension, the whole input is returned.
248
-func (c templateContext) StripExt(path string) string {
249
- for i := len(path) - 1; i >= 0 && path[i] != '/'; i-- {
250
- if path[i] == '.' {
251
- return path[:i]
252
- }
253
- }
254
- return path
255
-}
256
-
257
-// Replace replaces instances of find in input with replacement.
258
-func (c templateContext) Replace(input, find, replacement string) string {
259
- return strings.Replace(input, find, replacement, -1)
260
-}
261
-
262
-// HasPrefix returns true if s starts with prefix.
263
-func (c templateContext) HasPrefix(s, prefix string) bool {
264
- return strings.HasPrefix(s, prefix)
265
-}
266
-
267
-// ToLower will convert the given string to lower case.
268
-func (c templateContext) ToLower(s string) string {
269
- return strings.ToLower(s)
270
-}
271
-
272
-// ToUpper will convert the given string to upper case.
273
-func (c templateContext) ToUpper(s string) string {
274
- return strings.ToUpper(s)
275
-}
276
-
277
-// Split is a pass-through to strings.Split. It will split
278
-// the first argument at each instance of the separator and
279
-// return a slice of strings.
280
-func (c templateContext) Split(s string, sep string) []string {
281
- return strings.Split(s, sep)
282
-}
283
-
284
-// Join is a pass-through to strings.Join. It will join the
285
-// first argument slice with the separator in the second
286
-// argument and return the result.
287
-func (c templateContext) Join(a []string, sep string) string {
288
- return strings.Join(a, sep)
289
-}
290
-
291
-// Slice will convert the given arguments into a slice.
292
-func (c templateContext) Slice(elems ...interface{}) []interface{} {
293
- return elems
294
-}
295
-
296
-// Dict will convert the arguments into a dictionary (map). It expects
297
-// alternating keys and values of string types. This is useful since you
298
-// cannot express map literals directly in Go templates.
299
-func (c templateContext) Dict(values ...interface{}) (map[string]interface{}, error) {
300
- if len(values)%2 != 0 {
301
- return nil, fmt.Errorf("expected even number of arguments")
302
- }
303
- dict := make(map[string]interface{}, len(values)/2)
304
- for i := 0; i < len(values); i += 2 {
305
- key, ok := values[i].(string)
306
- if !ok {
307
- return nil, fmt.Errorf("argument %d: map keys must be strings", i)
308
- }
309
- dict[key] = values[i+1]
310
- }
311
- return dict, nil
312
-}
313
-
198
// ListFiles reads and returns a slice of names from the given
199
// directory relative to the root of c.
200
func (c templateContext) ListFiles(name string) ([]string, error) {
@@ -345,48 +229,6 @@ func (c templateContext) ListFiles(name string) ([]string, error) {
229
return names, nil
230
}
231
348
-// RandomString generates a random string of random length given
349
-// length bounds. Thanks to http://stackoverflow.com/a/35615565/1048862
350
-// for the clever technique that is fairly fast, secure, and maintains
351
-// proper distributions over the dictionary.
352
-func (c templateContext) RandomString(minLen, maxLen int) string {
353
- const (
354
- letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
355
- letterIdxBits = 6 // 6 bits to represent 64 possibilities (indexes)
356
- letterIdxMask = 1<<letterIdxBits - 1 // all 1-bits, as many as letterIdxBits
357
- )
358
-
359
- if minLen < 0 || maxLen < 0 || maxLen < minLen {
360
- return ""
361
- }
362
-
363
- n := weakrand.Intn(maxLen-minLen+1) + minLen // choose actual length
364
-
365
- // secureRandomBytes returns a number of bytes using crypto/rand.
366
- secureRandomBytes := func(numBytes int) []byte {
367
- randomBytes := make([]byte, numBytes)
368
- if _, err := rand.Read(randomBytes); err != nil {
369
- // TODO: what to do with the logs (throughout whole file) (could return as error? might get rendered though...)
370
- log.Println("[ERROR] failed to read bytes: ", err)
371
- }
372
- return randomBytes
373
- }
374
-
375
- result := make([]byte, n)
376
- bufferSize := int(float64(n) * 1.3)
377
- for i, j, randomBytes := 0, 0, []byte{}; i < n; j++ {
378
- if j%bufferSize == 0 {
379
- randomBytes = secureRandomBytes(bufferSize)
380
- }
381
- if idx := int(randomBytes[j%n] & letterIdxMask); idx < len(letterBytes) {
382
- result[i] = letterBytes[idx]
383
- i++
384
- }
385
- }
386
-
387
- return string(result)
388
-}
389
-
232
// tplWrappedHeader wraps niladic functions so that they
233
// can be used in templates. (Template functions must
234
// return a value.)
modules/caddyhttp/templates/tplcontext_test.go
-131
@@ -109,42 +109,6 @@ func TestCookieMultipleCookies(t *testing.T) {
109
}
110
}
111
112
-func TestEnv(t *testing.T) {
113
- context := getContextOrFail(t)
114
-
115
- name := "ENV_TEST_NAME"
116
- testValue := "TEST_VALUE"
117
- os.Setenv(name, testValue)
118
-
119
- notExisting := "ENV_TEST_NOT_EXISTING"
120
- os.Unsetenv(notExisting)
121
-
122
- invalidName := "ENV_TEST_INVALID_NAME"
123
- os.Setenv("="+invalidName, testValue)
124
-
125
- env := context.Env()
126
- if value := env[name]; value != testValue {
127
- t.Errorf("Expected env-variable %s value '%s', found '%s'",
128
- name, testValue, value)
129
- }
130
-
131
- if value, ok := env[notExisting]; ok {
132
- t.Errorf("Expected empty env-variable %s, found '%s'",
133
- notExisting, value)
134
- }
135
-
136
- for k, v := range env {
137
- if strings.Contains(k, invalidName) {
138
- t.Errorf("Expected invalid name not to be included in Env %s, found in key '%s'", invalidName, k)
139
- }
140
- if strings.Contains(v, invalidName) {
141
- t.Errorf("Expected invalid name not be be included in Env %s, found in value '%s'", invalidName, v)
142
- }
143
- }
144
-
145
- os.Unsetenv("=" + invalidName)
146
-}
147
-
112
func TestIP(t *testing.T) {
113
context := getContextOrFail(t)
114
for i, test := range []struct {
@@ -164,57 +128,6 @@ func TestIP(t *testing.T) {
128
}
129
}
130
167
-func TestTruncate(t *testing.T) {
168
- context := getContextOrFail(t)
169
-
170
- for i, test := range []struct {
171
- input string
172
- length int
173
- expect string
174
- }{
175
- {
176
- input: "string",
177
- length: 1,
178
- expect: "s",
179
- },
180
- {
181
- input: "string",
182
- length: 6,
183
- expect: "string",
184
- },
185
- {
186
- input: "string",
187
- length: 10,
188
- expect: "string",
189
- },
190
- {
191
- input: "string",
192
- length: 0,
193
- expect: "",
194
- },
195
- {
196
- input: "string",
197
- length: -5,
198
- expect: "tring",
199
- },
200
- {
201
- input: "string",
202
- length: -6,
203
- expect: "string",
204
- },
205
- {
206
- input: "string",
207
- length: -7,
208
- expect: "string",
209
- },
210
- } {
211
- actual := context.Truncate(test.input, test.length)
212
- if actual != test.expect {
213
- t.Errorf("Test %d: Expected '%s' but got '%s'", i, test.expect, actual)
214
- }
215
- }
216
-}
217
-
131
func TestStripHTML(t *testing.T) {
132
context := getContextOrFail(t)
133
@@ -260,50 +173,6 @@ func TestStripHTML(t *testing.T) {
173
}
174
}
175
263
-func TestStripExt(t *testing.T) {
264
- context := getContextOrFail(t)
265
- tests := []struct {
266
- input string
267
- expect string
268
- }{
269
- {
270
- input: "",
271
- expect: "",
272
- },
273
- {
274
- input: "file.ext",
275
- expect: "file",
276
- },
277
- {
278
- input: "file",
279
- expect: "file",
280
- },
281
- {
282
- input: "/file",
283
- expect: "/file",
284
- },
285
- {
286
- input: "/file.ext",
287
- expect: "/file",
288
- },
289
- {
290
- input: "/dir.ext/",
291
- expect: "/dir.ext/",
292
- },
293
- {
294
- input: "/dir.ext/file.ext",
295
- expect: "/dir.ext/file",
296
- },
297
- }
298
-
299
- for i, test := range tests {
300
- actual := context.StripExt(test.input)
301
- if actual != test.expect {
302
- t.Errorf("Test %d: Expected %s but got %s", i, test.expect, actual)
303
- }
304
- }
305
-}
306
-
176
func TestFileListing(t *testing.T) {
177
for i, test := range []struct {
178
fileNames []string