Commit a798e0c9 authored by Matthew Holt's avatar Matthew Holt

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.
parent 07b7c999
...@@ -67,7 +67,10 @@ type Instance struct { ...@@ -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 ...@@ -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 ...@@ -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, ...@@ -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
} }
} }
......
...@@ -16,7 +16,7 @@ func init() { ...@@ -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 { ...@@ -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() {
......
...@@ -12,11 +12,12 @@ import ( ...@@ -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` ...@@ -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)
......
...@@ -13,7 +13,7 @@ func init() { ...@@ -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()
......
...@@ -8,12 +8,13 @@ import ( ...@@ -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)
} }
......
...@@ -29,7 +29,7 @@ func setup(c *caddy.Controller) error { ...@@ -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 { ...@@ -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 {
......
...@@ -49,14 +49,15 @@ func TestSetup(t *testing.T) { ...@@ -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 {
......
...@@ -62,7 +62,7 @@ func setup(c *caddy.Controller) error { ...@@ -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) { ...@@ -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
......
...@@ -8,11 +8,12 @@ import ( ...@@ -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) { ...@@ -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)
......
...@@ -28,7 +28,7 @@ func setup(c *caddy.Controller) error { ...@@ -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
}) })
......
...@@ -8,25 +8,27 @@ import ( ...@@ -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)
......
...@@ -14,7 +14,7 @@ func init() { ...@@ -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 { ...@@ -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,
......
...@@ -8,12 +8,13 @@ import ( ...@@ -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) { ...@@ -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)
......
...@@ -18,7 +18,7 @@ func init() { ...@@ -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
......
...@@ -9,11 +9,12 @@ import ( ...@@ -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) { ...@@ -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)
......
...@@ -16,7 +16,7 @@ func setup(c *caddy.Controller) error { ...@@ -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}
}) })
......
...@@ -8,11 +8,12 @@ import ( ...@@ -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) { ...@@ -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 {
......
...@@ -19,7 +19,7 @@ func setup(c *caddy.Controller) error { ...@@ -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}
}) })
......
...@@ -9,12 +9,13 @@ import ( ...@@ -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) { ...@@ -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)
......
...@@ -4,37 +4,37 @@ import ( ...@@ -4,37 +4,37 @@ 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
markQualifiedForAutoHTTPS(ctx.siteConfigs)
// place certificates and keys on disk // pre-screen each config and earmark the ones that qualify for managed TLS
for _, c := range ctx.siteConfigs { markQualifiedForAutoHTTPS(ctx.siteConfigs)
err := c.TLS.ObtainCert(true)
if err != nil {
return err
}
}
// update TLS configurations // place certificates and keys on disk
err := enableAutoHTTPS(ctx.siteConfigs, true) for _, c := range ctx.siteConfigs {
err := c.TLS.ObtainCert(true)
if err != nil { if err != nil {
return err return err
} }
}
// set up redirects // update TLS configurations
ctx.siteConfigs = makePlaintextRedirects(ctx.siteConfigs) err := enableAutoHTTPS(ctx.siteConfigs, true)
if err != nil {
return err
} }
// set up redirects
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
} }
......
...@@ -44,16 +44,11 @@ func init() { ...@@ -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 { ...@@ -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 ...@@ -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) { ...@@ -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) { ...@@ -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 { return cfg
for _, context := range contexts {
if cfg, ok := context.keysToSiteConfigs[addrKey]; ok {
return cfg
}
}
if len(contexts) == 0 {
// this shouldn't happen except in tests
newContext()
} }
cfg := &SiteConfig{Root: Root, TLS: new(caddytls.Config)} // we should only get here during tests because directive
defaultCtx := contexts[len(contexts)-1] // actions typically skip the server blocks where we make
defaultCtx.siteConfigs = append(defaultCtx.siteConfigs, cfg) // the configs
defaultCtx.keysToSiteConfigs[addrKey] = cfg ctx.saveConfig(c.Key, &SiteConfig{Root: Root, TLS: new(caddytls.Config)})
return cfg return GetConfig(c)
} }
// shortCaddyfileLoader loads a Caddyfile if positional arguments are // shortCaddyfileLoader loads a Caddyfile if positional arguments are
......
...@@ -19,7 +19,7 @@ func setup(c *caddy.Controller) error { ...@@ -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}
}) })
......
...@@ -8,11 +8,12 @@ import ( ...@@ -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) { ...@@ -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)
......
...@@ -53,7 +53,7 @@ func setup(c *caddy.Controller) error { ...@@ -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}
}) })
......
...@@ -8,13 +8,12 @@ import ( ...@@ -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) { ...@@ -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 {
......
...@@ -23,7 +23,7 @@ func setup(c *caddy.Controller) error { ...@@ -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) { ...@@ -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":
......
...@@ -12,11 +12,12 @@ import ( ...@@ -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) { ...@@ -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 {
......
...@@ -22,7 +22,7 @@ func setup(c *caddy.Controller) error { ...@@ -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}
}) })
......
...@@ -8,11 +8,12 @@ import ( ...@@ -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) { ...@@ -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 {
......
...@@ -29,7 +29,7 @@ func setup(c *caddy.Controller) error { ...@@ -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()}
}) })
......
...@@ -21,7 +21,8 @@ func TestSetup(t *testing.T) { ...@@ -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 {
......
...@@ -18,7 +18,7 @@ func setup(c *caddy.Controller) error { ...@@ -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
......
...@@ -112,14 +112,15 @@ func TestSetup(t *testing.T) { ...@@ -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
......
...@@ -21,7 +21,7 @@ func setup(c *caddy.Controller) error { ...@@ -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 { ...@@ -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 {
......
...@@ -44,13 +44,14 @@ func TestSetup(t *testing.T) { ...@@ -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 {
......
...@@ -23,7 +23,7 @@ func setup(c *caddy.Controller) error { ...@@ -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{
......
...@@ -10,11 +10,12 @@ import ( ...@@ -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) { ...@@ -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) { ...@@ -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)
......
...@@ -16,7 +16,7 @@ func init() { ...@@ -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() {
......
...@@ -13,8 +13,6 @@ import ( ...@@ -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) { ...@@ -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)
......
...@@ -21,7 +21,7 @@ func setup(c *caddy.Controller) error { ...@@ -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,
......
...@@ -9,11 +9,12 @@ import ( ...@@ -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) { ...@@ -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 {
......
...@@ -22,7 +22,7 @@ func setup(c *caddy.Controller) error { ...@@ -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}
}) })
......
...@@ -8,11 +8,12 @@ import ( ...@@ -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) { ...@@ -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 {
......
...@@ -9,6 +9,7 @@ import ( ...@@ -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) { ...@@ -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)
......
...@@ -27,7 +27,7 @@ func setupTLS(c *caddy.Controller) error { ...@@ -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)
} }
......
...@@ -33,8 +33,8 @@ func TestMain(m *testing.M) { ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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 {
......
...@@ -70,16 +70,22 @@ func (c *Controller) OnShutdown(fn func() error) { ...@@ -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() },
} }
......
...@@ -25,7 +25,7 @@ var ( ...@@ -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) { ...@@ -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)
} }
......
...@@ -46,7 +46,7 @@ func TestStartup(t *testing.T) { ...@@ -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)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment