* Add middleware/cache Add a caching middleware that caches nxdomain, nodata and successful responses. It differentiates between DNSSEC on normal DNS replies. Each reply is compress and scrubbed so it will fit the specific client asking for it. * first simple test, less exporting of stuff * more * Add middleware/cache Add a caching middleware that caches nxdomain, nodata and successful responses. It differentiates between DNSSEC on normal DNS replies. Each reply is compressed and scrubbed so it will fit the specific client asking for it. The TTL is decremented with the time spend in the cache. There is syntax that allows you to cap the TTL for all records, no matter what. This allows for a shortlived cache, just to absorb query peaks. +Tests * cache test infrastructure * Testing
94 lines
3.2 KiB
Go
94 lines
3.2 KiB
Go
package core
|
|
|
|
import (
|
|
"github.com/miekg/coredns/core/https"
|
|
"github.com/miekg/coredns/core/parse"
|
|
"github.com/miekg/coredns/core/setup"
|
|
"github.com/miekg/coredns/middleware"
|
|
)
|
|
|
|
func init() {
|
|
// The parse package must know which directives
|
|
// are valid, but it must not import the setup
|
|
// or config package. To solve this problem, we
|
|
// fill up this map in our init function here.
|
|
// The parse package does not need to know the
|
|
// ordering of the directives.
|
|
for _, dir := range directiveOrder {
|
|
parse.ValidDirectives[dir.name] = struct{}{}
|
|
}
|
|
}
|
|
|
|
// Directives are registered in the order they should be
|
|
// executed. Middleware (directives that inject a handler)
|
|
// are executed in the order A-B-C-*-C-B-A, assuming
|
|
// they all call the Next handler in the chain.
|
|
//
|
|
// Ordering is VERY important. Every middleware will
|
|
// feel the effects of all other middleware below
|
|
// (after) them during a request, but they must not
|
|
// care what middleware above them are doing.
|
|
//
|
|
// For example, log needs to know the status code and
|
|
// exactly how many bytes were written to the client,
|
|
// which every other middleware can affect, so it gets
|
|
// registered first. The errors middleware does not
|
|
// care if gzip or log modifies its response, so it
|
|
// gets registered below them. Gzip, on the other hand,
|
|
// DOES care what errors does to the response since it
|
|
// must compress every output to the client, even error
|
|
// pages, so it must be registered before the errors
|
|
// middleware and any others that would write to the
|
|
// response.
|
|
var directiveOrder = []directive{
|
|
// Essential directives that initialize vital configuration settings
|
|
{"root", setup.Root},
|
|
{"bind", setup.BindHost},
|
|
{"tls", https.Setup},
|
|
{"health", setup.Health},
|
|
|
|
// Other directives that don't create HTTP handlers
|
|
{"startup", setup.Startup},
|
|
{"shutdown", setup.Shutdown},
|
|
|
|
// Directives that inject handlers (middleware)
|
|
{"prometheus", setup.Prometheus},
|
|
{"log", setup.Log},
|
|
{"chaos", setup.Chaos},
|
|
{"rewrite", setup.Rewrite},
|
|
{"loadbalance", setup.Loadbalance},
|
|
{"cache", setup.Cache},
|
|
{"file", setup.File},
|
|
{"secondary", setup.Secondary},
|
|
{"etcd", setup.Etcd},
|
|
{"proxy", setup.Proxy},
|
|
{"errors", setup.Errors},
|
|
}
|
|
|
|
// RegisterDirective adds the given directive to caddy's list of directives.
|
|
// Pass the name of a directive you want it to be placed after,
|
|
// otherwise it will be placed at the bottom of the stack.
|
|
func RegisterDirective(name string, setup SetupFunc, after string) {
|
|
dir := directive{name: name, setup: setup}
|
|
idx := len(directiveOrder)
|
|
for i := range directiveOrder {
|
|
if directiveOrder[i].name == after {
|
|
idx = i + 1
|
|
break
|
|
}
|
|
}
|
|
newDirectives := append(directiveOrder[:idx], append([]directive{dir}, directiveOrder[idx:]...)...)
|
|
directiveOrder = newDirectives
|
|
parse.ValidDirectives[name] = struct{}{}
|
|
}
|
|
|
|
// directive ties together a directive name with its setup function.
|
|
type directive struct {
|
|
name string
|
|
setup SetupFunc
|
|
}
|
|
|
|
// SetupFunc takes a controller and may optionally return a middleware.
|
|
// If the resulting middleware is not nil, it will be chained into
|
|
// the HTTP handlers in the order specified in this package.
|
|
type SetupFunc func(c *setup.Controller) (middleware.Middleware, error)
|