diff --git a/Middleware.md b/Middleware.md deleted file mode 100644 index 2bd372d..0000000 --- a/Middleware.md +++ /dev/null @@ -1,80 +0,0 @@ -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 middleware can also be used by any Go programs, as they are independent Go packages. - -For use with Caddy, middleware are registered in a particular order in the middleware.go file: - -```go -func init() { - register("gzip", gzip.New) - register("header", headers.New) - register("log", log.New) - // etc ... -} -``` - -Middleware take the basic form of a doubly-nested function: - -```go -func MyMiddleware(c middleware.Controller) (middleware.Middleware, error) { - return func(next http.HandlerFunc) http.HandlerFunc { - return func(w http.ResponseWriter, r *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 outer layer is a "middleware generator" which receives a parser. - -Most of the logic will be in the generator (outer layer) and handler (inner layer) functions: - -```go -func MyMiddleware(c middleware.Controller) Middleware { - - // use c to set up the middleware here - - return func(next http.HandlerFunc) http.HandlerFunc { - - // not much usually happens here - - return func(w http.ResponseWriter, r *http.Request) { - // do stuff before - next(w, r) - // do stuff after - } - } -} -``` - -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 - -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: - -1. Write the middleware code -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.) - -### Parsing - -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 - -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 a good variety there to get you started. - - -### Registration - -Now that your middleware is ready, register it to a directive. In the `init()` function of the `middleware.go` file, there are a bunch of `register()` calls made. Simply register your middleware in the proper spot (ordering is important, depending on what it does) and with the specific directive that activates your middleware. You can bind to more than one directive, but this is rare and should be discussed in an issue first. \ No newline at end of file