directives.go 2.61 KB
Newer Older
Matthew Holt's avatar
Matthew Holt committed
1 2
package config

3
import (
4 5
	"github.com/mholt/caddy/config/parse"
	"github.com/mholt/caddy/config/setup"
6
	"github.com/mholt/caddy/middleware"
7
)
8

Matthew Holt's avatar
Matthew Holt committed
9
func init() {
10 11
	// The parse package must know which directives
	// are valid, but it must not import the setup
12 13 14 15
	// or config package. To solve this problem, we
	// fill up this map in our init function here.
	// The parse package does not need to know the
	// ordering of the directives.
16 17 18 19
	for _, dir := range directiveOrder {
		parse.ValidDirectives[dir.name] = struct{}{}
	}
}
20

21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
// Directives are registered in the order they should be
// executed. Middleware (directives that inject a handler)
// are executed in the order A-B-C-*-C-B-A, assuming
// they all call the Next handler in the chain.
//
// Ordering is VERY important. Every middleware will
// feel the effects of all other middleware below
// (after) them during a request, but they must not
// care what middleware above them are doing.
//
// For example, log needs to know the status code and
// exactly how many bytes were written to the client,
// which every other middleware can affect, so it gets
// registered first. The errors middleware does not
// care if gzip or log modifies its response, so it
// gets registered below them. Gzip, on the other hand,
// DOES care what errors does to the response since it
// must compress every output to the client, even error
// pages, so it must be registered before the errors
// middleware and any others that would write to the
// response.
42
var directiveOrder = []directive{
43
	// Essential directives that initialize vital configuration settings
44 45
	{"root", setup.Root},
	{"tls", setup.TLS},
46
	{"bind", setup.BindHost},
47 48

	// Other directives that don't create HTTP handlers
49 50 51
	{"startup", setup.Startup},
	{"shutdown", setup.Shutdown},

52
	// Directives that inject handlers (middleware)
53 54 55 56 57 58 59
	{"log", setup.Log},
	{"gzip", setup.Gzip},
	{"errors", setup.Errors},
	{"header", setup.Headers},
	{"rewrite", setup.Rewrite},
	{"redir", setup.Redir},
	{"ext", setup.Ext},
60
	{"mime", setup.Mime},
61
	{"basicauth", setup.BasicAuth},
Michael Schoebel's avatar
Michael Schoebel committed
62
	{"internal", setup.Internal},
63 64
	{"proxy", setup.Proxy},
	{"fastcgi", setup.FastCGI},
65 66 67 68
	{"websocket", setup.WebSocket},
	{"markdown", setup.Markdown},
	{"templates", setup.Templates},
	{"browse", setup.Browse},
69
}
70

71
// directive ties together a directive name with its setup function.
72 73
type directive struct {
	name  string
74
	setup SetupFunc
Matthew Holt's avatar
Matthew Holt committed
75
}
76

77 78 79
// A setup function takes a setup controller. Its return values may
// both be nil. If middleware is not nil, it will be chained into
// the HTTP handlers in the order specified in this package.
80
type SetupFunc func(c *setup.Controller) (middleware.Middleware, error)