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
Clean up Dispenser and filename handling a bit
Matthew Holt committed
Aug 21, 2019 at 15:23 UTC
8420a2f250cf467a06c0081cb47a8f73b70e7f3f
5 files changed
+33
-47
caddyconfig/caddyfile/dispenser.go
+17
-30
@@ -24,19 +24,16 @@ import (
24
// except that it can do so with some notion of structure. An empty
25
// Dispenser is invalid; call NewDispenser to make a proper instance.
26
type Dispenser struct {
27
- filename string
28
- tokens []Token
29
- cursor int
30
- nesting int
27
+ tokens []Token
28
+ cursor int
29
+ nesting int
30
}
31
32
// NewDispenser returns a Dispenser filled with the given tokens.
34
-// TODO: Get rid of the filename argument; it seems pointless here
35
-func NewDispenser(filename string, tokens []Token) *Dispenser {
33
+func NewDispenser(tokens []Token) *Dispenser {
34
return &Dispenser{
37
- filename: filename,
38
- tokens: tokens,
39
- cursor: -1,
35
+ tokens: tokens,
36
+ cursor: -1,
37
}
38
}
39
@@ -170,8 +167,8 @@ func (d *Dispenser) Val() string {
167
return d.tokens[d.cursor].Text
168
}
169
173
-// Line gets the line number of the current token. If there is no token
174
-// loaded, it returns 0.
170
+// Line gets the line number of the current token.
171
+// If there is no token loaded, it returns 0.
172
func (d *Dispenser) Line() int {
173
if d.cursor < 0 || d.cursor >= len(d.tokens) {
174
return 0
@@ -179,16 +176,12 @@ func (d *Dispenser) Line() int {
176
return d.tokens[d.cursor].Line
177
}
178
182
-// File gets the filename of the current token. If there is no token loaded,
183
-// it returns the filename originally given when parsing started.
179
+// File gets the filename where the current token originated.
180
func (d *Dispenser) File() string {
181
if d.cursor < 0 || d.cursor >= len(d.tokens) {
186
- return d.filename
187
- }
188
- if tokenFilename := d.tokens[d.cursor].File; tokenFilename != "" {
189
- return tokenFilename
182
+ return ""
183
}
191
- return d.filename
184
+ return d.tokens[d.cursor].File
185
}
186
187
// Args is a convenience function that loads the next arguments
@@ -240,28 +233,22 @@ func (d *Dispenser) NewFromNextTokens() *Dispenser {
233
} else {
234
d.cursor--
235
}
243
- return NewDispenser(d.filename, tkns)
236
+ return NewDispenser(tkns)
237
}
238
239
// Token returns the current token.
240
func (d *Dispenser) Token() Token {
248
- return d.TokenAt(d.cursor)
249
-}
250
-
251
-func (d *Dispenser) TokenAt(cursor int) Token {
252
- if cursor < 0 || cursor >= len(d.tokens) {
241
+ if d.cursor < 0 || d.cursor >= len(d.tokens) {
242
return Token{}
243
}
255
- return d.tokens[cursor]
256
-}
257
-
258
-// Cursor returns the current cursor (token index).
259
-func (d *Dispenser) Cursor() int {
260
- return d.cursor
244
+ return d.tokens[d.cursor]
245
}
246
247
+// Reset sets d's cursor to the beginning, as
248
+// if this was a new and unused dispenser.
249
func (d *Dispenser) Reset() {
250
d.cursor = -1
251
+ d.nesting = 0
252
}
253
254
// ArgErr returns an argument error, meaning that another
caddyconfig/caddyfile/dispenser_test.go
+2
-2
@@ -308,9 +308,9 @@ func TestDispenser_ArgErr_Err(t *testing.T) {
308
}
309
310
func newTestDispenser(input string) *Dispenser {
311
- tokens, err := allTokens(strings.NewReader(input))
311
+ tokens, err := allTokens("Testfile", strings.NewReader(input))
312
if err != nil && err != io.EOF {
313
log.Fatalf("getting all tokens from input: %v", err)
314
}
315
- return NewDispenser("Testfile", tokens)
315
+ return NewDispenser(tokens)
316
}
caddyconfig/caddyfile/parse.go
+8
-13
@@ -29,18 +29,18 @@ import (
29
// an error. If you do not want to check for valid directives,
30
// pass in nil instead.
31
func Parse(filename string, input io.Reader) ([]ServerBlock, error) {
32
- tokens, err := allTokens(input)
32
+ tokens, err := allTokens(filename, input)
33
if err != nil {
34
return nil, err
35
}
36
- p := parser{Dispenser: NewDispenser(filename, tokens)}
36
+ p := parser{Dispenser: NewDispenser(tokens)}
37
return p.parseAll()
38
}
39
40
// allTokens lexes the entire input, but does not parse it.
41
// It returns all the tokens from the input, unstructured
42
// and in order.
43
-func allTokens(input io.Reader) ([]Token, error) {
43
+func allTokens(filename string, input io.Reader) ([]Token, error) {
44
l := new(lexer)
45
err := l.load(input)
46
if err != nil {
@@ -48,6 +48,7 @@ func allTokens(input io.Reader) ([]Token, error) {
48
}
49
var tokens []Token
50
for l.next() {
51
+ l.token.File = filename
52
tokens = append(tokens, l.token)
53
}
54
return tokens, nil
@@ -265,7 +266,7 @@ func (p *parser) doImport() error {
266
// list of matching filenames
267
absFile, err := filepath.Abs(p.Dispenser.File())
268
if err != nil {
268
- return p.Errf("Failed to get absolute path of file: %s: %v", p.Dispenser.filename, err)
269
+ return p.Errf("Failed to get absolute path of file: %s: %v", p.Dispenser.File(), err)
270
}
271
272
var matches []string
@@ -327,7 +328,7 @@ func (p *parser) doSingleImport(importFile string) ([]Token, error) {
328
return nil, p.Errf("Could not import %s: is a directory", importFile)
329
}
330
330
- importedTokens, err := allTokens(file)
331
+ importedTokens, err := allTokens(importFile, file)
332
if err != nil {
333
return nil, p.Errf("Could not read tokens while importing %s: %v", importFile, err)
334
}
@@ -336,7 +337,7 @@ func (p *parser) doSingleImport(importFile string) ([]Token, error) {
337
// (we use full, absolute path to avoid bugs: issue #1892)
338
filename, err := filepath.Abs(importFile)
339
if err != nil {
339
- return nil, p.Errf("Failed to get absolute path of file: %s: %v", p.Dispenser.filename, err)
340
+ return nil, p.Errf("Failed to get absolute path of file: %s: %v", importFile, err)
341
}
342
for i := 0; i < len(importedTokens); i++ {
343
importedTokens[i].File = filename
@@ -497,7 +498,7 @@ func (sb ServerBlock) DispenseDirective(dir string) *Dispenser {
498
tokens = append(tokens, seg...)
499
}
500
}
500
- return NewDispenser("", tokens)
501
+ return NewDispenser(tokens)
502
}
503
504
// Segment is a list of tokens which begins with a directive
@@ -513,9 +514,3 @@ func (s Segment) Directive() string {
514
}
515
return ""
516
}
516
-
517
-// NewDispenser returns a dispenser for this
518
-// segment's tokens.
519
-func (s Segment) NewDispenser() *Dispenser {
520
- return NewDispenser("", s)
521
-}
caddyconfig/caddyfile/parse_test.go
+1
-1
@@ -27,7 +27,7 @@ import (
27
func TestAllTokens(t *testing.T) {
28
input := strings.NewReader("a b c\nd e")
29
expected := []string{"a", "b", "c", "d", "e"}
30
- tokens, err := allTokens(input)
30
+ tokens, err := allTokens("TestAllTokens", input)
31
32
if err != nil {
33
t.Fatalf("Expected no error, got %v", err)
caddyconfig/httpcaddyfile/httptype.go
+5
-1
@@ -38,6 +38,10 @@ func init() {
38
type ServerType struct {
39
}
40
41
+// TODO: customize directive ordering
42
+
43
+// TODO: hide caddyfile when serving static files
44
+
45
// Setup makes a config from the tokens.
46
func (st ServerType) Setup(originalServerBlocks []caddyfile.ServerBlock,
47
options map[string]string) (*caddy.Config, []caddyconfig.Warning, error) {
@@ -88,7 +92,7 @@ func (st ServerType) Setup(originalServerBlocks []caddyfile.ServerBlock,
92
}
93
if dirFunc, ok := registeredDirectives[dir]; ok {
94
results, err := dirFunc(Helper{
91
- Dispenser: segment.NewDispenser(),
95
+ Dispenser: caddyfile.NewDispenser(segment),
96
warnings: &warnings,
97
matcherDefs: matcherDefs,
98
})