summaryrefslogtreecommitdiff
path: root/caddyconfig/httpcaddyfile/builtins.go
diff options
context:
space:
mode:
Diffstat (limited to 'caddyconfig/httpcaddyfile/builtins.go')
-rw-r--r--caddyconfig/httpcaddyfile/builtins.go356
1 files changed, 177 insertions, 179 deletions
diff --git a/caddyconfig/httpcaddyfile/builtins.go b/caddyconfig/httpcaddyfile/builtins.go
index 7e51e46..0fdfcd5 100644
--- a/caddyconfig/httpcaddyfile/builtins.go
+++ b/caddyconfig/httpcaddyfile/builtins.go
@@ -19,239 +19,237 @@ import (
"fmt"
"html"
"net/http"
+ "reflect"
- "github.com/caddyserver/caddy/v2/caddyconfig"
- "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
- "github.com/caddyserver/caddy/v2/modules/caddyhttp"
+ "github.com/caddyserver/caddy/caddyconfig"
+ "github.com/caddyserver/caddy/modules/caddyhttp"
"github.com/caddyserver/caddy/v2/modules/caddytls"
)
-func (st *ServerType) parseRoot(
- tkns []caddyfile.Token,
- matcherDefs map[string]map[string]json.RawMessage,
- warnings *[]caddyconfig.Warning,
-) ([]caddyhttp.Route, error) {
- var routes []caddyhttp.Route
-
- matchersAndTokens, err := st.tokensToMatcherSets(tkns, matcherDefs, warnings)
- if err != nil {
- return nil, err
- }
-
- for _, mst := range matchersAndTokens {
- d := caddyfile.NewDispenser("Caddyfile", mst.tokens)
-
- var root string
- for d.Next() {
- if !d.NextArg() {
- return nil, d.ArgErr()
- }
- root = d.Val()
- if d.NextArg() {
- return nil, d.ArgErr()
- }
- }
-
- varsHandler := caddyhttp.VarsMiddleware{"root": root}
- route := caddyhttp.Route{
- Handle: []json.RawMessage{
- caddyconfig.JSONModuleObject(varsHandler, "handler", "vars", warnings),
- },
- }
- if mst.matcherSet != nil {
- route.MatcherSets = []map[string]json.RawMessage{mst.matcherSet}
- }
+func init() {
+ RegisterDirective("bind", parseBind)
+ RegisterDirective("root", parseRoot)
+ RegisterDirective("tls", parseTLS)
+ RegisterHandlerDirective("redir", parseRedir)
+}
- routes = append(routes, route)
+func parseBind(h Helper) ([]ConfigValue, error) {
+ var lnHosts []string
+ for h.Next() {
+ lnHosts = append(lnHosts, h.RemainingArgs()...)
}
-
- return routes, nil
+ return h.NewBindAddresses(lnHosts), nil
}
-func (st *ServerType) parseRedir(
- tkns []caddyfile.Token,
- matcherDefs map[string]map[string]json.RawMessage,
- warnings *[]caddyconfig.Warning,
-) ([]caddyhttp.Route, error) {
- var routes []caddyhttp.Route
+func parseRoot(h Helper) ([]ConfigValue, error) {
+ if !h.Next() {
+ return nil, h.ArgErr()
+ }
- matchersAndTokens, err := st.tokensToMatcherSets(tkns, matcherDefs, warnings)
+ matcherSet, ok, err := h.MatcherToken()
if err != nil {
return nil, err
}
-
- for _, mst := range matchersAndTokens {
- var route caddyhttp.Route
-
- d := caddyfile.NewDispenser("Caddyfile", mst.tokens)
-
- for d.Next() {
- if !d.NextArg() {
- return nil, d.ArgErr()
- }
- to := d.Val()
-
- var code string
- if d.NextArg() {
- code = d.Val()
- }
- if code == "permanent" {
- code = "301"
- }
- if code == "temporary" || code == "" {
- code = "307"
- }
- var body string
- if code == "meta" {
- // Script tag comes first since that will better imitate a redirect in the browser's
- // history, but the meta tag is a fallback for most non-JS clients.
- const metaRedir = `<!DOCTYPE html>
-<html>
- <head>
- <title>Redirecting...</title>
- <script>window.location.replace("%s");</script>
- <meta http-equiv="refresh" content="0; URL='%s'">
- </head>
- <body>Redirecting to <a href="%s">%s</a>...</body>
-</html>
-`
- safeTo := html.EscapeString(to)
- body = fmt.Sprintf(metaRedir, safeTo, safeTo, safeTo, safeTo)
- }
-
- handler := caddyhttp.StaticResponse{
- StatusCode: caddyhttp.WeakString(code),
- Headers: http.Header{"Location": []string{to}},
- Body: body,
- }
-
- route.Handle = append(route.Handle,
- caddyconfig.JSONModuleObject(handler, "handler", "static_response", warnings))
- }
-
- if mst.matcherSet != nil {
- route.MatcherSets = []map[string]json.RawMessage{mst.matcherSet}
- }
-
- routes = append(routes, route)
+ if !ok {
+ // no matcher token; oops
+ h.Dispenser.Prev()
}
- return routes, nil
-}
-
-func (st *ServerType) parseTLSAutomationManager(d *caddyfile.Dispenser) (caddytls.ACMEManagerMaker, error) {
- var m caddytls.ACMEManagerMaker
-
- for d.Next() {
- firstLine := d.RemainingArgs()
- if len(firstLine) == 1 && firstLine[0] != "off" {
- m.Email = firstLine[0]
- }
-
- var hasBlock bool
- for d.NextBlock() {
- hasBlock = true
- switch d.Val() {
- case "ca":
- arg := d.RemainingArgs()
- if len(arg) != 1 {
- return m, d.ArgErr()
- }
- m.CA = arg[0]
- // TODO: other properties
- }
- }
+ if !h.NextArg() {
+ return nil, h.ArgErr()
+ }
+ root := h.Val()
+ if h.NextArg() {
+ return nil, h.ArgErr()
+ }
- // a naked tls directive is not allowed
- if len(firstLine) == 0 && !hasBlock {
- return m, d.ArgErr()
- }
+ varsHandler := caddyhttp.VarsMiddleware{"root": root}
+ route := caddyhttp.Route{
+ HandlersRaw: []json.RawMessage{
+ caddyconfig.JSONModuleObject(varsHandler, "handler", "vars", nil),
+ },
+ }
+ if matcherSet != nil {
+ route.MatcherSetsRaw = []map[string]json.RawMessage{matcherSet}
}
- return m, nil
+ return h.NewVarsRoute(route), nil
}
-func (st *ServerType) parseTLSCerts(d *caddyfile.Dispenser) (map[string]caddytls.CertificateLoader, error) {
+func parseTLS(h Helper) ([]ConfigValue, error) {
+ var configVals []ConfigValue
+
+ cp := new(caddytls.ConnectionPolicy)
var fileLoader caddytls.FileLoader
var folderLoader caddytls.FolderLoader
-
- for d.Next() {
- // file loader
- firstLine := d.RemainingArgs()
- if len(firstLine) == 2 {
+ var mgr caddytls.ACMEManagerMaker
+ var off bool
+
+ for h.Next() {
+ // file certificate loader
+ firstLine := h.RemainingArgs()
+ switch len(firstLine) {
+ case 0:
+ case 1:
+ if firstLine[0] == "off" {
+ off = true
+ } else {
+ mgr.Email = firstLine[0]
+ }
+ case 2:
fileLoader = append(fileLoader, caddytls.CertKeyFilePair{
Certificate: firstLine[0],
Key: firstLine[1],
- // TODO: tags, for enterprise module's certificate selection
+ // TODO: add tags, for enterprise module's certificate selection
})
+ default:
+ return nil, h.ArgErr()
}
- // folder loader
- for d.NextBlock() {
- if d.Val() == "load" {
- folderLoader = append(folderLoader, d.RemainingArgs()...)
- }
- }
- }
-
- // put configured loaders into the map
- loaders := make(map[string]caddytls.CertificateLoader)
- if len(fileLoader) > 0 {
- loaders["load_files"] = fileLoader
- }
- if len(folderLoader) > 0 {
- loaders["load_folders"] = folderLoader
- }
-
- return loaders, nil
-}
+ var hasBlock bool
+ for h.NextBlock() {
+ hasBlock = true
-func (st *ServerType) parseTLSConnPolicy(d *caddyfile.Dispenser) (*caddytls.ConnectionPolicy, error) {
- cp := new(caddytls.ConnectionPolicy)
+ switch h.Val() {
- for d.Next() {
- for d.NextBlock() {
- switch d.Val() {
+ // connection policy
case "protocols":
- args := d.RemainingArgs()
+ args := h.RemainingArgs()
if len(args) == 0 {
- return nil, d.SyntaxErr("one or two protocols")
+ return nil, h.SyntaxErr("one or two protocols")
}
if len(args) > 0 {
if _, ok := caddytls.SupportedProtocols[args[0]]; !ok {
- return nil, d.Errf("Wrong protocol name or protocol not supported: '%s'", args[0])
+ return nil, h.Errf("Wrong protocol name or protocol not supported: '%s'", args[0])
}
cp.ProtocolMin = args[0]
}
if len(args) > 1 {
if _, ok := caddytls.SupportedProtocols[args[1]]; !ok {
- return nil, d.Errf("Wrong protocol name or protocol not supported: '%s'", args[1])
+ return nil, h.Errf("Wrong protocol name or protocol not supported: '%s'", args[1])
}
cp.ProtocolMax = args[1]
}
case "ciphers":
- for d.NextArg() {
- if _, ok := caddytls.SupportedCipherSuites[d.Val()]; !ok {
- return nil, d.Errf("Wrong cipher suite name or cipher suite not supported: '%s'", d.Val())
+ for h.NextArg() {
+ if _, ok := caddytls.SupportedCipherSuites[h.Val()]; !ok {
+ return nil, h.Errf("Wrong cipher suite name or cipher suite not supported: '%s'", h.Val())
}
- cp.CipherSuites = append(cp.CipherSuites, d.Val())
+ cp.CipherSuites = append(cp.CipherSuites, h.Val())
}
case "curves":
- for d.NextArg() {
- if _, ok := caddytls.SupportedCurves[d.Val()]; !ok {
- return nil, d.Errf("Wrong curve name or curve not supported: '%s'", d.Val())
+ for h.NextArg() {
+ if _, ok := caddytls.SupportedCurves[h.Val()]; !ok {
+ return nil, h.Errf("Wrong curve name or curve not supported: '%s'", h.Val())
}
- cp.Curves = append(cp.Curves, d.Val())
+ cp.Curves = append(cp.Curves, h.Val())
}
case "alpn":
- args := d.RemainingArgs()
+ args := h.RemainingArgs()
if len(args) == 0 {
- return nil, d.ArgErr()
+ return nil, h.ArgErr()
}
cp.ALPN = args
+
+ // certificate folder loader
+ case "load":
+ folderLoader = append(folderLoader, h.RemainingArgs()...)
+
+ // automation policy
+ case "ca":
+ arg := h.RemainingArgs()
+ if len(arg) != 1 {
+ return nil, h.ArgErr()
+ }
+ mgr.CA = arg[0]
+
+ // TODO: other properties for automation manager
}
}
+
+ // a naked tls directive is not allowed
+ if len(firstLine) == 0 && !hasBlock {
+ return nil, h.ArgErr()
+ }
+ }
+
+ // connection policy
+ configVals = append(configVals, ConfigValue{
+ Class: "tls.connection_policy",
+ Value: cp,
+ })
+
+ // certificate loaders
+ if len(fileLoader) > 0 {
+ configVals = append(configVals, ConfigValue{
+ Class: "tls.certificate_loader",
+ Value: fileLoader,
+ })
+ }
+ if len(folderLoader) > 0 {
+ configVals = append(configVals, ConfigValue{
+ Class: "tls.certificate_loader",
+ Value: folderLoader,
+ })
+ }
+
+ // automation policy
+ if off {
+ configVals = append(configVals, ConfigValue{
+ Class: "tls.off",
+ Value: true,
+ })
+ } else if !reflect.DeepEqual(mgr, caddytls.ACMEManagerMaker{}) {
+ configVals = append(configVals, ConfigValue{
+ Class: "tls.automation_manager",
+ Value: mgr,
+ })
+ }
+
+ return configVals, nil
+}
+
+func parseRedir(h Helper) (caddyhttp.MiddlewareHandler, error) {
+ if !h.Next() {
+ return nil, h.ArgErr()
+ }
+
+ if !h.NextArg() {
+ return nil, h.ArgErr()
+ }
+ to := h.Val()
+
+ var code string
+ if h.NextArg() {
+ code = h.Val()
+ }
+ if code == "permanent" {
+ code = "301"
+ }
+ if code == "temporary" || code == "" {
+ code = "307"
+ }
+ var body string
+ if code == "meta" {
+ // Script tag comes first since that will better imitate a redirect in the browser's
+ // history, but the meta tag is a fallback for most non-JS clients.
+ const metaRedir = `<!DOCTYPE html>
+<html>
+ <head>
+ <title>Redirecting...</title>
+ <script>window.location.replace("%s");</script>
+ <meta http-equiv="refresh" content="0; URL='%s'">
+ </head>
+ <body>Redirecting to <a href="%s">%s</a>...</body>
+</html>
+`
+ safeTo := html.EscapeString(to)
+ body = fmt.Sprintf(metaRedir, safeTo, safeTo, safeTo, safeTo)
}
- return cp, nil
+ return caddyhttp.StaticResponse{
+ StatusCode: caddyhttp.WeakString(code),
+ Headers: http.Header{"Location": []string{to}},
+ Body: body,
+ }, nil
}