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
35225fe2
Commit
35225fe2
authored
Mar 20, 2015
by
Matthew Holt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Docs and comments, la la
parent
01266ece
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
104 additions
and
44 deletions
+104
-44
config/controller.go
config/controller.go
+1
-0
config/dispenser.go
config/dispenser.go
+31
-29
config/parser.go
config/parser.go
+11
-5
middleware/gzip/gzip.go
middleware/gzip/gzip.go
+5
-6
middleware/middleware.go
middleware/middleware.go
+56
-3
server/server.go
server/server.go
+0
-1
No files found.
config/controller.go
View file @
35225fe2
...
@@ -47,6 +47,7 @@ func (c *controller) Port() string {
...
@@ -47,6 +47,7 @@ func (c *controller) Port() string {
return
c
.
parser
.
cfg
.
Port
return
c
.
parser
.
cfg
.
Port
}
}
// Context returns the path scope that the Controller is in.
func
(
c
*
controller
)
Context
()
middleware
.
Path
{
func
(
c
*
controller
)
Context
()
middleware
.
Path
{
return
middleware
.
Path
(
c
.
pathScope
)
return
middleware
.
Path
(
c
.
pathScope
)
}
}
config/dispenser.go
View file @
35225fe2
...
@@ -5,10 +5,11 @@ import (
...
@@ -5,10 +5,11 @@ import (
"fmt"
"fmt"
)
)
// dispenser is a type that gets exposed to middleware
// dispenser is a type that dispenses tokens, similarly to
// generators so that they can parse tokens to configure
// a lexer, except that it can do so with some notion of
// their instance. It basically dispenses tokens but can
// structure. Its methods implement part of the
// do so in a structured manner.
// middleware.Controller interface, so refer to that
// documentation for more info.
type
dispenser
struct
{
type
dispenser
struct
{
filename
string
filename
string
cursor
int
cursor
int
...
@@ -18,15 +19,13 @@ type dispenser struct {
...
@@ -18,15 +19,13 @@ type dispenser struct {
// Next loads the next token. Returns true if a token
// Next loads the next token. Returns true if a token
// was loaded; false otherwise. If false, all tokens
// was loaded; false otherwise. If false, all tokens
// have been consumed.
// have already been consumed.
// TODO: Have the other Next functions call this one...?
func
(
d
*
dispenser
)
Next
()
bool
{
func
(
d
*
dispenser
)
Next
()
bool
{
if
d
.
cursor
>=
len
(
d
.
tokens
)
-
1
{
if
d
.
cursor
<
len
(
d
.
tokens
)
-
1
{
return
false
}
else
{
d
.
cursor
++
d
.
cursor
++
return
true
return
true
}
}
return
false
}
}
// NextArg loads the next token if it is on the same
// NextArg loads the next token if it is on the same
...
@@ -49,8 +48,10 @@ func (d *dispenser) NextArg() bool {
...
@@ -49,8 +48,10 @@ func (d *dispenser) NextArg() bool {
return
false
return
false
}
}
// TODO: Assert that there's a line break and only advance
// NextLine loads the next token only if it is not on the same
// the token if that's the case? (store an error otherwise)
// line as the current token, and returns true if a token was
// loaded; false otherwise. If false, there is not another token
// or it is on the same line.
func
(
d
*
dispenser
)
NextLine
()
bool
{
func
(
d
*
dispenser
)
NextLine
()
bool
{
if
d
.
cursor
<
0
{
if
d
.
cursor
<
0
{
d
.
cursor
++
d
.
cursor
++
...
@@ -96,7 +97,8 @@ func (d *dispenser) NextBlock() bool {
...
@@ -96,7 +97,8 @@ func (d *dispenser) NextBlock() bool {
return
true
return
true
}
}
// Val gets the text of the current token.
// Val gets the text of the current token. If there is no token
// loaded, it returns empty string.
func
(
d
*
dispenser
)
Val
()
string
{
func
(
d
*
dispenser
)
Val
()
string
{
if
d
.
cursor
<
0
||
d
.
cursor
>=
len
(
d
.
tokens
)
{
if
d
.
cursor
<
0
||
d
.
cursor
>=
len
(
d
.
tokens
)
{
return
""
return
""
...
@@ -105,23 +107,6 @@ func (d *dispenser) Val() string {
...
@@ -105,23 +107,6 @@ func (d *dispenser) Val() string {
}
}
}
}
// ArgErr returns an argument error, meaning that another
// argument was expected but not found. In other words,
// a line break or open curly brace was encountered instead of
// an argument.
func
(
d
*
dispenser
)
ArgErr
()
error
{
if
d
.
Val
()
==
"{"
{
return
d
.
Err
(
"Unexpected token '{', expecting argument"
)
}
return
d
.
Err
(
"Unexpected line break after '"
+
d
.
Val
()
+
"' (missing arguments?)"
)
}
// Err generates a custom parse error with a message of msg.
func
(
d
*
dispenser
)
Err
(
msg
string
)
error
{
msg
=
fmt
.
Sprintf
(
"%s:%d - Parse error: %s"
,
d
.
filename
,
d
.
tokens
[
d
.
cursor
]
.
line
,
msg
)
return
errors
.
New
(
msg
)
}
// Args is a convenience function that loads the next arguments
// Args is a convenience function that loads the next arguments
// (tokens on the same line) into an arbitrary number of strings
// (tokens on the same line) into an arbitrary number of strings
// pointed to in targets. If there are fewer tokens available
// pointed to in targets. If there are fewer tokens available
...
@@ -157,3 +142,20 @@ func (d *dispenser) RemainingArgs() []string {
...
@@ -157,3 +142,20 @@ func (d *dispenser) RemainingArgs() []string {
return
args
return
args
}
}
// ArgErr returns an argument error, meaning that another
// argument was expected but not found. In other words,
// a line break or open curly brace was encountered instead of
// an argument.
func
(
d
*
dispenser
)
ArgErr
()
error
{
if
d
.
Val
()
==
"{"
{
return
d
.
Err
(
"Unexpected token '{', expecting argument"
)
}
return
d
.
Err
(
"Unexpected line break after '"
+
d
.
Val
()
+
"' (missing arguments?)"
)
}
// Err generates a custom parse error with a message of msg.
func
(
d
*
dispenser
)
Err
(
msg
string
)
error
{
msg
=
fmt
.
Sprintf
(
"%s:%d - Parse error: %s"
,
d
.
filename
,
d
.
tokens
[
d
.
cursor
]
.
line
,
msg
)
return
errors
.
New
(
msg
)
}
config/parser.go
View file @
35225fe2
...
@@ -119,13 +119,18 @@ func (p *parser) parseOne() error {
...
@@ -119,13 +119,18 @@ func (p *parser) parseOne() error {
// executes the top-level functions (the generator function)
// executes the top-level functions (the generator function)
// to expose the second layers which are the actual middleware.
// to expose the second layers which are the actual middleware.
// This function should be called only after p has filled out
// This function should be called only after p has filled out
// p.other and th
at the entire server block has
been consumed.
// p.other and th
e entire server block has already
been consumed.
func
(
p
*
parser
)
unwrap
()
error
{
func
(
p
*
parser
)
unwrap
()
error
{
if
len
(
p
.
other
)
==
0
{
// no middlewares were invoked
return
nil
}
for
_
,
directive
:=
range
registry
.
ordered
{
for
_
,
directive
:=
range
registry
.
ordered
{
// TODO: For now, we only support the first and default path scope ("/")
// TODO: For now, we only support the first and default path scope ("/"
, held in p.other[0]
)
// but when we implement support for path scopes, we will have to
// but when we implement support for path scopes, we will have to
change this logic
//
change this logic to loop over them and order them. We need to account
//
to loop over them and order them. We need to account for situations where multiple
//
for situations where multiple
path scopes overlap, regex (??), etc...
// path scopes overlap, regex (??), etc...
if
disp
,
ok
:=
p
.
other
[
0
]
.
directives
[
directive
];
ok
{
if
disp
,
ok
:=
p
.
other
[
0
]
.
directives
[
directive
];
ok
{
if
generator
,
ok
:=
registry
.
directiveMap
[
directive
];
ok
{
if
generator
,
ok
:=
registry
.
directiveMap
[
directive
];
ok
{
mid
,
err
:=
generator
(
disp
)
mid
,
err
:=
generator
(
disp
)
...
@@ -141,6 +146,7 @@ func (p *parser) unwrap() error {
...
@@ -141,6 +146,7 @@ func (p *parser) unwrap() error {
}
}
}
}
}
}
return
nil
return
nil
}
}
...
...
middleware/gzip/gzip.go
View file @
35225fe2
...
@@ -11,6 +11,11 @@ import (
...
@@ -11,6 +11,11 @@ import (
"github.com/mholt/caddy/middleware"
"github.com/mholt/caddy/middleware"
)
)
// Gzip is a http.Handler middleware type which gzips HTTP responses.
type
Gzip
struct
{
Next
http
.
HandlerFunc
}
// New creates a new gzip middleware instance.
// New creates a new gzip middleware instance.
func
New
(
c
middleware
.
Controller
)
(
middleware
.
Middleware
,
error
)
{
func
New
(
c
middleware
.
Controller
)
(
middleware
.
Middleware
,
error
)
{
return
func
(
next
http
.
HandlerFunc
)
http
.
HandlerFunc
{
return
func
(
next
http
.
HandlerFunc
)
http
.
HandlerFunc
{
...
@@ -19,12 +24,6 @@ func New(c middleware.Controller) (middleware.Middleware, error) {
...
@@ -19,12 +24,6 @@ func New(c middleware.Controller) (middleware.Middleware, error) {
},
nil
},
nil
}
}
// Gzip is a http.Handler middleware type which gzips HTTP responses.
type
Gzip
struct
{
Next
http
.
HandlerFunc
// TODO: Compression level, other settings
}
// ServeHTTP serves a gzipped response if the client supports it.
// ServeHTTP serves a gzipped response if the client supports it.
func
(
g
Gzip
)
ServeHTTP
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
func
(
g
Gzip
)
ServeHTTP
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
if
!
strings
.
Contains
(
r
.
Header
.
Get
(
"Accept-Encoding"
),
"gzip"
)
{
if
!
strings
.
Contains
(
r
.
Header
.
Get
(
"Accept-Encoding"
),
"gzip"
)
{
...
...
middleware/middleware.go
View file @
35225fe2
...
@@ -13,23 +13,76 @@ type (
...
@@ -13,23 +13,76 @@ type (
// and returns the inner layer, which is the actual HandlerFunc.
// and returns the inner layer, which is the actual HandlerFunc.
Middleware
func
(
http
.
HandlerFunc
)
http
.
HandlerFunc
Middleware
func
(
http
.
HandlerFunc
)
http
.
HandlerFunc
//
Controller is the type which middleware generators use to access
//
A Control provides structured access to tokens from a configuration file
//
tokens and the server and any other information they need to
//
and also to properties of the server being configured. Middleware generators
//
configure themselves
.
//
use a Controller to construct their middleware instance
.
Controller
interface
{
Controller
interface
{
// Next loads the next token. Returns true if a token
// was loaded; false otherwise. If false, all tokens
// have already been consumed.
Next
()
bool
Next
()
bool
// NextArg loads the next token if it is on the same
// line. Returns true if a token was loaded; false
// otherwise. If false, all tokens on the line have
// been consumed.
NextArg
()
bool
NextArg
()
bool
// NextLine loads the next token only if it is NOT on the same
// line as the current token, and returns true if a token was
// loaded; false otherwise. If false, there is not another token
// or it is on the same line.
NextLine
()
bool
NextLine
()
bool
// NextBlock advances the cursor to the next token only
// if the current token is an open curly brace on the
// same line. If so, that token is consumed and this
// function will return true until the closing curly
// brace gets consumed by this method. Usually, you would
// use this as the condition of a for loop to parse
// tokens while being inside a block.
NextBlock
()
bool
NextBlock
()
bool
// Val gets the text of the current token.
Val
()
string
Val
()
string
// Args is a convenience function that loads the next arguments
// (tokens on the same line) into an arbitrary number of strings
// pointed to in arguments. If there are fewer tokens available
// than string pointers, the remaining strings will not be changed
// and false will be returned. If there were enough tokens available
// to fill the arguments, then true will be returned.
Args
(
...*
string
)
bool
Args
(
...*
string
)
bool
// RemainingArgs is a convenience function that loads any more arguments
// (tokens on the same line) into a slice and returns them. If an open curly
// brace token is encountered before the end of the line, that token is
// considered the end of the arguments (and the curly brace is not consumed).
RemainingArgs
()
[]
string
RemainingArgs
()
[]
string
// ArgErr returns an argument error, meaning that another
// argument was expected but not found. In other words,
// a line break, EOF, or open curly brace was encountered instead of
// an argument.
ArgErr
()
error
ArgErr
()
error
// Err generates a custom parse error with a message of msg.
Err
(
string
)
error
Err
(
string
)
error
// Startup registers a function to execute when the server starts.
Startup
(
func
()
error
)
Startup
(
func
()
error
)
// Root returns the file path from which the server is serving.
Root
()
string
Root
()
string
// Host returns the hostname the server is bound to.
Host
()
string
Host
()
string
// Port returns the port that the server is listening on.
Port
()
string
Port
()
string
// Context returns the path scope that the Controller is in.
// Note: This is not currently used, but may be in the future.
Context
()
Path
Context
()
Path
}
}
)
)
server/server.go
View file @
35225fe2
...
@@ -71,7 +71,6 @@ func (s *Server) Serve() error {
...
@@ -71,7 +71,6 @@ func (s *Server) Serve() error {
server
:=
&
http
.
Server
{
server
:=
&
http
.
Server
{
Addr
:
s
.
config
.
Address
(),
Addr
:
s
.
config
.
Address
(),
Handler
:
s
,
Handler
:
s
,
// TODO: Make more of the server configurable, also more http2 configurability
}
}
http2
.
ConfigureServer
(
server
,
nil
)
// TODO: This may not be necessary after HTTP/2 merged into std lib
http2
.
ConfigureServer
(
server
,
nil
)
// TODO: This may not be necessary after HTTP/2 merged into std lib
...
...
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