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 {
return
c
.
parser
.
cfg
.
Port
}
// Context returns the path scope that the Controller is in.
func
(
c
*
controller
)
Context
()
middleware
.
Path
{
return
middleware
.
Path
(
c
.
pathScope
)
}
config/dispenser.go
View file @
35225fe2
...
...
@@ -5,10 +5,11 @@ import (
"fmt"
)
// dispenser is a type that gets exposed to middleware
// generators so that they can parse tokens to configure
// their instance. It basically dispenses tokens but can
// do so in a structured manner.
// dispenser is a type that dispenses tokens, similarly to
// a lexer, except that it can do so with some notion of
// structure. Its methods implement part of the
// middleware.Controller interface, so refer to that
// documentation for more info.
type
dispenser
struct
{
filename
string
cursor
int
...
...
@@ -18,15 +19,13 @@ type dispenser struct {
// Next loads the next token. Returns true if a token
// was loaded; false otherwise. If false, all tokens
// have been consumed.
// TODO: Have the other Next functions call this one...?
// have already been consumed.
func
(
d
*
dispenser
)
Next
()
bool
{
if
d
.
cursor
>=
len
(
d
.
tokens
)
-
1
{
return
false
}
else
{
if
d
.
cursor
<
len
(
d
.
tokens
)
-
1
{
d
.
cursor
++
return
true
}
return
false
}
// NextArg loads the next token if it is on the same
...
...
@@ -49,8 +48,10 @@ func (d *dispenser) NextArg() bool {
return
false
}
// TODO: Assert that there's a line break and only advance
// the token if that's the case? (store an error otherwise)
// 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.
func
(
d
*
dispenser
)
NextLine
()
bool
{
if
d
.
cursor
<
0
{
d
.
cursor
++
...
...
@@ -96,7 +97,8 @@ func (d *dispenser) NextBlock() bool {
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
{
if
d
.
cursor
<
0
||
d
.
cursor
>=
len
(
d
.
tokens
)
{
return
""
...
...
@@ -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
// (tokens on the same line) into an arbitrary number of strings
// pointed to in targets. If there are fewer tokens available
...
...
@@ -157,3 +142,20 @@ func (d *dispenser) RemainingArgs() []string {
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 {
// executes the top-level functions (the generator function)
// to expose the second layers which are the actual middleware.
// 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
{
if
len
(
p
.
other
)
==
0
{
// no middlewares were invoked
return
nil
}
for
_
,
directive
:=
range
registry
.
ordered
{
// TODO: For now, we only support the first and default path scope ("/")
// but when we implement support for path scopes, we will have to
//
change this logic to loop over them and order them. We need to account
//
for situations where multiple
path scopes overlap, regex (??), etc...
// 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
change this logic
//
to loop over them and order them. We need to account for situations where multiple
// path scopes overlap, regex (??), etc...
if
disp
,
ok
:=
p
.
other
[
0
]
.
directives
[
directive
];
ok
{
if
generator
,
ok
:=
registry
.
directiveMap
[
directive
];
ok
{
mid
,
err
:=
generator
(
disp
)
...
...
@@ -141,6 +146,7 @@ func (p *parser) unwrap() error {
}
}
}
return
nil
}
...
...
middleware/gzip/gzip.go
View file @
35225fe2
...
...
@@ -11,6 +11,11 @@ import (
"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.
func
New
(
c
middleware
.
Controller
)
(
middleware
.
Middleware
,
error
)
{
return
func
(
next
http
.
HandlerFunc
)
http
.
HandlerFunc
{
...
...
@@ -19,12 +24,6 @@ func New(c middleware.Controller) (middleware.Middleware, error) {
},
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.
func
(
g
Gzip
)
ServeHTTP
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
if
!
strings
.
Contains
(
r
.
Header
.
Get
(
"Accept-Encoding"
),
"gzip"
)
{
...
...
middleware/middleware.go
View file @
35225fe2
...
...
@@ -13,23 +13,76 @@ type (
// and returns the inner layer, which is the actual HandlerFunc.
Middleware
func
(
http
.
HandlerFunc
)
http
.
HandlerFunc
//
Controller is the type which middleware generators use to access
//
tokens and the server and any other information they need to
//
configure themselves
.
//
A Control provides structured access to tokens from a configuration file
//
and also to properties of the server being configured. Middleware generators
//
use a Controller to construct their middleware instance
.
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
// 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
// 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
// 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
// Val gets the text of the current token.
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
// 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
// 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
// Err generates a custom parse error with a message of msg.
Err
(
string
)
error
// Startup registers a function to execute when the server starts.
Startup
(
func
()
error
)
// Root returns the file path from which the server is serving.
Root
()
string
// Host returns the hostname the server is bound to.
Host
()
string
// Port returns the port that the server is listening on.
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
}
)
server/server.go
View file @
35225fe2
...
...
@@ -71,7 +71,6 @@ func (s *Server) Serve() error {
server
:=
&
http
.
Server
{
Addr
:
s
.
config
.
Address
(),
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
...
...
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