Minor updates

Matt Holt 2015-03-03 11:31:49 -07:00
parent 540491f2d2
commit 4609d55d54

@ -1,14 +1,14 @@
This page describes what middleware is related to Caddy and introduces you to a way to write your own middleware. This page describes what middleware is related to Caddy and introduces you to a way to write your own middleware.
Caddy is powerful because of its extensible middleware stack. Middleware have the power to parse their own directives from config files, run code when the server starts, and intercept requests before and after the response is written. Caddy is powerful because of its extensible middleware stack. Middleware have the power to parse their own directives from config files, run code when the server starts, and intercept requests before and after the response is written. Caddy middleware can also be used by any Go programs, as they are independent Go packages.
Middleware are registered, in a particular order, in the middleware.go file: For use with Caddy, middleware are registered in a particular order in the middleware.go file:
```go ```go
func init() { func init() {
register("gzip", Gzip) register("gzip", gzip.New)
register("header", Headers) register("header", headers.New)
register("log", RequestLog) register("log", log.New)
// etc ... // etc ...
} }
``` ```
@ -16,7 +16,7 @@ func init() {
Middleware take the basic form of a doubly-nested function: Middleware take the basic form of a doubly-nested function:
```go ```go
func MyMiddleware(p parser) Middleware { func MyMiddleware(c middleware.Controller) (middleware.Middleware, error) {
return func(next http.HandlerFunc) http.HandlerFunc { return func(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
// handler // handler
@ -26,15 +26,15 @@ func MyMiddleware(p parser) Middleware {
``` ```
- The inner-most layer is the actual HTTP request handler. - The inner-most layer is the actual HTTP request handler.
- The middle layer is the is the common notion of a "middleware": it wraps the next handler. - The middle layer is the is the common notion of a middleware (it wraps the next handler).
- The outer layer is a "middleware generator" which receives a parser. - The outer layer is a "middleware generator" which receives a parser.
Most of the logic will be in the generator and handler functions: Most of the logic will be in the generator (outer layer) and handler (inner layer) functions:
```go ```go
func MyMiddleware(p parser) Middleware { func MyMiddleware(c middleware.Controller) Middleware {
// use p to set up the middleware here // use c to set up the middleware here
return func(next http.HandlerFunc) http.HandlerFunc { return func(next http.HandlerFunc) http.HandlerFunc {
@ -49,30 +49,31 @@ func MyMiddleware(p parser) Middleware {
} }
``` ```
When `caddy` is run and the config file is parsed and found to use a middleware, that middleware is unwrapped one piece at a time, to eventually expose the underlying handler, which is ready to use thanks to Go closures. (The handler chain is pre-compiled so it doesn't have to do that for every request.) When `caddy` is run and the config file is parsed and found to use a middleware, that middleware is unwrapped one piece at a time to eventually expose the underlying handler, which is ready to use thanks to Go closures. (The handler chain is pre-compiled so it doesn't have to do that for every request.)
## Creating new middleware ## Creating new middleware
Extend Caddy by writing your own middleware! First open an issue to detail what you want it to do and how it will work, including what the syntax in the Caddyfile would look like. Then once it looks good, go ahead and submit a pull request. Extend Caddy by writing your own middleware! First open an issue to detail what you want it to do and how it will work, including what the syntax in the Caddyfile would look like. Then once it looks good and has tests, go ahead and submit a pull request.
So how do you start writing middleware? There are two main things to do: So how do you start writing middleware? There are two main things to do:
1. Write the middleware code 1. Write the middleware code
2. Register it with a certain directive in `init()` 2. Register it with a directive in `init()`
When the server starts up, it unwraps each middleware down to the actual handlers one piece at a time. (Middleware that aren't needed won't be invoked.) When the server starts up, it unwraps each middleware down to the actual handlers one piece at a time. (Middleware that aren't needed won't be invoked.)
### Parsing ### Parsing
The generator function is the first layer to be unwrapped. It is passed a parser, which you can use to get data out of the Caddyfile. Better documentation on how to do this is coming, but for now, look at examples of existing middleware. You have a lot of control and there's a lot of power in being able to do your own parsing of the config. The generator function is the first layer to be unwrapped. It is passed a controller which you can use to get data out of the Caddyfile. Better documentation on how to do this is coming, but for now, look at examples of existing middleware. You have a lot of control and there's a lot of power in being able to do your own parsing of the config.
### Handler logic ### Handler logic
Once your middleware is configured (the generator layer), the second layer will be used by the server to compile your handler into the chain. The handler can do whatever you need it to do, as long as it calls `next`. You have to have a deliberate reason to not call the next HandlerFunc. Once your middleware is configured (the generator layer), the second layer will be used by the server to compile your handler into the chain. The handler can do whatever you need it to do, as long as it calls `next`. You have to have a deliberate reason to not call the next HandlerFunc.
Again, look at existing middleware for examples. There's already a good variety to get you started. Again, look at existing middleware for examples. There's a good variety there to get you started.
### Registration ### Registration