Refactor how caddy.Context is stored and used

- Server types no longer need to store their own contexts; they are
  stored on the caddy.Instance, which means each context will be
  properly GC'ed when the instance is stopped. Server types should use
  type assertions to convert from caddy.Context to their concrete
  context type when they need to use it.
- Pass the entire context into httpserver.GetConfig instead of only the
  Key field.
- caddy.NewTestController now requires a server type string so it can
  create a controller with the proper concrete context associated with
  that server type.

Tests still need more attention so that we can test the proper creation
of startup functions, etc.
This commit is contained in:
Matthew Holt 2016-06-20 11:44:20 -06:00
parent 07b7c99965
commit a798e0c951
49 changed files with 199 additions and 167 deletions

View file

@ -67,7 +67,10 @@ type Instance struct {
// wg is used to wait for all servers to shut down // wg is used to wait for all servers to shut down
wg *sync.WaitGroup wg *sync.WaitGroup
// servers is the list of servers with their listeners... // context is the context created for this instance.
context Context
// servers is the list of servers with their listeners.
servers []serverListener servers []serverListener
// these are callbacks to execute when certain events happen // these are callbacks to execute when certain events happen
@ -386,9 +389,12 @@ func startWithListenerFds(cdyfile Input, inst *Instance, restartFds map[string]r
return err return err
} }
ctx := stype.NewContext() inst.context = stype.NewContext()
if inst.context == nil {
return fmt.Errorf("server type %s produced a nil Context", stypeName)
}
sblocks, err = ctx.InspectServerBlocks(cdyfile.Path(), sblocks) sblocks, err = inst.context.InspectServerBlocks(cdyfile.Path(), sblocks)
if err != nil { if err != nil {
return err return err
} }
@ -398,7 +404,7 @@ func startWithListenerFds(cdyfile Input, inst *Instance, restartFds map[string]r
return err return err
} }
slist, err := ctx.MakeServers() slist, err := inst.context.MakeServers()
if err != nil { if err != nil {
return err return err
} }
@ -496,7 +502,7 @@ func executeDirectives(inst *Instance, filename string,
if allCallbacks, ok := parsingCallbacks[inst.serverType]; ok { if allCallbacks, ok := parsingCallbacks[inst.serverType]; ok {
callbacks := allCallbacks[dir] callbacks := allCallbacks[dir]
for _, callback := range callbacks { for _, callback := range callbacks {
if err := callback(); err != nil { if err := callback(inst.context); err != nil {
return err return err
} }
} }

View file

@ -16,7 +16,7 @@ func init() {
// setup configures a new BasicAuth middleware instance. // setup configures a new BasicAuth middleware instance.
func setup(c *caddy.Controller) error { func setup(c *caddy.Controller) error {
cfg := httpserver.GetConfig(c.Key) cfg := httpserver.GetConfig(c)
root := cfg.Root root := cfg.Root
rules, err := basicAuthParse(c) rules, err := basicAuthParse(c)
@ -37,7 +37,7 @@ func setup(c *caddy.Controller) error {
func basicAuthParse(c *caddy.Controller) ([]Rule, error) { func basicAuthParse(c *caddy.Controller) ([]Rule, error) {
var rules []Rule var rules []Rule
cfg := httpserver.GetConfig(c.Key) cfg := httpserver.GetConfig(c)
var err error var err error
for c.Next() { for c.Next() {

View file

@ -12,11 +12,12 @@ import (
) )
func TestSetup(t *testing.T) { func TestSetup(t *testing.T) {
err := setup(caddy.NewTestController(`basicauth user pwd`)) c := caddy.NewTestController("http", `basicauth user pwd`)
err := setup(c)
if err != nil { if err != nil {
t.Errorf("Expected no errors, but got: %v", err) t.Errorf("Expected no errors, but got: %v", err)
} }
mids := httpserver.GetConfig("").Middleware() mids := httpserver.GetConfig(c).Middleware()
if len(mids) == 0 { if len(mids) == 0 {
t.Fatal("Expected middleware, got 0 instead") t.Fatal("Expected middleware, got 0 instead")
} }
@ -87,7 +88,7 @@ md5:$apr1$l42y8rex$pOA2VJ0x/0TwaFeAF9nX61`
} }
for i, test := range tests { for i, test := range tests {
actual, err := basicAuthParse(caddy.NewTestController(test.input)) actual, err := basicAuthParse(caddy.NewTestController("http", test.input))
if err == nil && test.shouldErr { if err == nil && test.shouldErr {
t.Errorf("Test %d didn't error, but it should have", i) t.Errorf("Test %d didn't error, but it should have", i)

View file

@ -13,7 +13,7 @@ func init() {
} }
func setupBind(c *caddy.Controller) error { func setupBind(c *caddy.Controller) error {
config := httpserver.GetConfig(c.Key) config := httpserver.GetConfig(c)
for c.Next() { for c.Next() {
if !c.Args(&config.ListenHost) { if !c.Args(&config.ListenHost) {
return c.ArgErr() return c.ArgErr()

View file

@ -8,12 +8,13 @@ import (
) )
func TestSetupBind(t *testing.T) { func TestSetupBind(t *testing.T) {
err := setupBind(caddy.NewTestController(`bind 1.2.3.4`)) c := caddy.NewTestController("http", `bind 1.2.3.4`)
err := setupBind(c)
if err != nil { if err != nil {
t.Fatalf("Expected no errors, but got: %v", err) t.Fatalf("Expected no errors, but got: %v", err)
} }
cfg := httpserver.GetConfig("") cfg := httpserver.GetConfig(c)
if got, want := cfg.ListenHost, "1.2.3.4"; got != want { if got, want := cfg.ListenHost, "1.2.3.4"; got != want {
t.Errorf("Expected the config's ListenHost to be %s, was %s", want, got) t.Errorf("Expected the config's ListenHost to be %s, was %s", want, got)
} }

View file

@ -29,7 +29,7 @@ func setup(c *caddy.Controller) error {
IgnoreIndexes: false, IgnoreIndexes: false,
} }
httpserver.GetConfig(c.Key).AddMiddleware(func(next httpserver.Handler) httpserver.Handler { httpserver.GetConfig(c).AddMiddleware(func(next httpserver.Handler) httpserver.Handler {
b.Next = next b.Next = next
return b return b
}) })
@ -40,7 +40,7 @@ func setup(c *caddy.Controller) error {
func browseParse(c *caddy.Controller) ([]Config, error) { func browseParse(c *caddy.Controller) ([]Config, error) {
var configs []Config var configs []Config
cfg := httpserver.GetConfig(c.Key) cfg := httpserver.GetConfig(c)
appendCfg := func(bc Config) error { appendCfg := func(bc Config) error {
for _, c := range configs { for _, c := range configs {

View file

@ -49,14 +49,15 @@ func TestSetup(t *testing.T) {
{"browse " + tempDirPath + "\n browse " + tempDirPath, nil, true}, {"browse " + tempDirPath + "\n browse " + tempDirPath, nil, true},
} { } {
err := setup(caddy.NewTestController(test.input)) c := caddy.NewTestController("http", test.input)
err := setup(c)
if err != nil && !test.shouldErr { if err != nil && !test.shouldErr {
t.Errorf("Test case #%d recieved an error of %v", i, err) t.Errorf("Test case #%d recieved an error of %v", i, err)
} }
if test.expectedPathScope == nil { if test.expectedPathScope == nil {
continue continue
} }
mids := httpserver.GetConfig("").Middleware() mids := httpserver.GetConfig(c).Middleware()
mid := mids[len(mids)-1] mid := mids[len(mids)-1]
recievedConfigs := mid(nil).(Browse).Configs recievedConfigs := mid(nil).(Browse).Configs
for j, config := range recievedConfigs { for j, config := range recievedConfigs {

View file

@ -62,7 +62,7 @@ func setup(c *caddy.Controller) error {
return nil return nil
}) })
httpserver.GetConfig(c.Key).AddMiddleware(func(next httpserver.Handler) httpserver.Handler { httpserver.GetConfig(c).AddMiddleware(func(next httpserver.Handler) httpserver.Handler {
handler.Next = next handler.Next = next
return handler return handler
}) })
@ -76,7 +76,7 @@ func errorsParse(c *caddy.Controller) (*ErrorHandler, error) {
// same instance of the handler, not a copy. // same instance of the handler, not a copy.
handler := &ErrorHandler{ErrorPages: make(map[int]string)} handler := &ErrorHandler{ErrorPages: make(map[int]string)}
cfg := httpserver.GetConfig(c.Key) cfg := httpserver.GetConfig(c)
optionalBlock := func() (bool, error) { optionalBlock := func() (bool, error) {
var hadBlock bool var hadBlock bool

View file

@ -8,11 +8,12 @@ import (
) )
func TestSetup(t *testing.T) { func TestSetup(t *testing.T) {
err := setup(caddy.NewTestController(`errors`)) c := caddy.NewTestController("http", `errors`)
err := setup(c)
if err != nil { if err != nil {
t.Errorf("Expected no errors, got: %v", err) t.Errorf("Expected no errors, got: %v", err)
} }
mids := httpserver.GetConfig("").Middleware() mids := httpserver.GetConfig(c).Middleware()
if len(mids) == 0 { if len(mids) == 0 {
t.Fatal("Expected middlewares, was nil instead") t.Fatal("Expected middlewares, was nil instead")
} }
@ -104,7 +105,7 @@ func TestErrorsParse(t *testing.T) {
}}, }},
} }
for i, test := range tests { for i, test := range tests {
actualErrorsRule, err := errorsParse(caddy.NewTestController(test.inputErrorsRules)) actualErrorsRule, err := errorsParse(caddy.NewTestController("http", test.inputErrorsRules))
if err == nil && test.shouldErr { if err == nil && test.shouldErr {
t.Errorf("Test %d didn't error, but it should have", i) t.Errorf("Test %d didn't error, but it should have", i)

View file

@ -28,7 +28,7 @@ func setup(c *caddy.Controller) error {
ev := ExpVar{Resource: resource} ev := ExpVar{Resource: resource}
httpserver.GetConfig(c.Key).AddMiddleware(func(next httpserver.Handler) httpserver.Handler { httpserver.GetConfig(c).AddMiddleware(func(next httpserver.Handler) httpserver.Handler {
ev.Next = next ev.Next = next
return ev return ev
}) })

View file

@ -8,25 +8,27 @@ import (
) )
func TestSetup(t *testing.T) { func TestSetup(t *testing.T) {
err := setup(caddy.NewTestController(`expvar`)) c := caddy.NewTestController("http", `expvar`)
err := setup(c)
if err != nil { if err != nil {
t.Errorf("Expected no errors, got: %v", err) t.Errorf("Expected no errors, got: %v", err)
} }
mids := httpserver.GetConfig("").Middleware() mids := httpserver.GetConfig(c).Middleware()
if len(mids) == 0 { if len(mids) == 0 {
t.Fatal("Expected middleware, got 0 instead") t.Fatal("Expected middleware, got 0 instead")
} }
err = setup(caddy.NewTestController(`expvar /d/v`)) c = caddy.NewTestController("http", `expvar /d/v`)
err = setup(c)
if err != nil { if err != nil {
t.Errorf("Expected no errors, got: %v", err) t.Errorf("Expected no errors, got: %v", err)
} }
mids = httpserver.GetConfig("").Middleware() mids = httpserver.GetConfig(c).Middleware()
if len(mids) == 0 { if len(mids) == 0 {
t.Fatal("Expected middleware, got 0 instead") t.Fatal("Expected middleware, got 0 instead")
} }
handler := mids[1](httpserver.EmptyNext) handler := mids[0](httpserver.EmptyNext)
myHandler, ok := handler.(ExpVar) myHandler, ok := handler.(ExpVar)
if !ok { if !ok {
t.Fatalf("Expected handler to be type ExpVar, got: %#v", handler) t.Fatalf("Expected handler to be type ExpVar, got: %#v", handler)

View file

@ -14,7 +14,7 @@ func init() {
// setup configures a new instance of 'extensions' middleware for clean URLs. // setup configures a new instance of 'extensions' middleware for clean URLs.
func setup(c *caddy.Controller) error { func setup(c *caddy.Controller) error {
cfg := httpserver.GetConfig(c.Key) cfg := httpserver.GetConfig(c)
root := cfg.Root root := cfg.Root
exts, err := extParse(c) exts, err := extParse(c)
@ -22,7 +22,7 @@ func setup(c *caddy.Controller) error {
return err return err
} }
httpserver.GetConfig(c.Key).AddMiddleware(func(next httpserver.Handler) httpserver.Handler { httpserver.GetConfig(c).AddMiddleware(func(next httpserver.Handler) httpserver.Handler {
return Ext{ return Ext{
Next: next, Next: next,
Extensions: exts, Extensions: exts,

View file

@ -8,12 +8,13 @@ import (
) )
func TestSetup(t *testing.T) { func TestSetup(t *testing.T) {
err := setup(caddy.NewTestController(`ext .html .htm .php`)) c := caddy.NewTestController("http", `ext .html .htm .php`)
err := setup(c)
if err != nil { if err != nil {
t.Fatalf("Expected no errors, got: %v", err) t.Fatalf("Expected no errors, got: %v", err)
} }
mids := httpserver.GetConfig("").Middleware() mids := httpserver.GetConfig(c).Middleware()
if len(mids) == 0 { if len(mids) == 0 {
t.Fatal("Expected middleware, had 0 instead") t.Fatal("Expected middleware, had 0 instead")
} }
@ -51,7 +52,7 @@ func TestExtParse(t *testing.T) {
{`ext .txt .php .xml`, false, []string{".txt", ".php", ".xml"}}, {`ext .txt .php .xml`, false, []string{".txt", ".php", ".xml"}},
} }
for i, test := range tests { for i, test := range tests {
actualExts, err := extParse(caddy.NewTestController(test.inputExts)) actualExts, err := extParse(caddy.NewTestController("http", test.inputExts))
if err == nil && test.shouldErr { if err == nil && test.shouldErr {
t.Errorf("Test %d didn't error, but it should have", i) t.Errorf("Test %d didn't error, but it should have", i)

View file

@ -18,7 +18,7 @@ func init() {
// setup configures a new FastCGI middleware instance. // setup configures a new FastCGI middleware instance.
func setup(c *caddy.Controller) error { func setup(c *caddy.Controller) error {
cfg := httpserver.GetConfig(c.Key) cfg := httpserver.GetConfig(c)
absRoot, err := filepath.Abs(cfg.Root) absRoot, err := filepath.Abs(cfg.Root)
if err != nil { if err != nil {
return err return err

View file

@ -9,11 +9,12 @@ import (
) )
func TestSetup(t *testing.T) { func TestSetup(t *testing.T) {
err := setup(caddy.NewTestController(`fastcgi / 127.0.0.1:9000`)) c := caddy.NewTestController("http", `fastcgi / 127.0.0.1:9000`)
err := setup(c)
if err != nil { if err != nil {
t.Errorf("Expected no errors, got: %v", err) t.Errorf("Expected no errors, got: %v", err)
} }
mids := httpserver.GetConfig("").Middleware() mids := httpserver.GetConfig(c).Middleware()
if len(mids) == 0 { if len(mids) == 0 {
t.Fatal("Expected middleware, got 0 instead") t.Fatal("Expected middleware, got 0 instead")
} }
@ -73,7 +74,7 @@ func TestFastcgiParse(t *testing.T) {
}}}, }}},
} }
for i, test := range tests { for i, test := range tests {
actualFastcgiConfigs, err := fastcgiParse(caddy.NewTestController(test.inputFastcgiConfig)) actualFastcgiConfigs, err := fastcgiParse(caddy.NewTestController("http", test.inputFastcgiConfig))
if err == nil && test.shouldErr { if err == nil && test.shouldErr {
t.Errorf("Test %d didn't error, but it should have", i) t.Errorf("Test %d didn't error, but it should have", i)

View file

@ -16,7 +16,7 @@ func setup(c *caddy.Controller) error {
return err return err
} }
httpserver.GetConfig(c.Key).AddMiddleware(func(next httpserver.Handler) httpserver.Handler { httpserver.GetConfig(c).AddMiddleware(func(next httpserver.Handler) httpserver.Handler {
return Gzip{Next: next, Configs: configs} return Gzip{Next: next, Configs: configs}
}) })

View file

@ -8,11 +8,12 @@ import (
) )
func TestSetup(t *testing.T) { func TestSetup(t *testing.T) {
err := setup(caddy.NewTestController(`gzip`)) c := caddy.NewTestController("http", `gzip`)
err := setup(c)
if err != nil { if err != nil {
t.Errorf("Expected no errors, but got: %v", err) t.Errorf("Expected no errors, but got: %v", err)
} }
mids := httpserver.GetConfig("").Middleware() mids := httpserver.GetConfig(c).Middleware()
if mids == nil { if mids == nil {
t.Fatal("Expected middleware, was nil instead") t.Fatal("Expected middleware, was nil instead")
} }
@ -90,7 +91,7 @@ func TestSetup(t *testing.T) {
`, false}, `, false},
} }
for i, test := range tests { for i, test := range tests {
_, err := gzipParse(caddy.NewTestController(test.input)) _, err := gzipParse(caddy.NewTestController("http", test.input))
if test.shouldErr && err == nil { if test.shouldErr && err == nil {
t.Errorf("Test %v: Expected error but found nil", i) t.Errorf("Test %v: Expected error but found nil", i)
} else if !test.shouldErr && err != nil { } else if !test.shouldErr && err != nil {

View file

@ -19,7 +19,7 @@ func setup(c *caddy.Controller) error {
return err return err
} }
httpserver.GetConfig(c.Key).AddMiddleware(func(next httpserver.Handler) httpserver.Handler { httpserver.GetConfig(c).AddMiddleware(func(next httpserver.Handler) httpserver.Handler {
return Headers{Next: next, Rules: rules} return Headers{Next: next, Rules: rules}
}) })

View file

@ -9,12 +9,13 @@ import (
) )
func TestSetup(t *testing.T) { func TestSetup(t *testing.T) {
err := setup(caddy.NewTestController(`header / Foo Bar`)) c := caddy.NewTestController("http", `header / Foo Bar`)
err := setup(c)
if err != nil { if err != nil {
t.Errorf("Expected no errors, but got: %v", err) t.Errorf("Expected no errors, but got: %v", err)
} }
mids := httpserver.GetConfig("").Middleware() mids := httpserver.GetConfig(c).Middleware()
if len(mids) == 0 { if len(mids) == 0 {
t.Fatal("Expected middleware, had 0 instead") t.Fatal("Expected middleware, had 0 instead")
} }
@ -52,7 +53,7 @@ func TestHeadersParse(t *testing.T) {
} }
for i, test := range tests { for i, test := range tests {
actual, err := headersParse(caddy.NewTestController(test.input)) actual, err := headersParse(caddy.NewTestController("http", test.input))
if err == nil && test.shouldErr { if err == nil && test.shouldErr {
t.Errorf("Test %d didn't error, but it should have", i) t.Errorf("Test %d didn't error, but it should have", i)

View file

@ -4,12 +4,13 @@ import (
"net" "net"
"net/http" "net/http"
"github.com/mholt/caddy"
"github.com/mholt/caddy/caddytls" "github.com/mholt/caddy/caddytls"
) )
func activateHTTPS() error { func activateHTTPS(cctx caddy.Context) error {
// TODO: Is this loop a bug? Should we scope this method to just a single context? (restarts...?) ctx := cctx.(*httpContext)
for _, ctx := range contexts {
// pre-screen each config and earmark the ones that qualify for managed TLS // pre-screen each config and earmark the ones that qualify for managed TLS
markQualifiedForAutoHTTPS(ctx.siteConfigs) markQualifiedForAutoHTTPS(ctx.siteConfigs)
@ -29,12 +30,11 @@ func activateHTTPS() error {
// set up redirects // set up redirects
ctx.siteConfigs = makePlaintextRedirects(ctx.siteConfigs) ctx.siteConfigs = makePlaintextRedirects(ctx.siteConfigs)
}
// renew all relevant certificates that need renewal. this is important // renew all relevant certificates that need renewal. this is important
// to do right away so we guarantee that renewals aren't missed, and // to do right away so we guarantee that renewals aren't missed, and
// also the user can respond to any potential errors that occur. // also the user can respond to any potential errors that occur.
err := caddytls.RenewManagedCertificates(true) err = caddytls.RenewManagedCertificates(true)
if err != nil { if err != nil {
return err return err
} }

View file

@ -44,16 +44,11 @@ func init() {
}) })
caddy.RegisterCaddyfileLoader("short", caddy.LoaderFunc(shortCaddyfileLoader)) caddy.RegisterCaddyfileLoader("short", caddy.LoaderFunc(shortCaddyfileLoader))
caddy.RegisterParsingCallback(serverType, "tls", activateHTTPS) caddy.RegisterParsingCallback(serverType, "tls", activateHTTPS)
caddytls.RegisterConfigGetter(serverType, func(key string) *caddytls.Config { return GetConfig(key).TLS }) caddytls.RegisterConfigGetter(serverType, func(c *caddy.Controller) *caddytls.Config { return GetConfig(c).TLS })
} }
var contexts []*httpContext
func newContext() caddy.Context { func newContext() caddy.Context {
context := &httpContext{keysToSiteConfigs: make(map[string]*SiteConfig)} return &httpContext{keysToSiteConfigs: make(map[string]*SiteConfig)}
// put the new context at start to allow setup of directives on new instance
contexts = append([]*httpContext{context}, contexts...)
return context
} }
type httpContext struct { type httpContext struct {
@ -67,6 +62,11 @@ type httpContext struct {
siteConfigs []*SiteConfig siteConfigs []*SiteConfig
} }
func (h *httpContext) saveConfig(key string, cfg *SiteConfig) {
h.siteConfigs = append(h.siteConfigs, cfg)
h.keysToSiteConfigs[key] = cfg
}
// InspectServerBlocks make sure that everything checks out before // InspectServerBlocks make sure that everything checks out before
// executing directives and otherwise prepares the directives to // executing directives and otherwise prepares the directives to
// be parsed and executed. // be parsed and executed.
@ -89,15 +89,14 @@ func (h *httpContext) InspectServerBlocks(sourceFile string, serverBlocks []cadd
TLS: &caddytls.Config{Hostname: addr.Host}, TLS: &caddytls.Config{Hostname: addr.Host},
HiddenFiles: []string{sourceFile}, HiddenFiles: []string{sourceFile},
} }
h.siteConfigs = append(h.siteConfigs, cfg) h.saveConfig(key, cfg)
h.keysToSiteConfigs[key] = cfg
} }
} }
// For sites that have gzip (which gets chained in // For sites that have gzip (which gets chained in
// before the error handler) we should ensure that the // before the error handler) we should ensure that the
// errors directive also appears so error pages aren't // errors directive also appears so error pages aren't
// written after the gzip writer is closed. // written after the gzip writer is closed. See #616.
for _, sb := range serverBlocks { for _, sb := range serverBlocks {
_, hasGzip := sb.Tokens["gzip"] _, hasGzip := sb.Tokens["gzip"]
_, hasErrors := sb.Tokens["errors"] _, hasErrors := sb.Tokens["errors"]
@ -129,6 +128,12 @@ func (h *httpContext) MakeServers() ([]caddy.Server, error) {
// is incorrect for this site. // is incorrect for this site.
cfg.Addr.Scheme = "https" cfg.Addr.Scheme = "https"
} }
if cfg.Addr.Port == "" {
// this is vital, otherwise the function call below that
// sets the listener address will use the default port
// instead of 443 because it doesn't know about TLS.
cfg.Addr.Port = "443"
}
} }
// we must map (group) each config to a bind address // we must map (group) each config to a bind address
@ -150,27 +155,19 @@ func (h *httpContext) MakeServers() ([]caddy.Server, error) {
return servers, nil return servers, nil
} }
// GetConfig gets a SiteConfig that is keyed by addrKey. // GetConfig gets the SiteConfig that corresponds to c.
// It creates an empty one in the latest context if // If none exist (should only happen in tests), then a
// the key does not exist in any context, so it // new, empty one will be created.
// will never return nil. If no contexts exist (which func GetConfig(c *caddy.Controller) *SiteConfig {
// should never happen except in tests), it creates a ctx := c.Context().(*httpContext)
// new context in which to put it. if cfg, ok := ctx.keysToSiteConfigs[c.Key]; ok {
func GetConfig(addrKey string) *SiteConfig {
for _, context := range contexts {
if cfg, ok := context.keysToSiteConfigs[addrKey]; ok {
return cfg return cfg
} }
} // we should only get here during tests because directive
if len(contexts) == 0 { // actions typically skip the server blocks where we make
// this shouldn't happen except in tests // the configs
newContext() ctx.saveConfig(c.Key, &SiteConfig{Root: Root, TLS: new(caddytls.Config)})
} return GetConfig(c)
cfg := &SiteConfig{Root: Root, TLS: new(caddytls.Config)}
defaultCtx := contexts[len(contexts)-1]
defaultCtx.siteConfigs = append(defaultCtx.siteConfigs, cfg)
defaultCtx.keysToSiteConfigs[addrKey] = cfg
return cfg
} }
// shortCaddyfileLoader loads a Caddyfile if positional arguments are // shortCaddyfileLoader loads a Caddyfile if positional arguments are

View file

@ -19,7 +19,7 @@ func setup(c *caddy.Controller) error {
return err return err
} }
httpserver.GetConfig(c.Key).AddMiddleware(func(next httpserver.Handler) httpserver.Handler { httpserver.GetConfig(c).AddMiddleware(func(next httpserver.Handler) httpserver.Handler {
return Internal{Next: next, Paths: paths} return Internal{Next: next, Paths: paths}
}) })

View file

@ -8,11 +8,12 @@ import (
) )
func TestSetup(t *testing.T) { func TestSetup(t *testing.T) {
err := setup(caddy.NewTestController(`internal /internal`)) c := caddy.NewTestController("http", `internal /internal`)
err := setup(c)
if err != nil { if err != nil {
t.Errorf("Expected no errors, got: %v", err) t.Errorf("Expected no errors, got: %v", err)
} }
mids := httpserver.GetConfig("").Middleware() mids := httpserver.GetConfig(c).Middleware()
if len(mids) == 0 { if len(mids) == 0 {
t.Fatal("Expected middleware, got 0 instead") t.Fatal("Expected middleware, got 0 instead")
} }
@ -46,7 +47,7 @@ func TestInternalParse(t *testing.T) {
internal /internal2`, false, []string{"/internal1", "/internal2"}}, internal /internal2`, false, []string{"/internal1", "/internal2"}},
} }
for i, test := range tests { for i, test := range tests {
actualInternalPaths, err := internalParse(caddy.NewTestController(test.inputInternalPaths)) actualInternalPaths, err := internalParse(caddy.NewTestController("http", test.inputInternalPaths))
if err == nil && test.shouldErr { if err == nil && test.shouldErr {
t.Errorf("Test %d didn't error, but it should have", i) t.Errorf("Test %d didn't error, but it should have", i)

View file

@ -53,7 +53,7 @@ func setup(c *caddy.Controller) error {
return nil return nil
}) })
httpserver.GetConfig(c.Key).AddMiddleware(func(next httpserver.Handler) httpserver.Handler { httpserver.GetConfig(c).AddMiddleware(func(next httpserver.Handler) httpserver.Handler {
return Logger{Next: next, Rules: rules, ErrorFunc: httpserver.DefaultErrorFunc} return Logger{Next: next, Rules: rules, ErrorFunc: httpserver.DefaultErrorFunc}
}) })

View file

@ -8,13 +8,12 @@ import (
) )
func TestSetup(t *testing.T) { func TestSetup(t *testing.T) {
cfg := httpserver.GetConfig("") c := caddy.NewTestController("http", `log`)
err := setup(c)
err := setup(caddy.NewTestController(`log`))
if err != nil { if err != nil {
t.Errorf("Expected no errors, got: %v", err) t.Errorf("Expected no errors, got: %v", err)
} }
cfg := httpserver.GetConfig(c)
mids := cfg.Middleware() mids := cfg.Middleware()
if mids == nil { if mids == nil {
t.Fatal("Expected middleware, was nil instead") t.Fatal("Expected middleware, was nil instead")
@ -114,7 +113,7 @@ func TestLogParse(t *testing.T) {
}}}, }}},
} }
for i, test := range tests { for i, test := range tests {
c := caddy.NewTestController(test.inputLogRules) c := caddy.NewTestController("http", test.inputLogRules)
actualLogRules, err := logParse(c) actualLogRules, err := logParse(c)
if err == nil && test.shouldErr { if err == nil && test.shouldErr {

View file

@ -23,7 +23,7 @@ func setup(c *caddy.Controller) error {
return err return err
} }
cfg := httpserver.GetConfig(c.Key) cfg := httpserver.GetConfig(c)
md := Markdown{ md := Markdown{
Root: cfg.Root, Root: cfg.Root,
@ -82,7 +82,7 @@ func markdownParse(c *caddy.Controller) ([]*Config, error) {
} }
func loadParams(c *caddy.Controller, mdc *Config) error { func loadParams(c *caddy.Controller, mdc *Config) error {
cfg := httpserver.GetConfig(c.Key) cfg := httpserver.GetConfig(c)
switch c.Val() { switch c.Val() {
case "ext": case "ext":

View file

@ -12,11 +12,12 @@ import (
) )
func TestSetup(t *testing.T) { func TestSetup(t *testing.T) {
err := setup(caddy.NewTestController(`markdown /blog`)) c := caddy.NewTestController("http", `markdown /blog`)
err := setup(c)
if err != nil { if err != nil {
t.Errorf("Expected no errors, got: %v", err) t.Errorf("Expected no errors, got: %v", err)
} }
mids := httpserver.GetConfig("").Middleware() mids := httpserver.GetConfig(c).Middleware()
if len(mids) == 0 { if len(mids) == 0 {
t.Fatal("Expected middleware, got 0 instead") t.Fatal("Expected middleware, got 0 instead")
} }
@ -78,8 +79,8 @@ func TestMarkdownParse(t *testing.T) {
SetTemplate(tmpl, "", "./testdata/tpl_with_include.html") SetTemplate(tmpl, "", "./testdata/tpl_with_include.html")
for i, test := range tests { for i, test := range tests {
c := caddy.NewTestController(test.inputMarkdownConfig) c := caddy.NewTestController("http", test.inputMarkdownConfig)
httpserver.GetConfig("").Root = "./testdata" httpserver.GetConfig(c).Root = "./testdata"
actualMarkdownConfigs, err := markdownParse(c) actualMarkdownConfigs, err := markdownParse(c)
if err == nil && test.shouldErr { if err == nil && test.shouldErr {

View file

@ -22,7 +22,7 @@ func setup(c *caddy.Controller) error {
return err return err
} }
httpserver.GetConfig(c.Key).AddMiddleware(func(next httpserver.Handler) httpserver.Handler { httpserver.GetConfig(c).AddMiddleware(func(next httpserver.Handler) httpserver.Handler {
return Mime{Next: next, Configs: configs} return Mime{Next: next, Configs: configs}
}) })

View file

@ -8,11 +8,12 @@ import (
) )
func TestSetup(t *testing.T) { func TestSetup(t *testing.T) {
err := setup(caddy.NewTestController(`mime .txt text/plain`)) c := caddy.NewTestController("http", `mime .txt text/plain`)
err := setup(c)
if err != nil { if err != nil {
t.Errorf("Expected no errors, but got: %v", err) t.Errorf("Expected no errors, but got: %v", err)
} }
mids := httpserver.GetConfig("").Middleware() mids := httpserver.GetConfig(c).Middleware()
if len(mids) == 0 { if len(mids) == 0 {
t.Fatal("Expected middleware, but had 0 instead") t.Fatal("Expected middleware, but had 0 instead")
} }
@ -52,7 +53,7 @@ func TestSetup(t *testing.T) {
{`mime .txt text/plain`, false}, {`mime .txt text/plain`, false},
} }
for i, test := range tests { for i, test := range tests {
m, err := mimeParse(caddy.NewTestController(test.input)) m, err := mimeParse(caddy.NewTestController("http", test.input))
if test.shouldErr && err == nil { if test.shouldErr && err == nil {
t.Errorf("Test %v: Expected error but found nil %v", i, m) t.Errorf("Test %v: Expected error but found nil %v", i, m)
} else if !test.shouldErr && err != nil { } else if !test.shouldErr && err != nil {

View file

@ -29,7 +29,7 @@ func setup(c *caddy.Controller) error {
found = true found = true
} }
httpserver.GetConfig(c.Key).AddMiddleware(func(next httpserver.Handler) httpserver.Handler { httpserver.GetConfig(c).AddMiddleware(func(next httpserver.Handler) httpserver.Handler {
return &Handler{Next: next, Mux: NewMux()} return &Handler{Next: next, Mux: NewMux()}
}) })

View file

@ -21,7 +21,8 @@ func TestSetup(t *testing.T) {
pprof`, true}, pprof`, true},
} }
for i, test := range tests { for i, test := range tests {
err := setup(caddy.NewTestController(test.input)) c := caddy.NewTestController("http", test.input)
err := setup(c)
if test.shouldErr && err == nil { if test.shouldErr && err == nil {
t.Errorf("Test %v: Expected error but found nil", i) t.Errorf("Test %v: Expected error but found nil", i)
} else if !test.shouldErr && err != nil { } else if !test.shouldErr && err != nil {

View file

@ -18,7 +18,7 @@ func setup(c *caddy.Controller) error {
if err != nil { if err != nil {
return err return err
} }
httpserver.GetConfig(c.Key).AddMiddleware(func(next httpserver.Handler) httpserver.Handler { httpserver.GetConfig(c).AddMiddleware(func(next httpserver.Handler) httpserver.Handler {
return Proxy{Next: next, Upstreams: upstreams} return Proxy{Next: next, Upstreams: upstreams}
}) })
return nil return nil

View file

@ -112,14 +112,15 @@ func TestSetup(t *testing.T) {
}, },
}, },
} { } {
err := setup(caddy.NewTestController(test.input)) c := caddy.NewTestController("http", test.input)
err := setup(c)
if err != nil && !test.shouldErr { if err != nil && !test.shouldErr {
t.Errorf("Test case #%d received an error of %v", i, err) t.Errorf("Test case #%d received an error of %v", i, err)
} else if test.shouldErr { } else if test.shouldErr {
continue continue
} }
mids := httpserver.GetConfig("").Middleware() mids := httpserver.GetConfig(c).Middleware()
mid := mids[len(mids)-1] mid := mids[len(mids)-1]
upstreams := mid(nil).(Proxy).Upstreams upstreams := mid(nil).(Proxy).Upstreams

View file

@ -21,7 +21,7 @@ func setup(c *caddy.Controller) error {
return err return err
} }
httpserver.GetConfig(c.Key).AddMiddleware(func(next httpserver.Handler) httpserver.Handler { httpserver.GetConfig(c).AddMiddleware(func(next httpserver.Handler) httpserver.Handler {
return Redirect{Next: next, Rules: rules} return Redirect{Next: next, Rules: rules}
}) })
@ -31,7 +31,7 @@ func setup(c *caddy.Controller) error {
func redirParse(c *caddy.Controller) ([]Rule, error) { func redirParse(c *caddy.Controller) ([]Rule, error) {
var redirects []Rule var redirects []Rule
cfg := httpserver.GetConfig(c.Key) cfg := httpserver.GetConfig(c)
// setRedirCode sets the redirect code for rule if it can, or returns an error // setRedirCode sets the redirect code for rule if it can, or returns an error
setRedirCode := func(code string, rule *Rule) error { setRedirCode := func(code string, rule *Rule) error {

View file

@ -44,13 +44,14 @@ func TestSetup(t *testing.T) {
// test case #9 tests the detection of duplicate redirections // test case #9 tests the detection of duplicate redirections
{"redir {\n /bar /foo 304 \n} redir {\n /bar /foo 304 \n}", true, []Rule{{}}}, {"redir {\n /bar /foo 304 \n} redir {\n /bar /foo 304 \n}", true, []Rule{{}}},
} { } {
err := setup(caddy.NewTestController(test.input)) c := caddy.NewTestController("http", test.input)
err := setup(c)
if err != nil && !test.shouldErr { if err != nil && !test.shouldErr {
t.Errorf("Test case #%d recieved an error of %v", j, err) t.Errorf("Test case #%d recieved an error of %v", j, err)
} else if test.shouldErr { } else if test.shouldErr {
continue continue
} }
mids := httpserver.GetConfig("").Middleware() mids := httpserver.GetConfig(c).Middleware()
recievedRules := mids[len(mids)-1](nil).(Redirect).Rules recievedRules := mids[len(mids)-1](nil).(Redirect).Rules
for i, recievedRule := range recievedRules { for i, recievedRule := range recievedRules {

View file

@ -23,7 +23,7 @@ func setup(c *caddy.Controller) error {
return err return err
} }
cfg := httpserver.GetConfig(c.Key) cfg := httpserver.GetConfig(c)
cfg.AddMiddleware(func(next httpserver.Handler) httpserver.Handler { cfg.AddMiddleware(func(next httpserver.Handler) httpserver.Handler {
return Rewrite{ return Rewrite{

View file

@ -10,11 +10,12 @@ import (
) )
func TestSetup(t *testing.T) { func TestSetup(t *testing.T) {
err := setup(caddy.NewTestController(`rewrite /from /to`)) c := caddy.NewTestController("http", `rewrite /from /to`)
err := setup(c)
if err != nil { if err != nil {
t.Errorf("Expected no errors, but got: %v", err) t.Errorf("Expected no errors, but got: %v", err)
} }
mids := httpserver.GetConfig("").Middleware() mids := httpserver.GetConfig(c).Middleware()
if len(mids) == 0 { if len(mids) == 0 {
t.Fatal("Expected middleware, had 0 instead") t.Fatal("Expected middleware, had 0 instead")
} }
@ -56,7 +57,7 @@ func TestRewriteParse(t *testing.T) {
} }
for i, test := range simpleTests { for i, test := range simpleTests {
actual, err := rewriteParse(caddy.NewTestController(test.input)) actual, err := rewriteParse(caddy.NewTestController("http", test.input))
if err == nil && test.shouldErr { if err == nil && test.shouldErr {
t.Errorf("Test %d didn't error, but it should have", i) t.Errorf("Test %d didn't error, but it should have", i)
@ -187,7 +188,7 @@ func TestRewriteParse(t *testing.T) {
} }
for i, test := range regexpTests { for i, test := range regexpTests {
actual, err := rewriteParse(caddy.NewTestController(test.input)) actual, err := rewriteParse(caddy.NewTestController("http", test.input))
if err == nil && test.shouldErr { if err == nil && test.shouldErr {
t.Errorf("Test %d didn't error, but it should have", i) t.Errorf("Test %d didn't error, but it should have", i)

View file

@ -16,7 +16,7 @@ func init() {
} }
func setupRoot(c *caddy.Controller) error { func setupRoot(c *caddy.Controller) error {
config := httpserver.GetConfig(c.Key) config := httpserver.GetConfig(c)
for c.Next() { for c.Next() {
if !c.NextArg() { if !c.NextArg() {

View file

@ -13,8 +13,6 @@ import (
) )
func TestRoot(t *testing.T) { func TestRoot(t *testing.T) {
cfg := httpserver.GetConfig("")
// Predefined error substrings // Predefined error substrings
parseErrContent := "Parse error:" parseErrContent := "Parse error:"
unableToAccessErrContent := "Unable to access root path" unableToAccessErrContent := "Unable to access root path"
@ -65,8 +63,9 @@ func TestRoot(t *testing.T) {
} }
for i, test := range tests { for i, test := range tests {
c := caddy.NewTestController(test.input) c := caddy.NewTestController("http", test.input)
err := setupRoot(c) err := setupRoot(c)
cfg := httpserver.GetConfig(c)
if test.shouldErr && err == nil { if test.shouldErr && err == nil {
t.Errorf("Test %d: Expected error but found %s for input %s", i, err, test.input) t.Errorf("Test %d: Expected error but found %s for input %s", i, err, test.input)

View file

@ -21,7 +21,7 @@ func setup(c *caddy.Controller) error {
return err return err
} }
cfg := httpserver.GetConfig(c.Key) cfg := httpserver.GetConfig(c)
tmpls := Templates{ tmpls := Templates{
Rules: rules, Rules: rules,

View file

@ -9,11 +9,12 @@ import (
) )
func TestSetup(t *testing.T) { func TestSetup(t *testing.T) {
err := setup(caddy.NewTestController(`templates`)) c := caddy.NewTestController("http", `templates`)
err := setup(c)
if err != nil { if err != nil {
t.Errorf("Expected no errors, got: %v", err) t.Errorf("Expected no errors, got: %v", err)
} }
mids := httpserver.GetConfig("").Middleware() mids := httpserver.GetConfig(c).Middleware()
if len(mids) == 0 { if len(mids) == 0 {
t.Fatal("Expected middleware, got 0 instead") t.Fatal("Expected middleware, got 0 instead")
} }
@ -81,7 +82,7 @@ func TestTemplatesParse(t *testing.T) {
}}}, }}},
} }
for i, test := range tests { for i, test := range tests {
c := caddy.NewTestController(test.inputTemplateConfig) c := caddy.NewTestController("http", test.inputTemplateConfig)
actualTemplateConfigs, err := templatesParse(c) actualTemplateConfigs, err := templatesParse(c)
if err == nil && test.shouldErr { if err == nil && test.shouldErr {

View file

@ -22,7 +22,7 @@ func setup(c *caddy.Controller) error {
GatewayInterface = caddy.AppName + "-CGI/1.1" GatewayInterface = caddy.AppName + "-CGI/1.1"
ServerSoftware = caddy.AppName + "/" + caddy.AppVersion ServerSoftware = caddy.AppName + "/" + caddy.AppVersion
httpserver.GetConfig(c.Key).AddMiddleware(func(next httpserver.Handler) httpserver.Handler { httpserver.GetConfig(c).AddMiddleware(func(next httpserver.Handler) httpserver.Handler {
return WebSocket{Next: next, Sockets: websocks} return WebSocket{Next: next, Sockets: websocks}
}) })

View file

@ -8,11 +8,12 @@ import (
) )
func TestWebSocket(t *testing.T) { func TestWebSocket(t *testing.T) {
err := setup(caddy.NewTestController(`websocket cat`)) c := caddy.NewTestController("http", `websocket cat`)
err := setup(c)
if err != nil { if err != nil {
t.Errorf("Expected no errors, got: %v", err) t.Errorf("Expected no errors, got: %v", err)
} }
mids := httpserver.GetConfig("").Middleware() mids := httpserver.GetConfig(c).Middleware()
if len(mids) == 0 { if len(mids) == 0 {
t.Fatal("Expected middleware, got 0 instead") t.Fatal("Expected middleware, got 0 instead")
} }
@ -72,7 +73,7 @@ func TestWebSocketParse(t *testing.T) {
}`, true, []Config{}}, }`, true, []Config{}},
} }
for i, test := range tests { for i, test := range tests {
c := caddy.NewTestController(test.inputWebSocketConfig) c := caddy.NewTestController("http", test.inputWebSocketConfig)
actualWebSocketConfigs, err := webSocketParse(c) actualWebSocketConfigs, err := webSocketParse(c)
if err == nil && test.shouldErr { if err == nil && test.shouldErr {

View file

@ -9,6 +9,7 @@ import (
"io/ioutil" "io/ioutil"
"time" "time"
"github.com/mholt/caddy"
"github.com/xenolf/lego/acme" "github.com/xenolf/lego/acme"
) )
@ -306,7 +307,7 @@ func MakeTLSConfig(configs []*Config) (*tls.Config, error) {
} }
// ConfigGetter gets a Config keyed by key. // ConfigGetter gets a Config keyed by key.
type ConfigGetter func(key string) *Config type ConfigGetter func(c *caddy.Controller) *Config
var configGetters = make(map[string]ConfigGetter) var configGetters = make(map[string]ConfigGetter)

View file

@ -27,7 +27,7 @@ func setupTLS(c *caddy.Controller) error {
if !ok { if !ok {
return fmt.Errorf("no caddytls.ConfigGetter for %s server type; must call RegisterConfigGetter", c.ServerType()) return fmt.Errorf("no caddytls.ConfigGetter for %s server type; must call RegisterConfigGetter", c.ServerType())
} }
config := configGetter(c.Key) config := configGetter(c)
if config == nil { if config == nil {
return fmt.Errorf("no caddytls.Config to set up for %s", c.Key) return fmt.Errorf("no caddytls.Config to set up for %s", c.Key)
} }

View file

@ -33,8 +33,8 @@ func TestMain(m *testing.M) {
func TestSetupParseBasic(t *testing.T) { func TestSetupParseBasic(t *testing.T) {
cfg := new(Config) cfg := new(Config)
RegisterConfigGetter("", func(key string) *Config { return cfg }) RegisterConfigGetter("", func(c *caddy.Controller) *Config { return cfg })
c := caddy.NewTestController(`tls ` + certFile + ` ` + keyFile + ``) c := caddy.NewTestController("http", `tls `+certFile+` `+keyFile+``)
err := setupTLS(c) err := setupTLS(c)
if err != nil { if err != nil {
@ -92,7 +92,7 @@ func TestSetupParseBasic(t *testing.T) {
func TestSetupParseIncompleteParams(t *testing.T) { func TestSetupParseIncompleteParams(t *testing.T) {
// Using tls without args is an error because it's unnecessary. // Using tls without args is an error because it's unnecessary.
c := caddy.NewTestController(`tls`) c := caddy.NewTestController("http", `tls`)
err := setupTLS(c) err := setupTLS(c)
if err == nil { if err == nil {
t.Error("Expected an error, but didn't get one") t.Error("Expected an error, but didn't get one")
@ -105,8 +105,8 @@ func TestSetupParseWithOptionalParams(t *testing.T) {
ciphers RSA-AES256-CBC-SHA ECDHE-RSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES256-GCM-SHA384 ciphers RSA-AES256-CBC-SHA ECDHE-RSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES256-GCM-SHA384
}` }`
cfg := new(Config) cfg := new(Config)
RegisterConfigGetter("", func(key string) *Config { return cfg }) RegisterConfigGetter("", func(c *caddy.Controller) *Config { return cfg })
c := caddy.NewTestController(params) c := caddy.NewTestController("http", params)
err := setupTLS(c) err := setupTLS(c)
if err != nil { if err != nil {
@ -131,8 +131,8 @@ func TestSetupDefaultWithOptionalParams(t *testing.T) {
ciphers RSA-3DES-EDE-CBC-SHA ciphers RSA-3DES-EDE-CBC-SHA
}` }`
cfg := new(Config) cfg := new(Config)
RegisterConfigGetter("", func(key string) *Config { return cfg }) RegisterConfigGetter("", func(c *caddy.Controller) *Config { return cfg })
c := caddy.NewTestController(params) c := caddy.NewTestController("http", params)
err := setupTLS(c) err := setupTLS(c)
if err != nil { if err != nil {
@ -149,8 +149,8 @@ func TestSetupParseWithWrongOptionalParams(t *testing.T) {
protocols ssl tls protocols ssl tls
}` }`
cfg := new(Config) cfg := new(Config)
RegisterConfigGetter("", func(key string) *Config { return cfg }) RegisterConfigGetter("", func(c *caddy.Controller) *Config { return cfg })
c := caddy.NewTestController(params) c := caddy.NewTestController("http", params)
err := setupTLS(c) err := setupTLS(c)
if err == nil { if err == nil {
t.Errorf("Expected errors, but no error returned") t.Errorf("Expected errors, but no error returned")
@ -161,8 +161,8 @@ func TestSetupParseWithWrongOptionalParams(t *testing.T) {
ciphers not-valid-cipher ciphers not-valid-cipher
}` }`
cfg = new(Config) cfg = new(Config)
RegisterConfigGetter("", func(key string) *Config { return cfg }) RegisterConfigGetter("", func(c *caddy.Controller) *Config { return cfg })
c = caddy.NewTestController(params) c = caddy.NewTestController("http", params)
err = setupTLS(c) err = setupTLS(c)
if err == nil { if err == nil {
t.Errorf("Expected errors, but no error returned") t.Errorf("Expected errors, but no error returned")
@ -173,8 +173,8 @@ func TestSetupParseWithWrongOptionalParams(t *testing.T) {
key_type ab123 key_type ab123
}` }`
cfg = new(Config) cfg = new(Config)
RegisterConfigGetter("", func(key string) *Config { return cfg }) RegisterConfigGetter("", func(c *caddy.Controller) *Config { return cfg })
c = caddy.NewTestController(params) c = caddy.NewTestController("http", params)
err = setupTLS(c) err = setupTLS(c)
if err == nil { if err == nil {
t.Errorf("Expected errors, but no error returned") t.Errorf("Expected errors, but no error returned")
@ -187,8 +187,8 @@ func TestSetupParseWithClientAuth(t *testing.T) {
clients clients
}` }`
cfg := new(Config) cfg := new(Config)
RegisterConfigGetter("", func(key string) *Config { return cfg }) RegisterConfigGetter("", func(c *caddy.Controller) *Config { return cfg })
c := caddy.NewTestController(params) c := caddy.NewTestController("http", params)
err := setupTLS(c) err := setupTLS(c)
if err == nil { if err == nil {
t.Errorf("Expected an error, but no error returned") t.Errorf("Expected an error, but no error returned")
@ -220,8 +220,8 @@ func TestSetupParseWithClientAuth(t *testing.T) {
}`, tls.VerifyClientCertIfGiven, true, noCAs}, }`, tls.VerifyClientCertIfGiven, true, noCAs},
} { } {
cfg := new(Config) cfg := new(Config)
RegisterConfigGetter("", func(key string) *Config { return cfg }) RegisterConfigGetter("", func(c *caddy.Controller) *Config { return cfg })
c := caddy.NewTestController(caseData.params) c := caddy.NewTestController("http", caseData.params)
err := setupTLS(c) err := setupTLS(c)
if caseData.expectedErr { if caseData.expectedErr {
if err == nil { if err == nil {
@ -256,8 +256,8 @@ func TestSetupParseWithKeyType(t *testing.T) {
key_type p384 key_type p384
}` }`
cfg := new(Config) cfg := new(Config)
RegisterConfigGetter("", func(key string) *Config { return cfg }) RegisterConfigGetter("", func(c *caddy.Controller) *Config { return cfg })
c := caddy.NewTestController(params) c := caddy.NewTestController("http", params)
err := setupTLS(c) err := setupTLS(c)
if err != nil { if err != nil {

View file

@ -70,16 +70,22 @@ func (c *Controller) OnShutdown(fn func() error) {
c.instance.onShutdown = append(c.instance.onShutdown, fn) c.instance.onShutdown = append(c.instance.onShutdown, fn)
} }
// NewTestController creates a new *Controller for // Context gets the context associated with the instance associated with c.
func (c *Controller) Context() Context {
return c.instance.context
}
// NewTestController creates a new Controller for
// the input specified, with a filename of "Testfile". // the input specified, with a filename of "Testfile".
// The Config is bare, consisting only of a Root of cwd. // The Config is bare, consisting only of a Root of cwd.
// //
// Used primarily for testing but needs to be exported so // Used primarily for testing but needs to be exported so
// add-ons can use this as a convenience. Does not initialize // add-ons can use this as a convenience. Does not initialize
// the server-block-related fields. // the server-block-related fields.
func NewTestController(input string) *Controller { func NewTestController(serverType, input string) *Controller {
stype, _ := getServerType(serverType)
return &Controller{ return &Controller{
instance: &Instance{serverType: ""}, instance: &Instance{serverType: serverType, context: stype.NewContext()},
Dispenser: caddyfile.NewDispenser("Testfile", strings.NewReader(input)), Dispenser: caddyfile.NewDispenser("Testfile", strings.NewReader(input)),
OncePerServerBlock: func(f func() error) error { return f() }, OncePerServerBlock: func(f func() error) error { return f() },
} }

View file

@ -25,7 +25,7 @@ var (
// to list of callback functions. These aren't really // to list of callback functions. These aren't really
// plugins on their own, but are often registered from // plugins on their own, but are often registered from
// plugins. // plugins.
parsingCallbacks = make(map[string]map[string][]func() error) parsingCallbacks = make(map[string]map[string][]ParsingCallback)
// caddyfileLoaders is the list of all Caddyfile loaders // caddyfileLoaders is the list of all Caddyfile loaders
// in registration order. // in registration order.
@ -180,11 +180,16 @@ func RegisterPlugin(name string, plugin Plugin) {
plugins[plugin.ServerType][name] = plugin plugins[plugin.ServerType][name] = plugin
} }
// ParsingCallback is a function that is called after
// a directive's setup functions have been executed
// for all the server blocks.
type ParsingCallback func(Context) error
// RegisterParsingCallback registers callback to be called after // RegisterParsingCallback registers callback to be called after
// executing the directive afterDir for server type serverType. // executing the directive afterDir for server type serverType.
func RegisterParsingCallback(serverType, afterDir string, callback func() error) { func RegisterParsingCallback(serverType, afterDir string, callback ParsingCallback) {
if _, ok := parsingCallbacks[serverType]; !ok { if _, ok := parsingCallbacks[serverType]; !ok {
parsingCallbacks[serverType] = make(map[string][]func() error) parsingCallbacks[serverType] = make(map[string][]ParsingCallback)
} }
parsingCallbacks[serverType][afterDir] = append(parsingCallbacks[serverType][afterDir], callback) parsingCallbacks[serverType][afterDir] = append(parsingCallbacks[serverType][afterDir], callback)
} }

View file

@ -46,7 +46,7 @@ func TestStartup(t *testing.T) {
} }
for i, test := range tests { for i, test := range tests {
c := caddy.NewTestController(test.input) c := caddy.NewTestController("http", test.input)
err := registerCallback(c, fakeRegister) err := registerCallback(c, fakeRegister)
if err != nil { if err != nil {
t.Errorf("Expected no errors, got: %v", err) t.Errorf("Expected no errors, got: %v", err)