Refactor automatic HTTPS configuration; ability to skip certain names

This commit is contained in:
Matthew Holt 2019-06-26 10:49:32 -06:00
parent 6000855c82
commit 91b03dccb0
2 changed files with 63 additions and 27 deletions

View file

@ -48,16 +48,23 @@ func (app *App) Provision(ctx caddy.Context) error {
repl := caddy.NewReplacer() repl := caddy.NewReplacer()
for _, srv := range app.Servers { for _, srv := range app.Servers {
if srv.AutoHTTPS == nil {
// avoid nil pointer dereferences
srv.AutoHTTPS = new(AutoHTTPSConfig)
}
// TODO: Test this function to ensure these replacements are performed // TODO: Test this function to ensure these replacements are performed
for i := range srv.Listen { for i := range srv.Listen {
srv.Listen[i] = repl.ReplaceAll(srv.Listen[i], "") srv.Listen[i] = repl.ReplaceAll(srv.Listen[i], "")
} }
if srv.Routes != nil { if srv.Routes != nil {
err := srv.Routes.Provision(ctx) err := srv.Routes.Provision(ctx)
if err != nil { if err != nil {
return fmt.Errorf("setting up server routes: %v", err) return fmt.Errorf("setting up server routes: %v", err)
} }
} }
if srv.Errors != nil { if srv.Errors != nil {
err := srv.Errors.Routes.Provision(ctx) err := srv.Errors.Routes.Provision(ctx)
if err != nil { if err != nil {
@ -187,7 +194,7 @@ func (app *App) automaticHTTPS() error {
for srvName, srv := range app.Servers { for srvName, srv := range app.Servers {
srv.tlsApp = tlsApp srv.tlsApp = tlsApp
if srv.DisableAutoHTTPS { if srv.AutoHTTPS.Disabled {
continue continue
} }
@ -203,7 +210,7 @@ func (app *App) automaticHTTPS() error {
for _, m := range matcherSet { for _, m := range matcherSet {
if hm, ok := m.(*MatchHost); ok { if hm, ok := m.(*MatchHost); ok {
for _, d := range *hm { for _, d := range *hm {
if certmagic.HostQualifies(d) { if certmagic.HostQualifies(d) && !srv.AutoHTTPS.HostSkipped(d) {
domainSet[d] = struct{}{} domainSet[d] = struct{}{}
} }
} }
@ -256,7 +263,7 @@ func (app *App) automaticHTTPS() error {
{ALPN: defaultALPN}, {ALPN: defaultALPN},
} }
if srv.DisableAutoHTTPSRedir { if srv.AutoHTTPS.DisableRedir {
continue continue
} }
@ -324,10 +331,10 @@ func (app *App) automaticHTTPS() error {
lnAddrs = append(lnAddrs, addr) lnAddrs = append(lnAddrs, addr)
} }
app.Servers["auto_https_redirects"] = &Server{ app.Servers["auto_https_redirects"] = &Server{
Listen: lnAddrs, Listen: lnAddrs,
Routes: redirRoutes, Routes: redirRoutes,
DisableAutoHTTPS: true, AutoHTTPS: &AutoHTTPSConfig{Disabled: true},
tlsApp: tlsApp, // required to solve HTTP challenge tlsApp: tlsApp, // required to solve HTTP challenge
} }
} }

View file

@ -14,19 +14,17 @@ import (
// Server is an HTTP server. // Server is an HTTP server.
type Server struct { type Server struct {
Listen []string `json:"listen,omitempty"` Listen []string `json:"listen,omitempty"`
ReadTimeout caddy.Duration `json:"read_timeout,omitempty"` ReadTimeout caddy.Duration `json:"read_timeout,omitempty"`
ReadHeaderTimeout caddy.Duration `json:"read_header_timeout,omitempty"` ReadHeaderTimeout caddy.Duration `json:"read_header_timeout,omitempty"`
WriteTimeout caddy.Duration `json:"write_timeout,omitempty"` WriteTimeout caddy.Duration `json:"write_timeout,omitempty"`
IdleTimeout caddy.Duration `json:"idle_timeout,omitempty"` IdleTimeout caddy.Duration `json:"idle_timeout,omitempty"`
MaxHeaderBytes int `json:"max_header_bytes,omitempty"` MaxHeaderBytes int `json:"max_header_bytes,omitempty"`
Routes RouteList `json:"routes,omitempty"` Routes RouteList `json:"routes,omitempty"`
Errors *httpErrorConfig `json:"errors,omitempty"` Errors *HTTPErrorConfig `json:"errors,omitempty"`
// TODO: Having a separate connection policy to act as a default or template would be handy... then override using first matching conn policy... TLSConnPolicies caddytls.ConnectionPolicies `json:"tls_connection_policies,omitempty"`
TLSConnPolicies caddytls.ConnectionPolicies `json:"tls_connection_policies,omitempty"` AutoHTTPS *AutoHTTPSConfig `json:"automatic_https,omitempty"`
DisableAutoHTTPS bool `json:"disable_auto_https,omitempty"` MaxRehandles int `json:"max_rehandles,omitempty"`
DisableAutoHTTPSRedir bool `json:"disable_auto_https_redir,omitempty"`
MaxRehandles int `json:"max_rehandles,omitempty"`
tlsApp *caddytls.TLS tlsApp *caddytls.TLS
} }
@ -121,13 +119,44 @@ func (s *Server) listenersUseAnyPortOtherThan(otherPort int) bool {
return false return false
} }
type httpErrorConfig struct { // AutoHTTPSConfig is used to disable automatic HTTPS
Routes RouteList `json:"routes,omitempty"` // or certain aspects of it for a specific server.
// TODO: some way to configure the logging of errors, probably? standardize type AutoHTTPSConfig struct {
// the logging configuration first. // If true, automatic HTTPS will be entirely disabled.
Disabled bool `json:"disable,omitempty"`
// If true, only automatic HTTP->HTTPS redirects will
// be disabled.
DisableRedir bool `json:"disable_redirects,omitempty"`
// Hosts/domain names listed here will not be included
// in automatic HTTPS (they will not have certificates
// loaded nor redirects applied).
Skip []string `json:"skip,omitempty"`
} }
const ServerCtxKey caddy.CtxKey = "server" // HostSkipped returns true if name is supposed to be skipped
// when setting up automatic HTTPS.
func (ahc AutoHTTPSConfig) HostSkipped(name string) bool {
for _, n := range ahc.Skip {
if name == n {
return true
}
}
return false
}
// TableCtxKey is the context key for the request's variable table. TODO: implement this // HTTPErrorConfig determines how to handle errors
const TableCtxKey caddy.CtxKey = "table" // from the HTTP handlers.
type HTTPErrorConfig struct {
Routes RouteList `json:"routes,omitempty"`
}
// Context keys for HTTP request context values.
const (
// For referencing the server instance
ServerCtxKey caddy.CtxKey = "server"
// For the request's variable table (TODO: implement this)
TableCtxKey caddy.CtxKey = "table"
)