diff options
Diffstat (limited to 'modules')
31 files changed, 532 insertions, 310 deletions
diff --git a/modules/caddyhttp/caddyhttp.go b/modules/caddyhttp/caddyhttp.go index 21c5b6d..b4b1ec6 100644 --- a/modules/caddyhttp/caddyhttp.go +++ b/modules/caddyhttp/caddyhttp.go @@ -37,10 +37,7 @@ import ( func init() { weakrand.Seed(time.Now().UnixNano()) - err := caddy.RegisterModule(caddy.Module{ - Name: "http", - New: func() interface{} { return new(App) }, - }) + err := caddy.RegisterModule(App{}) if err != nil { log.Fatal(err) } @@ -58,6 +55,14 @@ type App struct { ctx caddy.Context } +// CaddyModule returns the Caddy module information. +func (App) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + Name: "http", + New: func() caddy.Module { return new(App) }, + } +} + // Provision sets up the app. func (app *App) Provision(ctx caddy.Context) error { app.ctx = ctx @@ -227,7 +232,7 @@ func (app *App) automaticHTTPS() error { // find all qualifying domain names, de-duplicated domainSet := make(map[string]struct{}) for _, route := range srv.Routes { - for _, matcherSet := range route.matcherSets { + for _, matcherSet := range route.MatcherSets { for _, m := range matcherSet { if hm, ok := m.(*MatchHost); ok { for _, d := range *hm { @@ -331,13 +336,13 @@ func (app *App) automaticHTTPS() error { redirTo += "{http.request.uri}" redirRoutes = append(redirRoutes, Route{ - matcherSets: []MatcherSet{ + MatcherSets: []MatcherSet{ { MatchProtocol("http"), MatchHost(domains), }, }, - handlers: []MiddlewareHandler{ + Handlers: []MiddlewareHandler{ StaticResponse{ StatusCode: WeakString(strconv.Itoa(http.StatusTemporaryRedirect)), // TODO: use permanent redirect instead Headers: http.Header{ diff --git a/modules/caddyhttp/caddylog/log.go b/modules/caddyhttp/caddylog/log.go index 902f60f..3f636d1 100644 --- a/modules/caddyhttp/caddylog/log.go +++ b/modules/caddyhttp/caddylog/log.go @@ -24,10 +24,7 @@ import ( ) func init() { - caddy.RegisterModule(caddy.Module{ - Name: "http.handlers.log", - New: func() interface{} { return new(Log) }, - }) + caddy.RegisterModule(Log{}) } // Log implements a simple logging middleware. @@ -36,6 +33,14 @@ type Log struct { counter int } +// CaddyModule returns the Caddy module information. +func (Log) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + Name: "http.handlers.log", + New: func() caddy.Module { return new(Log) }, + } +} + func (l *Log) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error { start := time.Now() diff --git a/modules/caddyhttp/encode/brotli/brotli.go b/modules/caddyhttp/encode/brotli/brotli.go index 0a9f871..cf055aa 100644 --- a/modules/caddyhttp/encode/brotli/brotli.go +++ b/modules/caddyhttp/encode/brotli/brotli.go @@ -19,16 +19,13 @@ import ( "strconv" "github.com/andybalholm/brotli" - "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" "github.com/caddyserver/caddy/v2" + "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" "github.com/caddyserver/caddy/v2/modules/caddyhttp/encode" ) func init() { - caddy.RegisterModule(caddy.Module{ - Name: "http.encoders.brotli", - New: func() interface{} { return new(Brotli) }, - }) + caddy.RegisterModule(Brotli{}) } // Brotli can create brotli encoders. Note that brotli @@ -37,6 +34,14 @@ type Brotli struct { Quality *int `json:"quality,omitempty"` } +// CaddyModule returns the Caddy module information. +func (Brotli) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + Name: "http.encoders.brotli", + New: func() caddy.Module { return new(Brotli) }, + } +} + // UnmarshalCaddyfile sets up the handler from Caddyfile tokens. func (b *Brotli) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { for d.Next() { diff --git a/modules/caddyhttp/encode/caddyfile.go b/modules/caddyhttp/encode/caddyfile.go index 5aca6ac..5762bd3 100644 --- a/modules/caddyhttp/encode/caddyfile.go +++ b/modules/caddyhttp/encode/caddyfile.go @@ -22,8 +22,25 @@ import ( "github.com/caddyserver/caddy/v2/caddyconfig" "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" "github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile" + "github.com/caddyserver/caddy/v2/modules/caddyhttp" ) +func init() { + httpcaddyfile.RegisterHandlerDirective("encode", parseCaddyfile) +} + +// TODO: This is a good example of why UnmarshalCaddyfile is still a good idea... hmm. +func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error) { + enc := new(Encode) + err := enc.UnmarshalCaddyfile(h.Dispenser) + if err != nil { + return nil, err + } + return enc, nil +} + +// TODO: Keep UnmarshalCaddyfile pattern? + // UnmarshalCaddyfile sets up the handler from Caddyfile tokens. Syntax: // // encode [<matcher>] <formats...> { @@ -78,8 +95,5 @@ func (enc *Encode) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { return nil } -// Bucket returns the HTTP Caddyfile handler bucket number. -func (enc Encode) Bucket() int { return 3 } - // Interface guard -var _ httpcaddyfile.HandlerDirective = (*Encode)(nil) +var _ caddyfile.Unmarshaler = (*Encode)(nil) diff --git a/modules/caddyhttp/encode/encode.go b/modules/caddyhttp/encode/encode.go index 4e5f743..723b988 100644 --- a/modules/caddyhttp/encode/encode.go +++ b/modules/caddyhttp/encode/encode.go @@ -35,10 +35,7 @@ import ( ) func init() { - caddy.RegisterModule(caddy.Module{ - Name: "http.handlers.encode", - New: func() interface{} { return new(Encode) }, - }) + caddy.RegisterModule(Encode{}) } // Encode is a middleware which can encode responses. @@ -50,6 +47,14 @@ type Encode struct { writerPools map[string]*sync.Pool // TODO: these pools do not get reused through config reloads... } +// CaddyModule returns the Caddy module information. +func (Encode) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + Name: "http.handlers.encode", + New: func() caddy.Module { return new(Encode) }, + } +} + // Provision provisions enc. func (enc *Encode) Provision(ctx caddy.Context) error { for modName, rawMsg := range enc.EncodingsRaw { diff --git a/modules/caddyhttp/encode/gzip/gzip.go b/modules/caddyhttp/encode/gzip/gzip.go index 87e8816..d6d67f7 100644 --- a/modules/caddyhttp/encode/gzip/gzip.go +++ b/modules/caddyhttp/encode/gzip/gzip.go @@ -20,16 +20,13 @@ import ( "fmt" "strconv" - "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" "github.com/caddyserver/caddy/v2" + "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" "github.com/caddyserver/caddy/v2/modules/caddyhttp/encode" ) func init() { - caddy.RegisterModule(caddy.Module{ - Name: "http.encoders.gzip", - New: func() interface{} { return new(Gzip) }, - }) + caddy.RegisterModule(Gzip{}) } // Gzip can create gzip encoders. @@ -37,6 +34,14 @@ type Gzip struct { Level int `json:"level,omitempty"` } +// CaddyModule returns the Caddy module information. +func (Gzip) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + Name: "http.encoders.gzip", + New: func() caddy.Module { return new(Gzip) }, + } +} + // UnmarshalCaddyfile sets up the handler from Caddyfile tokens. func (g *Gzip) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { for d.Next() { diff --git a/modules/caddyhttp/encode/zstd/zstd.go b/modules/caddyhttp/encode/zstd/zstd.go index 3622628..f2b4e85 100644 --- a/modules/caddyhttp/encode/zstd/zstd.go +++ b/modules/caddyhttp/encode/zstd/zstd.go @@ -15,22 +15,27 @@ package caddyzstd import ( - "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" "github.com/caddyserver/caddy/v2" + "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" "github.com/caddyserver/caddy/v2/modules/caddyhttp/encode" "github.com/klauspost/compress/zstd" ) func init() { - caddy.RegisterModule(caddy.Module{ - Name: "http.encoders.zstd", - New: func() interface{} { return new(Zstd) }, - }) + caddy.RegisterModule(Zstd{}) } // Zstd can create Zstandard encoders. type Zstd struct{} +// CaddyModule returns the Caddy module information. +func (Zstd) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + Name: "http.encoders.zstd", + New: func() caddy.Module { return new(Zstd) }, + } +} + // UnmarshalCaddyfile sets up the handler from Caddyfile tokens. func (z *Zstd) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { return nil diff --git a/modules/caddyhttp/fileserver/caddyfile.go b/modules/caddyhttp/fileserver/caddyfile.go index 7d9ddd9..6fa94e7 100644 --- a/modules/caddyhttp/fileserver/caddyfile.go +++ b/modules/caddyhttp/fileserver/caddyfile.go @@ -15,59 +15,58 @@ package fileserver import ( - "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" + "encoding/json" + + "github.com/caddyserver/caddy/modules/caddyhttp/rewrite" "github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile" + "github.com/caddyserver/caddy/v2/modules/caddyhttp" ) -// UnmarshalCaddyfile sets up the handler from Caddyfile tokens. Syntax: -// -// file_server [<matcher>] [browse] { -// hide <files...> -// index <files...> -// browse [<template_file>] -// root <path> -// } -// -// If browse is given on the first line, it can't be used in the block also. -// The default root is the one given by the root directive. -func (fsrv *FileServer) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { - for d.Next() { - args := d.RemainingArgs() +func init() { + httpcaddyfile.RegisterHandlerDirective("file_server", parseCaddyfile) + httpcaddyfile.RegisterDirective("try_files", parseTryFiles) +} + +func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error) { + var fsrv FileServer + + for h.Next() { + args := h.RemainingArgs() switch len(args) { case 0: case 1: if args[0] != "browse" { - return d.ArgErr() + return nil, h.ArgErr() } fsrv.Browse = new(Browse) default: - return d.ArgErr() + return nil, h.ArgErr() } - for d.NextBlock() { - switch d.Val() { + for h.NextBlock() { + switch h.Val() { case "hide": - fsrv.Hide = d.RemainingArgs() + fsrv.Hide = h.RemainingArgs() if len(fsrv.Hide) == 0 { - return d.ArgErr() + return nil, h.ArgErr() } case "index": - fsrv.IndexNames = d.RemainingArgs() + fsrv.IndexNames = h.RemainingArgs() if len(fsrv.Hide) == 0 { - return d.ArgErr() + return nil, h.ArgErr() } case "root": - if !d.Args(&fsrv.Root) { - return d.ArgErr() + if !h.Args(&fsrv.Root) { + return nil, h.ArgErr() } case "browse": if fsrv.Browse != nil { - return d.Err("browsing is already configured") + return nil, h.Err("browsing is already configured") } fsrv.Browse = new(Browse) - d.Args(&fsrv.Browse.TemplateFile) + h.Args(&fsrv.Browse.TemplateFile) default: - return d.Errf("unknown subdirective '%s'", d.Val()) + return nil, h.Errf("unknown subdirective '%s'", h.Val()) } } } @@ -77,11 +76,29 @@ func (fsrv *FileServer) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { fsrv.Root = "{http.var.root}" } - return nil + return &fsrv, nil } -// Bucket returns the HTTP Caddyfile handler bucket number. -func (fsrv FileServer) Bucket() int { return 7 } +func parseTryFiles(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error) { + if !h.Next() { + return nil, h.ArgErr() + } + + try := h.RemainingArgs() + if len(try) == 0 { + return nil, h.ArgErr() + } + + handler := rewrite.Rewrite{ + URI: "{http.matchers.file.relative}{http.request.uri.query}", + } -// Interface guard -var _ httpcaddyfile.HandlerDirective = (*FileServer)(nil) + matcherSet := map[string]json.RawMessage{ + "file": h.JSON(MatchFile{ + Root: "{http.var.root}", + TryFiles: try, + }, nil), + } + + return h.NewRoute(matcherSet, handler), nil +} diff --git a/modules/caddyhttp/fileserver/matcher.go b/modules/caddyhttp/fileserver/matcher.go index eca0e8f..b091250 100644 --- a/modules/caddyhttp/fileserver/matcher.go +++ b/modules/caddyhttp/fileserver/matcher.go @@ -20,16 +20,13 @@ import ( "os" "time" - "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" "github.com/caddyserver/caddy/v2" + "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" "github.com/caddyserver/caddy/v2/modules/caddyhttp" ) func init() { - caddy.RegisterModule(caddy.Module{ - Name: "http.matchers.file", - New: func() interface{} { return new(MatchFile) }, - }) + caddy.RegisterModule(MatchFile{}) } // MatchFile is an HTTP request matcher that can match @@ -52,12 +49,20 @@ type MatchFile struct { TryPolicy string `json:"try_policy,omitempty"` } +// CaddyModule returns the Caddy module information. +func (MatchFile) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + Name: "http.matchers.file", + New: func() caddy.Module { return new(MatchFile) }, + } +} + // UnmarshalCaddyfile sets up the matcher from Caddyfile tokens. Syntax: // // file { // root <path> // try_files <files...> -// try_policy <first_exist|smallest_size|largest_size|most_recent_modified> +// try_policy first_exist|smallest_size|largest_size|most_recent_modified // } // func (m *MatchFile) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { @@ -82,6 +87,9 @@ func (m *MatchFile) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { } } } + if m.Root == "" { + m.Root = "{http.var.root}" + } return nil } @@ -121,7 +129,7 @@ func (m MatchFile) Match(r *http.Request) bool { func (m MatchFile) selectFile(r *http.Request) (rel, abs string, matched bool) { repl := r.Context().Value(caddy.ReplacerCtxKey).(caddy.Replacer) - root := repl.ReplaceAll(m.Root, "") + root := repl.ReplaceAll(m.Root, ".") // if list of files to try was omitted entirely, // assume URL path diff --git a/modules/caddyhttp/fileserver/staticfiles.go b/modules/caddyhttp/fileserver/staticfiles.go index 1b542cf..cdac453 100644 --- a/modules/caddyhttp/fileserver/staticfiles.go +++ b/modules/caddyhttp/fileserver/staticfiles.go @@ -36,10 +36,7 @@ import ( func init() { weakrand.Seed(time.Now().UnixNano()) - caddy.RegisterModule(caddy.Module{ - Name: "http.handlers.file_server", - New: func() interface{} { return new(FileServer) }, - }) + caddy.RegisterModule(FileServer{}) } // FileServer implements a static file server responder for Caddy. @@ -50,6 +47,14 @@ type FileServer struct { Browse *Browse `json:"browse,omitempty"` } +// CaddyModule returns the Caddy module information. +func (FileServer) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + Name: "http.handlers.file_server", + New: func() caddy.Module { return new(FileServer) }, + } +} + // Provision sets up the static files responder. func (fsrv *FileServer) Provision(ctx caddy.Context) error { if fsrv.IndexNames == nil { diff --git a/modules/caddyhttp/headers/caddyfile.go b/modules/caddyhttp/headers/caddyfile.go index 8d320e5..5eaf064 100644 --- a/modules/caddyhttp/headers/caddyfile.go +++ b/modules/caddyhttp/headers/caddyfile.go @@ -18,11 +18,15 @@ import ( "net/http" "strings" - "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" "github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile" + "github.com/caddyserver/caddy/v2/modules/caddyhttp" ) -// UnmarshalCaddyfile sets up the handler from Caddyfile tokens. Syntax: +func init() { + httpcaddyfile.RegisterHandlerDirective("headers", parseCaddyfile) +} + +// parseCaddyfile sets up the handler from Caddyfile tokens. Syntax: // // headers [<matcher>] [[+|-]<field> <value>] { // [+][<field>] [<value>] @@ -31,62 +35,57 @@ import ( // // Either a block can be opened or a single header field can be configured // in the first line, but not both in the same directive. -func (h *Headers) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { - for d.Next() { +func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error) { + hdr := new(Headers) + for h.Next() { // first see if headers are in the initial line var hasArgs bool - if d.NextArg() { + if h.NextArg() { hasArgs = true - field := d.Val() - d.NextArg() - value := d.Val() - h.processCaddyfileLine(field, value) + field := h.Val() + h.NextArg() + value := h.Val() + processCaddyfileLine(hdr, field, value) } // if not, they should be in a block - for d.NextBlock() { + for h.NextBlock() { if hasArgs { - return d.Err("cannot specify headers in both arguments and block") + return nil, h.Err("cannot specify headers in both arguments and block") } - field := d.Val() + field := h.Val() var value string - if d.NextArg() { - value = d.Val() + if h.NextArg() { + value = h.Val() } - h.processCaddyfileLine(field, value) + processCaddyfileLine(hdr, field, value) } } - return nil + return hdr, nil } -func (h *Headers) processCaddyfileLine(field, value string) { +func processCaddyfileLine(hdr *Headers, field, value string) { if strings.HasPrefix(field, "+") { - if h.Response == nil { - h.Response = &RespHeaderOps{HeaderOps: new(HeaderOps)} + if hdr.Response == nil { + hdr.Response = &RespHeaderOps{HeaderOps: new(HeaderOps)} } - if h.Response.Add == nil { - h.Response.Add = make(http.Header) + if hdr.Response.Add == nil { + hdr.Response.Add = make(http.Header) } - h.Response.Add.Set(field[1:], value) + hdr.Response.Add.Set(field[1:], value) } else if strings.HasPrefix(field, "-") { - if h.Response == nil { - h.Response = &RespHeaderOps{HeaderOps: new(HeaderOps)} + if hdr.Response == nil { + hdr.Response = &RespHeaderOps{HeaderOps: new(HeaderOps)} } - h.Response.Delete = append(h.Response.Delete, field[1:]) - h.Response.Deferred = true + hdr.Response.Delete = append(hdr.Response.Delete, field[1:]) + hdr.Response.Deferred = true } else { - if h.Response == nil { - h.Response = &RespHeaderOps{HeaderOps: new(HeaderOps)} + if hdr.Response == nil { + hdr.Response = &RespHeaderOps{HeaderOps: new(HeaderOps)} } - if h.Response.Set == nil { - h.Response.Set = make(http.Header) + if hdr.Response.Set == nil { + hdr.Response.Set = make(http.Header) } - h.Response.Set.Set(field, value) + hdr.Response.Set.Set(field, value) } } - -// Bucket returns the HTTP Caddyfile handler bucket number. -func (h Headers) Bucket() int { return 3 } - -// Interface guard -var _ httpcaddyfile.HandlerDirective = (*Headers)(nil) diff --git a/modules/caddyhttp/headers/headers.go b/modules/caddyhttp/headers/headers.go index 8f4976a..e740004 100644 --- a/modules/caddyhttp/headers/headers.go +++ b/modules/caddyhttp/headers/headers.go @@ -23,10 +23,7 @@ import ( ) func init() { - caddy.RegisterModule(caddy.Module{ - Name: "http.handlers.headers", - New: func() interface{} { return new(Headers) }, - }) + caddy.RegisterModule(Headers{}) } // Headers is a middleware which can mutate HTTP headers. @@ -35,6 +32,14 @@ type Headers struct { Response *RespHeaderOps `json:"response,omitempty"` } +// CaddyModule returns the Caddy module information. +func (Headers) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + Name: "http.handlers.headers", + New: func() caddy.Module { return new(Headers) }, + } +} + // HeaderOps defines some operations to // perform on HTTP headers. type HeaderOps struct { diff --git a/modules/caddyhttp/markdown/markdown.go b/modules/caddyhttp/markdown/markdown.go index 3ba4d02..122aad6 100644 --- a/modules/caddyhttp/markdown/markdown.go +++ b/modules/caddyhttp/markdown/markdown.go @@ -28,16 +28,21 @@ import ( ) func init() { - caddy.RegisterModule(caddy.Module{ - Name: "http.handlers.markdown", - New: func() interface{} { return new(Markdown) }, - }) + caddy.RegisterModule(Markdown{}) } // Markdown is a middleware for rendering a Markdown response body. type Markdown struct { } +// CaddyModule returns the Caddy module information. +func (Markdown) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + Name: "http.handlers.markdown", + New: func() caddy.Module { return new(Markdown) }, + } +} + func (m Markdown) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error { buf := bufPool.Get().(*bytes.Buffer) buf.Reset() diff --git a/modules/caddyhttp/matchers.go b/modules/caddyhttp/matchers.go index 72b5476..0dac151 100644 --- a/modules/caddyhttp/matchers.go +++ b/modules/caddyhttp/matchers.go @@ -80,50 +80,25 @@ type ( ) func init() { - caddy.RegisterModule(caddy.Module{ + caddy.RegisterModule(MatchHost{}) + caddy.RegisterModule(MatchPath{}) + caddy.RegisterModule(MatchPathRE{}) + caddy.RegisterModule(MatchMethod{}) + caddy.RegisterModule(MatchQuery{}) + caddy.RegisterModule(MatchHeader{}) + caddy.RegisterModule(MatchHeaderRE{}) + caddy.RegisterModule(new(MatchProtocol)) + caddy.RegisterModule(MatchRemoteIP{}) + caddy.RegisterModule(MatchNegate{}) + caddy.RegisterModule(new(MatchStarlarkExpr)) +} + +// CaddyModule returns the Caddy module information. +func (MatchHost) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ Name: "http.matchers.host", - New: func() interface{} { return new(MatchHost) }, - }) - caddy.RegisterModule(caddy.Module{ - Name: "http.matchers.path", - New: func() interface{} { return new(MatchPath) }, - }) - caddy.RegisterModule(caddy.Module{ - Name: "http.matchers.path_regexp", - New: func() interface{} { return new(MatchPathRE) }, - }) - caddy.RegisterModule(caddy.Module{ - Name: "http.matchers.method", - New: func() interface{} { return new(MatchMethod) }, - }) - caddy.RegisterModule(caddy.Module{ - Name: "http.matchers.query", - New: func() interface{} { return new(MatchQuery) }, - }) - caddy.RegisterModule(caddy.Module{ - Name: "http.matchers.header", - New: func() interface{} { return new(MatchHeader) }, - }) - caddy.RegisterModule(caddy.Module{ - Name: "http.matchers.header_regexp", - New: func() interface{} { return new(MatchHeaderRE) }, - }) - caddy.RegisterModule(caddy.Module{ - Name: "http.matchers.protocol", - New: func() interface{} { return new(MatchProtocol) }, - }) - caddy.RegisterModule(caddy.Module{ - Name: "http.matchers.remote_ip", - New: func() interface{} { return new(MatchRemoteIP) }, - }) - caddy.RegisterModule(caddy.Module{ - Name: "http.matchers.not", - New: func() interface{} { return new(MatchNegate) }, - }) - caddy.RegisterModule(caddy.Module{ - Name: "http.matchers.starlark_expr", - New: func() interface{} { return new(MatchStarlarkExpr) }, - }) + New: func() caddy.Module { return new(MatchHost) }, + } } // UnmarshalCaddyfile implements caddyfile.Unmarshaler. @@ -165,6 +140,14 @@ outer: return false } +// CaddyModule returns the Caddy module information. +func (MatchPath) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + Name: "http.matchers.path", + New: func() caddy.Module { return new(MatchPath) }, + } +} + // Match returns true if r matches m. func (m MatchPath) Match(r *http.Request) bool { for _, matchPath := range m { @@ -186,19 +169,39 @@ func (m MatchPath) Match(r *http.Request) bool { // UnmarshalCaddyfile implements caddyfile.Unmarshaler. func (m *MatchPath) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { - *m = d.RemainingArgs() + for d.Next() { + *m = d.RemainingArgs() + } return nil } +// CaddyModule returns the Caddy module information. +func (MatchPathRE) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + Name: "http.matchers.path_regexp", + New: func() caddy.Module { return new(MatchPathRE) }, + } +} + // Match returns true if r matches m. func (m MatchPathRE) Match(r *http.Request) bool { repl := r.Context().Value(caddy.ReplacerCtxKey).(caddy.Replacer) return m.MatchRegexp.Match(r.URL.Path, repl, "path_regexp") } +// CaddyModule returns the Caddy module information. +func (MatchMethod) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + Name: "http.matchers.method", + New: func() caddy.Module { return new(MatchMethod) }, + } +} + // UnmarshalCaddyfile implements caddyfile.Unmarshaler. func (m *MatchMethod) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { - *m = d.RemainingArgs() + for d.Next() { + *m = d.RemainingArgs() + } return nil } @@ -212,6 +215,14 @@ func (m MatchMethod) Match(r *http.Request) bool { return false } +// CaddyModule returns the Caddy module information. +func (MatchQuery) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + Name: "http.matchers.query", + New: func() caddy.Module { return new(MatchQuery) }, + } +} + // UnmarshalCaddyfile implements caddyfile.Unmarshaler. func (m *MatchQuery) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { for d.Next() { @@ -237,6 +248,14 @@ func (m MatchQuery) Match(r *http.Request) bool { return false } +// CaddyModule returns the Caddy module information. +func (MatchHeader) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + Name: "http.matchers.header", + New: func() caddy.Module { return new(MatchHeader) }, + } +} + // UnmarshalCaddyfile implements caddyfile.Unmarshaler. func (m *MatchHeader) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { for d.Next() { @@ -270,6 +289,14 @@ func (m MatchHeader) Match(r *http.Request) bool { return true } +// CaddyModule returns the Caddy module information. +func (MatchHeaderRE) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + Name: "http.matchers.header_regexp", + New: func() caddy.Module { return new(MatchHeaderRE) }, + } +} + // UnmarshalCaddyfile implements caddyfile.Unmarshaler. func (m *MatchHeaderRE) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { if *m == nil { @@ -319,6 +346,14 @@ func (m MatchHeaderRE) Validate() error { return nil } +// CaddyModule returns the Caddy module information. +func (MatchProtocol) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + Name: "http.matchers.protocol", + New: func() caddy.Module { return new(MatchProtocol) }, + } +} + // Match returns true if r matches m. func (m MatchProtocol) Match(r *http.Request) bool { switch string(m) { @@ -334,14 +369,24 @@ func (m MatchProtocol) Match(r *http.Request) bool { // UnmarshalCaddyfile implements caddyfile.Unmarshaler. func (m *MatchProtocol) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { - var proto string - if !d.Args(&proto) { - return d.Err("expected exactly one protocol") + for d.Next() { + var proto string + if !d.Args(&proto) { + return d.Err("expected exactly one protocol") + } + *m = MatchProtocol(proto) } - *m = MatchProtocol(proto) return nil } +// CaddyModule returns the Caddy module information. +func (MatchNegate) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + Name: "http.matchers.not", + New: func() caddy.Module { return new(MatchNegate) }, + } +} + // UnmarshalJSON unmarshals data into m's unexported map field. // This is done because we cannot embed the map directly into // the struct, but we need a struct because we need another @@ -375,9 +420,19 @@ func (m MatchNegate) Match(r *http.Request) bool { return !m.matchers.Match(r) } +// CaddyModule returns the Caddy module information. +func (MatchRemoteIP) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + Name: "http.matchers.remote_ip", + New: func() caddy.Module { return new(MatchRemoteIP) }, + } +} + // UnmarshalCaddyfile implements caddyfile.Unmarshaler. func (m *MatchRemoteIP) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { - m.Ranges = d.RemainingArgs() + for d.Next() { + m.Ranges = d.RemainingArgs() + } return nil } @@ -442,6 +497,14 @@ func (m MatchRemoteIP) Match(r *http.Request) bool { return false } +// CaddyModule returns the Caddy module information. +func (MatchStarlarkExpr) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + Name: "http.matchers.starlark_expr", // TODO: Rename to 'starlark'? + New: func() caddy.Module { return new(MatchStarlarkExpr) }, + } +} + // Match returns true if r matches m. func (m MatchStarlarkExpr) Match(r *http.Request) bool { input := string(m) @@ -513,8 +576,17 @@ func (mre *MatchRegexp) Match(input string, repl caddy.Replacer, scope string) b // UnmarshalCaddyfile implements caddyfile.Unmarshaler. func (mre *MatchRegexp) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { - if !d.Args(&mre.Name, &mre.Pattern) { - return fmt.Errorf("missing arguments") + for d.Next() { + args := d.RemainingArgs() + switch len(args) { + case 1: + mre.Pattern = args[0] + case 2: + mre.Name = args[0] + mre.Pattern = args[1] + default: + return d.ArgErr() + } } return nil } diff --git a/modules/caddyhttp/requestbody/requestbody.go b/modules/caddyhttp/requestbody/requestbody.go index 3763cfe..9b16250 100644 --- a/modules/caddyhttp/requestbody/requestbody.go +++ b/modules/caddyhttp/requestbody/requestbody.go @@ -22,10 +22,7 @@ import ( ) func init() { - caddy.RegisterModule(caddy.Module{ - Name: "http.handlers.request_body", - New: func() interface{} { return new(RequestBody) }, - }) + caddy.RegisterModule(RequestBody{}) } // RequestBody is a middleware for manipulating the request body. @@ -33,6 +30,14 @@ type RequestBody struct { MaxSize int64 `json:"max_size,omitempty"` } +// CaddyModule returns the Caddy module information. +func (RequestBody) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + Name: "http.handlers.request_body", // TODO: better name for this? + New: func() caddy.Module { return new(RequestBody) }, + } +} + func (rb RequestBody) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error { if r.Body == nil { return next.ServeHTTP(w, r) diff --git a/modules/caddyhttp/reverseproxy/module.go b/modules/caddyhttp/reverseproxy/module.go index ff5786c..21aca1d 100755 --- a/modules/caddyhttp/reverseproxy/module.go +++ b/modules/caddyhttp/reverseproxy/module.go @@ -15,39 +15,39 @@ package reverseproxy import ( - "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" - "github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile" "github.com/caddyserver/caddy/v2" + "github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile" + "github.com/caddyserver/caddy/v2/modules/caddyhttp" ) -// Register caddy module. func init() { - caddy.RegisterModule(caddy.Module{ + caddy.RegisterModule(new(LoadBalanced)) + httpcaddyfile.RegisterHandlerDirective("reverse_proxy", parseCaddyfile) // TODO: "proxy"? +} + +// CaddyModule returns the Caddy module information. +func (*LoadBalanced) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ Name: "http.handlers.reverse_proxy", - New: func() interface{} { return new(LoadBalanced) }, - }) + New: func() caddy.Module { return new(LoadBalanced) }, + } } -// UnmarshalCaddyfile sets up the handler from Caddyfile tokens. Syntax: +// parseCaddyfile sets up the handler from Caddyfile tokens. Syntax: // // proxy [<matcher>] <to> // // TODO: This needs to be finished. It definitely needs to be able to open a block... -func (lb *LoadBalanced) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { - for d.Next() { - allTo := d.RemainingArgs() +func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error) { + lb := new(LoadBalanced) + for h.Next() { + allTo := h.RemainingArgs() if len(allTo) == 0 { - return d.ArgErr() + return nil, h.ArgErr() } for _, to := range allTo { lb.Upstreams = append(lb.Upstreams, &UpstreamConfig{Host: to}) } } - return nil + return lb, nil } - -// Bucket returns the HTTP Caddyfile handler bucket number. -func (*LoadBalanced) Bucket() int { return 7 } - -// Interface guard -var _ httpcaddyfile.HandlerDirective = (*LoadBalanced)(nil) diff --git a/modules/caddyhttp/rewrite/caddyfile.go b/modules/caddyhttp/rewrite/caddyfile.go index a067fe1..a977a72 100644 --- a/modules/caddyhttp/rewrite/caddyfile.go +++ b/modules/caddyhttp/rewrite/caddyfile.go @@ -15,24 +15,23 @@ package rewrite import ( - "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" "github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile" + "github.com/caddyserver/caddy/v2/modules/caddyhttp" ) -// UnmarshalCaddyfile sets up the handler from Caddyfile tokens. Syntax: +func init() { + httpcaddyfile.RegisterHandlerDirective("rewrite", parseCaddyfile) +} + +// parseCaddyfile sets up the handler from Caddyfile tokens. Syntax: // // rewrite [<matcher>] <to> // // The <to> parameter becomes the new URI. -func (rewr *Rewrite) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { - for d.Next() { - rewr.URI = d.Val() +func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error) { + var rewr Rewrite + for h.Next() { + rewr.URI = h.Val() } - return nil + return rewr, nil } - -// Bucket returns the HTTP Caddyfile handler bucket number. -func (rewr Rewrite) Bucket() int { return 1 } - -// Interface guard -var _ httpcaddyfile.HandlerDirective = (*Rewrite)(nil) diff --git a/modules/caddyhttp/rewrite/rewrite.go b/modules/caddyhttp/rewrite/rewrite.go index ac113ff..f434a38 100644 --- a/modules/caddyhttp/rewrite/rewrite.go +++ b/modules/caddyhttp/rewrite/rewrite.go @@ -24,10 +24,7 @@ import ( ) func init() { - caddy.RegisterModule(caddy.Module{ - Name: "http.handlers.rewrite", - New: func() interface{} { return new(Rewrite) }, - }) + caddy.RegisterModule(Rewrite{}) } // Rewrite is a middleware which can rewrite HTTP requests. @@ -37,6 +34,14 @@ type Rewrite struct { Rehandle bool `json:"rehandle,omitempty"` } +// CaddyModule returns the Caddy module information. +func (Rewrite) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + Name: "http.handlers.rewrite", + New: func() caddy.Module { return new(Rewrite) }, + } +} + func (rewr Rewrite) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error { repl := r.Context().Value(caddy.ReplacerCtxKey).(caddy.Replacer) var rehandleNeeded bool diff --git a/modules/caddyhttp/routes.go b/modules/caddyhttp/routes.go index ffa7ce7..1efbad6 100644 --- a/modules/caddyhttp/routes.go +++ b/modules/caddyhttp/routes.go @@ -26,33 +26,34 @@ import ( // middlewares, and a responder for handling HTTP // requests. type Route struct { - Group string `json:"group,omitempty"` - MatcherSets []map[string]json.RawMessage `json:"match,omitempty"` - Handle []json.RawMessage `json:"handle,omitempty"` - Terminal bool `json:"terminal,omitempty"` + Group string `json:"group,omitempty"` + MatcherSetsRaw []map[string]json.RawMessage `json:"match,omitempty"` + HandlersRaw []json.RawMessage `json:"handle,omitempty"` + Terminal bool `json:"terminal,omitempty"` // decoded values - matcherSets []MatcherSet - handlers []MiddlewareHandler + MatcherSets []MatcherSet `json:"-"` + Handlers []MiddlewareHandler `json:"-"` } // Empty returns true if the route has all zero/default values. func (r Route) Empty() bool { - return len(r.MatcherSets) == 0 && - len(r.Handle) == 0 && - len(r.handlers) == 0 && + return len(r.MatcherSetsRaw) == 0 && + len(r.MatcherSets) == 0 && + len(r.HandlersRaw) == 0 && + len(r.Handlers) == 0 && !r.Terminal && r.Group == "" } func (r Route) anyMatcherSetMatches(req *http.Request) bool { - for _, ms := range r.matcherSets { + for _, ms := range r.MatcherSets { if ms.Match(req) { return true } } // if no matchers, always match - return len(r.matcherSets) == 0 + return len(r.MatcherSets) == 0 } // MatcherSet is a set of matchers which @@ -79,7 +80,7 @@ type RouteList []Route func (routes RouteList) Provision(ctx caddy.Context) error { for i, route := range routes { // matchers - for _, matcherSet := range route.MatcherSets { + for _, matcherSet := range route.MatcherSetsRaw { var matchers MatcherSet for modName, rawMsg := range matcherSet { val, err := ctx.LoadModule("http.matchers."+modName, rawMsg) @@ -88,19 +89,19 @@ func (routes RouteList) Provision(ctx caddy.Context) error { } matchers = append(matchers, val.(RequestMatcher)) } - routes[i].matcherSets = append(routes[i].matcherSets, matchers) + routes[i].MatcherSets = append(routes[i].MatcherSets, matchers) } - routes[i].MatcherSets = nil // allow GC to deallocate - TODO: Does this help? + routes[i].MatcherSetsRaw = nil // allow GC to deallocate - TODO: Does this help? // handlers - for j, rawMsg := range route.Handle { + for j, rawMsg := range route.HandlersRaw { mh, err := ctx.LoadModuleInline("handler", "http.handlers", rawMsg) if err != nil { return fmt.Errorf("loading handler module in position %d: %v", j, err) } - routes[i].handlers = append(routes[i].handlers, mh.(MiddlewareHandler)) + routes[i].Handlers = append(routes[i].Handlers, mh.(MiddlewareHandler)) } - routes[i].Handle = nil // allow GC to deallocate - TODO: Does this help? + routes[i].HandlersRaw = nil // allow GC to deallocate - TODO: Does this help? } return nil } @@ -135,7 +136,7 @@ func (routes RouteList) BuildCompositeRoute(req *http.Request) Handler { } // apply the rest of the route - for _, mh := range route.handlers { + for _, mh := range route.Handlers { // we have to be sure to wrap mh outside // of our current stack frame so that the // reference to this mh isn't overwritten diff --git a/modules/caddyhttp/staticerror.go b/modules/caddyhttp/staticerror.go index 1834cf7..3a45366 100644 --- a/modules/caddyhttp/staticerror.go +++ b/modules/caddyhttp/staticerror.go @@ -23,10 +23,7 @@ import ( ) func init() { - caddy.RegisterModule(caddy.Module{ - Name: "http.handlers.error", - New: func() interface{} { return new(StaticError) }, - }) + caddy.RegisterModule(StaticError{}) } // StaticError implements a simple handler that returns an error. @@ -35,6 +32,14 @@ type StaticError struct { StatusCode WeakString `json:"status_code,omitempty"` } +// CaddyModule returns the Caddy module information. +func (StaticError) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + Name: "http.handlers.error", + New: func() caddy.Module { return new(StaticError) }, + } +} + func (e StaticError) ServeHTTP(w http.ResponseWriter, r *http.Request, _ Handler) error { repl := r.Context().Value(caddy.ReplacerCtxKey).(caddy.Replacer) diff --git a/modules/caddyhttp/staticresp.go b/modules/caddyhttp/staticresp.go index cafee35..942459b 100644 --- a/modules/caddyhttp/staticresp.go +++ b/modules/caddyhttp/staticresp.go @@ -24,10 +24,8 @@ import ( ) func init() { - caddy.RegisterModule(caddy.Module{ - Name: "http.handlers.static_response", - New: func() interface{} { return new(StaticResponse) }, - }) + caddy.RegisterModule(StaticResponse{}) + // TODO: Caddyfile directive } // StaticResponse implements a simple responder for static responses. @@ -38,6 +36,14 @@ type StaticResponse struct { Close bool `json:"close,omitempty"` } +// CaddyModule returns the Caddy module information. +func (StaticResponse) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + Name: "http.handlers.static_response", + New: func() caddy.Module { return new(StaticResponse) }, + } +} + // UnmarshalCaddyfile sets up the handler from Caddyfile tokens. Syntax: // // static_response [<matcher>] <status> { @@ -71,9 +77,6 @@ func (s *StaticResponse) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { return nil } -// Bucket returns the HTTP Caddyfile handler bucket number. -func (StaticResponse) Bucket() int { return 7 } - func (s StaticResponse) ServeHTTP(w http.ResponseWriter, r *http.Request, _ Handler) error { repl := r.Context().Value(caddy.ReplacerCtxKey).(caddy.Replacer) diff --git a/modules/caddyhttp/subroute.go b/modules/caddyhttp/subroute.go index 9172146..3b0d718 100644 --- a/modules/caddyhttp/subroute.go +++ b/modules/caddyhttp/subroute.go @@ -22,10 +22,7 @@ import ( ) func init() { - caddy.RegisterModule(caddy.Module{ - Name: "http.handlers.subroute", - New: func() interface{} { return new(Subroute) }, - }) + caddy.RegisterModule(Subroute{}) } // Subroute implements a handler that compiles and executes routes. @@ -37,6 +34,14 @@ type Subroute struct { Routes RouteList `json:"routes,omitempty"` } +// CaddyModule returns the Caddy module information. +func (Subroute) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + Name: "http.handlers.subroute", + New: func() caddy.Module { return new(Subroute) }, + } +} + // Provision sets up subrouting. func (sr *Subroute) Provision(ctx caddy.Context) error { if sr.Routes != nil { diff --git a/modules/caddyhttp/templates/caddyfile.go b/modules/caddyhttp/templates/caddyfile.go index d27b8e3..d948da0 100644 --- a/modules/caddyhttp/templates/caddyfile.go +++ b/modules/caddyhttp/templates/caddyfile.go @@ -15,11 +15,15 @@ package templates import ( - "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" "github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile" + "github.com/caddyserver/caddy/v2/modules/caddyhttp" ) -// UnmarshalCaddyfile sets up the handler from Caddyfile tokens. Syntax: +func init() { + httpcaddyfile.RegisterHandlerDirective("templates", parseCaddyfile) +} + +// parseCaddyfile sets up the handler from Caddyfile tokens. Syntax: // // templates [<matcher>] { // mime <types...> @@ -27,23 +31,24 @@ import ( // root <path> // } // -func (t *Templates) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { - for d.Next() { - for d.NextBlock() { - switch d.Val() { +func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error) { + t := new(Templates) + for h.Next() { + for h.NextBlock() { + switch h.Val() { case "mime": - t.MIMETypes = d.RemainingArgs() + t.MIMETypes = h.RemainingArgs() if len(t.MIMETypes) == 0 { - return d.ArgErr() + return nil, h.ArgErr() } case "between": - t.Delimiters = d.RemainingArgs() + t.Delimiters = h.RemainingArgs() if len(t.Delimiters) != 2 { - return d.ArgErr() + return nil, h.ArgErr() } case "root": - if !d.Args(&t.IncludeRoot) { - return d.ArgErr() + if !h.Args(&t.IncludeRoot) { + return nil, h.ArgErr() } } } @@ -53,11 +58,5 @@ func (t *Templates) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { t.IncludeRoot = "{http.var.root}" } - return nil + return t, nil } - -// Bucket returns the HTTP Caddyfile handler bucket number. -func (t Templates) Bucket() int { return 5 } - -// Interface guard -var _ httpcaddyfile.HandlerDirective = (*Templates)(nil) diff --git a/modules/caddyhttp/templates/templates.go b/modules/caddyhttp/templates/templates.go index 442e177..1cd347c 100644 --- a/modules/caddyhttp/templates/templates.go +++ b/modules/caddyhttp/templates/templates.go @@ -27,10 +27,7 @@ import ( ) func init() { - caddy.RegisterModule(caddy.Module{ - Name: "http.handlers.templates", - New: func() interface{} { return new(Templates) }, - }) + caddy.RegisterModule(Templates{}) } // Templates is a middleware which execute response bodies as templates. @@ -40,6 +37,14 @@ type Templates struct { Delimiters []string `json:"delimiters,omitempty"` } +// CaddyModule returns the Caddy module information. +func (Templates) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + Name: "http.handlers.templates", + New: func() caddy.Module { return new(Templates) }, + } +} + // Provision provisions t. func (t *Templates) Provision(ctx caddy.Context) error { if t.MIMETypes == nil { diff --git a/modules/caddyhttp/vars.go b/modules/caddyhttp/vars.go index f74556a..bbd4568 100644 --- a/modules/caddyhttp/vars.go +++ b/modules/caddyhttp/vars.go @@ -21,20 +21,22 @@ import ( ) func init() { - caddy.RegisterModule(caddy.Module{ - Name: "http.handlers.vars", - New: func() interface{} { return new(VarsMiddleware) }, - }) - caddy.RegisterModule(caddy.Module{ - Name: "http.matchers.vars", - New: func() interface{} { return new(VarsMiddleware) }, - }) + caddy.RegisterModule(VarsMiddleware{}) + caddy.RegisterModule(VarsMatcher{}) } // VarsMiddleware is an HTTP middleware which sets variables // in the context, mainly for use by placeholders. type VarsMiddleware map[string]string +// CaddyModule returns the Caddy module information. +func (VarsMiddleware) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + Name: "http.handlers.vars", + New: func() caddy.Module { return new(VarsMiddleware) }, + } +} + func (t VarsMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request, next Handler) error { vars := r.Context().Value(VarCtxKey).(map[string]interface{}) repl := r.Context().Value(caddy.ReplacerCtxKey).(caddy.Replacer) @@ -50,6 +52,14 @@ func (t VarsMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request, next H // requests based on variables in the context. type VarsMatcher map[string]string +// CaddyModule returns the Caddy module information. +func (VarsMatcher) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + Name: "http.matchers.vars", + New: func() caddy.Module { return new(VarsMatcher) }, + } +} + // Match matches a request based on variables in the context. func (m VarsMatcher) Match(r *http.Request) bool { vars := r.Context().Value(VarCtxKey).(map[string]string) diff --git a/modules/caddytls/acmemanager.go b/modules/caddytls/acmemanager.go index 578cdb3..36f1c21 100644 --- a/modules/caddytls/acmemanager.go +++ b/modules/caddytls/acmemanager.go @@ -28,10 +28,7 @@ import ( ) func init() { - caddy.RegisterModule(caddy.Module{ - Name: "tls.management.acme", - New: func() interface{} { return new(ACMEManagerMaker) }, - }) + caddy.RegisterModule(ACMEManagerMaker{}) } // ACMEManagerMaker makes an ACME manager @@ -57,9 +54,17 @@ type ACMEManagerMaker struct { keyType certcrypto.KeyType } -// newManager is a no-op to satisfy the ManagerMaker interface, +// CaddyModule returns the Caddy module information. +func (ACMEManagerMaker) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + Name: "tls.management.acme", + New: func() caddy.Module { return new(ACMEManagerMaker) }, + } +} + +// NewManager is a no-op to satisfy the ManagerMaker interface, // because this manager type is a special case. -func (m *ACMEManagerMaker) newManager(interactive bool) (certmagic.Manager, error) { +func (m ACMEManagerMaker) NewManager(interactive bool) (certmagic.Manager, error) { return nil, nil } @@ -203,4 +208,4 @@ func onDemandAskRequest(ask string, name string) error { } // Interface guard -var _ managerMaker = (*ACMEManagerMaker)(nil) +var _ ManagerMaker = (*ACMEManagerMaker)(nil) diff --git a/modules/caddytls/fileloader.go b/modules/caddytls/fileloader.go index 7a0d14d..b2cc132 100644 --- a/modules/caddytls/fileloader.go +++ b/modules/caddytls/fileloader.go @@ -23,15 +23,20 @@ import ( ) func init() { - caddy.RegisterModule(caddy.Module{ - Name: "tls.certificates.load_files", - New: func() interface{} { return FileLoader{} }, - }) + caddy.RegisterModule(FileLoader{}) } // FileLoader loads certificates and their associated keys from disk. type FileLoader []CertKeyFilePair +// CaddyModule returns the Caddy module information. +func (FileLoader) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + Name: "tls.certificates.load_files", + New: func() caddy.Module { return new(FileLoader) }, + } +} + // CertKeyFilePair pairs certificate and key file names along with their // encoding format so that they can be loaded from disk. type CertKeyFilePair struct { diff --git a/modules/caddytls/folderloader.go b/modules/caddytls/folderloader.go index ae7f056..da1dff0 100644 --- a/modules/caddytls/folderloader.go +++ b/modules/caddytls/folderloader.go @@ -28,10 +28,7 @@ import ( ) func init() { - caddy.RegisterModule(caddy.Module{ - Name: "tls.certificates.load_folders", - New: func() interface{} { return FolderLoader{} }, - }) + caddy.RegisterModule(FolderLoader{}) } // FolderLoader loads certificates and their associated keys from disk @@ -39,6 +36,14 @@ func init() { // files which contain both a certificate and a key. type FolderLoader []string +// CaddyModule returns the Caddy module information. +func (FolderLoader) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + Name: "tls.certificates.load_folders", + New: func() caddy.Module { return new(FolderLoader) }, + } +} + // LoadCertificates loads all the certificates+keys in the directories // listed in fl from all files ending with .pem. This method of loading // certificates expects the certificate and key to be bundled into the diff --git a/modules/caddytls/matchers.go b/modules/caddytls/matchers.go index ee146d4..47fb296 100644 --- a/modules/caddytls/matchers.go +++ b/modules/caddytls/matchers.go @@ -20,14 +20,19 @@ import ( "github.com/caddyserver/caddy/v2" ) +func init() { + caddy.RegisterModule(MatchServerName{}) +} + // MatchServerName matches based on SNI. type MatchServerName []string -func init() { - caddy.RegisterModule(caddy.Module{ +// CaddyModule returns the Caddy module information. +func (MatchServerName) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ Name: "tls.handshake_match.sni", - New: func() interface{} { return MatchServerName{} }, - }) + New: func() caddy.Module { return new(MatchServerName) }, + } } // Match matches hello based on SNI. diff --git a/modules/caddytls/standardstek/stek.go b/modules/caddytls/standardstek/stek.go index 6a4b1c8..6d10c76 100644 --- a/modules/caddytls/standardstek/stek.go +++ b/modules/caddytls/standardstek/stek.go @@ -24,10 +24,7 @@ import ( ) func init() { - caddy.RegisterModule(caddy.Module{ - Name: "tls.stek.standard", - New: func() interface{} { return new(standardSTEKProvider) }, - }) + caddy.RegisterModule(standardSTEKProvider{}) } type standardSTEKProvider struct { @@ -35,6 +32,14 @@ type standardSTEKProvider struct { timer *time.Timer } +// CaddyModule returns the Caddy module information. +func (standardSTEKProvider) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + Name: "tls.stek.standard", + New: func() caddy.Module { return new(standardSTEKProvider) }, + } +} + // Initialize sets the configuration for s and returns the starting keys. func (s *standardSTEKProvider) Initialize(config *caddytls.SessionTicketService) ([][32]byte, error) { // keep a reference to the config; we'll need it when rotating keys diff --git a/modules/caddytls/tls.go b/modules/caddytls/tls.go index ec16995..88b7790 100644 --- a/modules/caddytls/tls.go +++ b/modules/caddytls/tls.go @@ -30,10 +30,7 @@ import ( ) func init() { - caddy.RegisterModule(caddy.Module{ - Name: "tls", - New: func() interface{} { return new(TLS) }, - }) + caddy.RegisterModule(TLS{}) // opt-in TLS 1.3 for Go1.12 // TODO: remove this line when Go1.13 is released. @@ -53,6 +50,14 @@ type TLS struct { ctx caddy.Context } +// CaddyModule returns the Caddy module information. +func (TLS) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + Name: "tls", + New: func() caddy.Module { return new(TLS) }, + } +} + // Provision sets up the configuration for the TLS app. func (t *TLS) Provision(ctx caddy.Context) error { t.ctx = ctx @@ -73,7 +78,7 @@ func (t *TLS) Provision(ctx caddy.Context) error { if err != nil { return fmt.Errorf("loading TLS automation management module: %s", err) } - t.Automation.Policies[i].Management = val.(managerMaker) + t.Automation.Policies[i].Management = val.(ManagerMaker) t.Automation.Policies[i].ManagementRaw = nil // allow GC to deallocate - TODO: Does this help? } @@ -237,7 +242,7 @@ type AutomationPolicy struct { Hosts []string `json:"hosts,omitempty"` ManagementRaw json.RawMessage `json:"management,omitempty"` - Management managerMaker `json:"-"` + Management ManagerMaker `json:"-"` } // makeCertMagicConfig converts ap into a CertMagic config. Passing onDemand @@ -252,7 +257,7 @@ func (ap AutomationPolicy) makeCertMagicConfig(ctx caddy.Context) certmagic.Conf } return certmagic.Config{ - NewManager: ap.Management.newManager, + NewManager: ap.Management.NewManager, } } @@ -290,9 +295,9 @@ type RateLimit struct { Burst int `json:"burst,omitempty"` } -// managerMaker makes a certificate manager. -type managerMaker interface { - newManager(interactive bool) (certmagic.Manager, error) +// ManagerMaker makes a certificate manager. +type ManagerMaker interface { + NewManager(interactive bool) (certmagic.Manager, error) } // These perpetual values are used for on-demand TLS. |