Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
caddy
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
caddy
Commits
decfda27
Commit
decfda27
authored
Jan 21, 2015
by
Matthew Holt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Made parsing easier in middleware
parent
31878151
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
76 additions
and
97 deletions
+76
-97
config/dispenser.go
config/dispenser.go
+56
-52
middleware/headers.go
middleware/headers.go
+16
-40
middleware/middleware.go
middleware/middleware.go
+3
-4
middleware/redirect.go
middleware/redirect.go
+1
-1
No files found.
config/dispenser.go
View file @
decfda27
...
@@ -11,16 +11,17 @@ import (
...
@@ -11,16 +11,17 @@ import (
// generators so that they can parse tokens to configure
// generators so that they can parse tokens to configure
// their instance.
// their instance.
type
dispenser
struct
{
type
dispenser
struct
{
parser
*
parser
parser
*
parser
iter
int
cursor
int
tokens
[]
token
nesting
int
err
error
tokens
[]
token
err
error
}
}
// newDispenser returns a new dispenser.
// newDispenser returns a new dispenser.
func
newDispenser
(
p
*
parser
)
*
dispenser
{
func
newDispenser
(
p
*
parser
)
*
dispenser
{
d
:=
new
(
dispenser
)
d
:=
new
(
dispenser
)
d
.
ite
r
=
-
1
d
.
curso
r
=
-
1
d
.
parser
=
p
d
.
parser
=
p
return
d
return
d
}
}
...
@@ -30,10 +31,10 @@ func newDispenser(p *parser) *dispenser {
...
@@ -30,10 +31,10 @@ func newDispenser(p *parser) *dispenser {
// have been consumed.
// have been consumed.
// TODO: Have the other Next functions call this one...?
// TODO: Have the other Next functions call this one...?
func
(
d
*
dispenser
)
Next
()
bool
{
func
(
d
*
dispenser
)
Next
()
bool
{
if
d
.
ite
r
>=
len
(
d
.
tokens
)
-
1
{
if
d
.
curso
r
>=
len
(
d
.
tokens
)
-
1
{
return
false
return
false
}
else
{
}
else
{
d
.
ite
r
++
d
.
curso
r
++
return
true
return
true
}
}
}
}
...
@@ -43,91 +44,96 @@ func (d *dispenser) Next() bool {
...
@@ -43,91 +44,96 @@ func (d *dispenser) Next() bool {
// otherwise. If false, all tokens on the line have
// otherwise. If false, all tokens on the line have
// been consumed.
// been consumed.
func
(
d
*
dispenser
)
NextArg
()
bool
{
func
(
d
*
dispenser
)
NextArg
()
bool
{
if
d
.
ite
r
<
0
{
if
d
.
curso
r
<
0
{
d
.
ite
r
++
d
.
curso
r
++
return
true
return
true
}
}
if
d
.
ite
r
>=
len
(
d
.
tokens
)
{
if
d
.
curso
r
>=
len
(
d
.
tokens
)
{
return
false
return
false
}
}
if
d
.
ite
r
<
len
(
d
.
tokens
)
-
1
&&
if
d
.
curso
r
<
len
(
d
.
tokens
)
-
1
&&
d
.
tokens
[
d
.
iter
]
.
line
==
d
.
tokens
[
d
.
ite
r
+
1
]
.
line
{
d
.
tokens
[
d
.
cursor
]
.
line
==
d
.
tokens
[
d
.
curso
r
+
1
]
.
line
{
d
.
ite
r
++
d
.
curso
r
++
return
true
return
true
}
}
return
false
return
false
}
}
// TODO:
Keep this method? It's like NextArg
// TODO:
Assert that there's a line break and only advance
//
but only gets the next token if it's on the next line...
//
the token if that's the case? (store an error otherwise)
func
(
d
*
dispenser
)
NextLine
()
bool
{
func
(
d
*
dispenser
)
NextLine
()
bool
{
if
d
.
ite
r
<
0
{
if
d
.
curso
r
<
0
{
d
.
ite
r
++
d
.
curso
r
++
return
true
return
true
}
}
if
d
.
ite
r
>=
len
(
d
.
tokens
)
{
if
d
.
curso
r
>=
len
(
d
.
tokens
)
{
return
false
return
false
}
}
if
d
.
ite
r
<
len
(
d
.
tokens
)
-
1
&&
if
d
.
curso
r
<
len
(
d
.
tokens
)
-
1
&&
d
.
tokens
[
d
.
iter
]
.
line
<
d
.
tokens
[
d
.
ite
r
+
1
]
.
line
{
d
.
tokens
[
d
.
cursor
]
.
line
<
d
.
tokens
[
d
.
curso
r
+
1
]
.
line
{
d
.
ite
r
++
d
.
curso
r
++
return
true
return
true
}
}
return
false
return
false
}
}
// OpenCurlyBrace asserts that the current token is
// NextBlock advances the cursor to the next token only
// an opening curly brace "{". If it isn't, an error
// if the current token is an open curly brace on the
// is produced and false is returned.
// same line. If so, that token is consumed and this
func
(
d
*
dispenser
)
OpenCurlyBrace
()
bool
{
// function will return true until the closing curly
if
d
.
Val
()
==
"{"
{
// brace is consumed by this method.
func
(
d
*
dispenser
)
NextBlock
()
bool
{
if
d
.
nesting
>
0
{
d
.
Next
()
if
d
.
Val
()
==
"}"
{
d
.
nesting
--
d
.
Next
()
// consume closing brace
return
false
}
return
true
return
true
}
else
{
}
d
.
Err
(
"Parse"
,
"Expected '{'"
)
if
!
d
.
NextArg
()
{
return
false
return
false
}
}
}
if
d
.
Val
()
!=
"{"
{
d
.
cursor
--
// roll back if not opening brace
// CloseCurlyBrace asserts that the current token is
// a closing curly brace "}". If it isn't, an error
// is produced and false is returned.
func
(
d
*
dispenser
)
CloseCurlyBrace
()
bool
{
if
d
.
Val
()
==
"}"
{
return
true
}
else
{
d
.
Err
(
"Parse"
,
"Expected '}'"
)
return
false
return
false
}
}
d
.
Next
()
d
.
nesting
++
return
true
}
}
// Val gets the text of the current token.
// Val gets the text of the current token.
func
(
d
*
dispenser
)
Val
()
string
{
func
(
d
*
dispenser
)
Val
()
string
{
if
d
.
iter
>=
len
(
d
.
tokens
)
||
d
.
iter
<
0
{
if
d
.
cursor
<
0
||
d
.
cursor
>=
len
(
d
.
tokens
)
{
return
""
return
""
}
else
{
}
else
{
return
d
.
tokens
[
d
.
ite
r
]
.
text
return
d
.
tokens
[
d
.
curso
r
]
.
text
}
}
}
}
// ArgErr generates an argument error, meaning that another
// ArgErr generates an argument error, meaning that another
// argument was expected but not found. The error is saved
// argument was expected but not found. The error is saved
// within the dispenser, but this function returns nil for
// within the dispenser, but this function returns nil for
// convenience.
// convenience
in practice
.
func
(
d
*
dispenser
)
ArgErr
()
middleware
.
Middleware
{
func
(
d
*
dispenser
)
ArgErr
()
middleware
.
Middleware
{
if
d
.
Val
()
==
"{"
{
if
d
.
Val
()
==
"{"
{
d
.
Err
(
"
Syntax"
,
"Unexpected token '{', expecting argument for directive
"
)
d
.
Err
(
"
Unexpected token '{', expecting argument
"
)
return
nil
return
nil
}
}
d
.
Err
(
"
Syntax"
,
"Unexpected line break after '"
+
d
.
tokens
[
d
.
iter
]
.
text
+
"' (missing arguments?)"
)
d
.
Err
(
"
Unexpected line break after '"
+
d
.
Val
()
+
"' (missing arguments?)"
)
return
nil
return
nil
}
}
// Err generates a custom error of type kind and with a message
// Err generates a custom parse error with a message of msg.
// of msg. The kind should be capitalized. This function returns
// This function returns nil for convenience, but loads the
// nil for convenience, but loads the error into the dispenser
// error into the dispenser so it can be reported. The caller
// so it can be reported immediately.
// of the middleware preparator is responsible for checking
func
(
d
*
dispenser
)
Err
(
kind
,
msg
string
)
middleware
.
Middleware
{
// the error in the dispenser after the middleware preparator
msg
=
fmt
.
Sprintf
(
"%s:%d - %s error: %s"
,
d
.
parser
.
filename
,
d
.
tokens
[
d
.
iter
]
.
line
,
kind
,
msg
)
// is finished.
func
(
d
*
dispenser
)
Err
(
msg
string
)
middleware
.
Middleware
{
msg
=
fmt
.
Sprintf
(
"%s:%d - Parse error: %s"
,
d
.
parser
.
filename
,
d
.
tokens
[
d
.
cursor
]
.
line
,
msg
)
d
.
err
=
errors
.
New
(
msg
)
d
.
err
=
errors
.
New
(
msg
)
return
nil
return
nil
}
}
...
@@ -137,10 +143,8 @@ func (d *dispenser) Err(kind, msg string) middleware.Middleware {
...
@@ -137,10 +143,8 @@ func (d *dispenser) Err(kind, msg string) middleware.Middleware {
// pointed to in targets. If there are fewer tokens available
// pointed to in targets. If there are fewer tokens available
// than string pointers, the remaining strings will not be changed.
// than string pointers, the remaining strings will not be changed.
func
(
d
*
dispenser
)
Args
(
targets
...*
string
)
{
func
(
d
*
dispenser
)
Args
(
targets
...*
string
)
{
i
:=
0
for
i
:=
0
;
i
<
len
(
targets
)
&&
d
.
NextArg
();
i
++
{
for
d
.
NextArg
()
{
*
targets
[
i
]
=
d
.
Val
()
*
targets
[
i
]
=
d
.
Val
()
i
++
}
}
}
}
...
...
middleware/headers.go
View file @
decfda27
...
@@ -20,7 +20,7 @@ func Headers(p parser) Middleware {
...
@@ -20,7 +20,7 @@ func Headers(p parser) Middleware {
)
)
var
rules
[]
headers
var
rules
[]
headers
for
p
.
Next
()
{
for
p
.
Next
Line
()
{
var
head
headers
var
head
headers
var
isNewPattern
bool
var
isNewPattern
bool
...
@@ -43,49 +43,25 @@ func Headers(p parser) Middleware {
...
@@ -43,49 +43,25 @@ func Headers(p parser) Middleware {
isNewPattern
=
true
isNewPattern
=
true
}
}
processHeaderBlock
:=
func
()
bool
{
for
p
.
NextBlock
()
{
if
!
p
.
OpenCurlyBrace
()
{
h
:=
header
{
Name
:
p
.
Val
()}
return
false
}
if
p
.
NextArg
()
{
for
p
.
Next
()
{
h
.
Value
=
p
.
Val
()
if
p
.
Val
()
==
"}"
{
break
}
h
:=
header
{
Name
:
p
.
Val
()}
if
p
.
NextArg
()
{
h
.
Value
=
p
.
Val
()
}
head
.
Headers
=
append
(
head
.
Headers
,
h
)
}
if
!
p
.
CloseCurlyBrace
()
{
return
false
}
}
return
true
}
// A single header could be declared on the same line, or
head
.
Headers
=
append
(
head
.
Headers
,
h
)
// multiple headers can be grouped by URL pattern, so we have
}
// to look for both here.
if
p
.
NextArg
()
{
if
p
.
NextArg
()
{
if
p
.
Val
()
==
"{"
{
h
:=
header
{
Name
:
p
.
Val
()}
if
!
processHeaderBlock
()
{
return
nil
h
.
Value
=
p
.
Val
()
}
}
else
{
if
p
.
NextArg
()
{
h
:=
header
{
Name
:
p
.
Val
()}
h
.
Value
=
p
.
Val
()
if
p
.
NextArg
()
{
h
.
Value
=
p
.
Val
()
}
head
.
Headers
=
append
(
head
.
Headers
,
h
)
}
}
else
{
// Okay, it might be an opening curly brace on the next line
if
!
p
.
Next
()
{
return
p
.
Err
(
"Parse"
,
"Unexpected EOF"
)
}
if
!
processHeaderBlock
()
{
return
nil
}
}
head
.
Headers
=
append
(
head
.
Headers
,
h
)
}
}
if
isNewPattern
{
if
isNewPattern
{
...
...
middleware/middleware.go
View file @
decfda27
...
@@ -35,12 +35,11 @@ type (
...
@@ -35,12 +35,11 @@ type (
Next
()
bool
Next
()
bool
NextArg
()
bool
NextArg
()
bool
NextLine
()
bool
NextLine
()
bool
NextBlock
()
bool
Val
()
string
Val
()
string
OpenCurlyBrace
()
bool
CloseCurlyBrace
()
bool
ArgErr
()
Middleware
Err
(
string
,
string
)
Middleware
Args
(
...*
string
)
Args
(
...*
string
)
ArgErr
()
Middleware
Err
(
string
)
Middleware
Startup
(
func
()
error
)
Startup
(
func
()
error
)
Root
()
string
Root
()
string
Host
()
string
Host
()
string
...
...
middleware/redirect.go
View file @
decfda27
...
@@ -36,7 +36,7 @@ func Redirect(p parser) Middleware {
...
@@ -36,7 +36,7 @@ func Redirect(p parser) Middleware {
}
}
if
code
,
ok
:=
httpRedirs
[
p
.
Val
()];
!
ok
{
if
code
,
ok
:=
httpRedirs
[
p
.
Val
()];
!
ok
{
return
p
.
Err
(
"
Parse"
,
"Invalid redirect code '"
+
p
.
Val
()
+
"'"
)
return
p
.
Err
(
"
Invalid redirect code '"
+
p
.
Val
()
+
"'"
)
}
else
{
}
else
{
rule
.
Code
=
code
rule
.
Code
=
code
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment