mirror of
https://github.com/caddyserver/caddy.git
synced 2025-01-23 09:06:29 +01:00
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:
parent
07b7c99965
commit
a798e0c951
49 changed files with 199 additions and 167 deletions
16
caddy.go
16
caddy.go
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 (
|
||||||
)
|
)
|
||||||
|
|
||||||
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 {
|
||||||
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 {
|
||||||
|
|
|
@ -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 {
|
||||||
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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 (
|
||||||
)
|
)
|
||||||
|
|
||||||
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() {
|
||||||
|
|
||||||
// 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,
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 (
|
||||||
)
|
)
|
||||||
|
|
||||||
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)
|
||||||
|
|
|
@ -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 (
|
||||||
)
|
)
|
||||||
|
|
||||||
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 {
|
||||||
|
|
|
@ -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 (
|
||||||
)
|
)
|
||||||
|
|
||||||
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)
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 (
|
||||||
)
|
)
|
||||||
|
|
||||||
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)
|
||||||
|
|
|
@ -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 (
|
||||||
)
|
)
|
||||||
|
|
||||||
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 {
|
||||||
|
|
|
@ -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":
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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 (
|
||||||
)
|
)
|
||||||
|
|
||||||
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 {
|
||||||
|
|
|
@ -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) {
|
||||||
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 {
|
||||||
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) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
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 {
|
||||||
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 {
|
||||||
|
|
|
@ -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 {
|
||||||
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 (
|
||||||
)
|
)
|
||||||
|
|
||||||
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)
|
||||||
|
|
|
@ -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 (
|
||||||
)
|
)
|
||||||
|
|
||||||
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)
|
||||||
|
|
|
@ -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 (
|
||||||
)
|
)
|
||||||
|
|
||||||
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 {
|
||||||
|
|
|
@ -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 (
|
||||||
)
|
)
|
||||||
|
|
||||||
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 {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
||||||
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 {
|
||||||
|
|
|
@ -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() },
|
||||||
}
|
}
|
||||||
|
|
11
plugins.go
11
plugins.go
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue