Use CertMagic's HTTP and HTTPS port variable

Slightly inconvenient because it uses int type and we use string, but
oh well. This fixes a bug related to setting -http-port and -https-port
flags which weren't being used by CertMagic in some cases.
This commit is contained in:
Matthew Holt 2019-06-19 16:55:27 -06:00
parent 6720bdfb55
commit 721c100bb0
3 changed files with 34 additions and 27 deletions

View file

@ -18,6 +18,7 @@ import (
"fmt" "fmt"
"net" "net"
"net/http" "net/http"
"strconv"
"github.com/mholt/caddy" "github.com/mholt/caddy"
"github.com/mholt/caddy/caddytls" "github.com/mholt/caddy/caddytls"
@ -125,7 +126,7 @@ func enableAutoHTTPS(configs []*SiteConfig, loadCertificates bool) error {
cfg.TLS.Enabled && cfg.TLS.Enabled &&
(!cfg.TLS.Manual || cfg.TLS.Manager.OnDemand != nil) && (!cfg.TLS.Manual || cfg.TLS.Manager.OnDemand != nil) &&
cfg.Addr.Host != "localhost" { cfg.Addr.Host != "localhost" {
cfg.Addr.Port = HTTPSPort cfg.Addr.Port = strconv.Itoa(certmagic.HTTPSPort)
} }
} }
return nil return nil
@ -138,10 +139,12 @@ func enableAutoHTTPS(configs []*SiteConfig, loadCertificates bool) error {
// only set up redirects for configs that qualify. It returns the updated list of // only set up redirects for configs that qualify. It returns the updated list of
// all configs. // all configs.
func makePlaintextRedirects(allConfigs []*SiteConfig) []*SiteConfig { func makePlaintextRedirects(allConfigs []*SiteConfig) []*SiteConfig {
httpPort := strconv.Itoa(certmagic.HTTPPort)
httpsPort := strconv.Itoa(certmagic.HTTPSPort)
for i, cfg := range allConfigs { for i, cfg := range allConfigs {
if cfg.TLS.Managed && if cfg.TLS.Managed &&
!hostHasOtherPort(allConfigs, i, HTTPPort) && !hostHasOtherPort(allConfigs, i, httpPort) &&
(cfg.Addr.Port == HTTPSPort || !hostHasOtherPort(allConfigs, i, HTTPSPort)) { (cfg.Addr.Port == httpsPort || !hostHasOtherPort(allConfigs, i, httpsPort)) {
allConfigs = append(allConfigs, redirPlaintextHost(cfg)) allConfigs = append(allConfigs, redirPlaintextHost(cfg))
} }
} }
@ -167,10 +170,10 @@ func hostHasOtherPort(allConfigs []*SiteConfig, thisConfigIdx int, otherPort str
// redirPlaintextHost returns a new plaintext HTTP configuration for // redirPlaintextHost returns a new plaintext HTTP configuration for
// a virtualHost that simply redirects to cfg, which is assumed to // a virtualHost that simply redirects to cfg, which is assumed to
// be the HTTPS configuration. The returned configuration is set // be the HTTPS configuration. The returned configuration is set
// to listen on HTTPPort. The TLS field of cfg must not be nil. // to listen on certmagic.HTTPPort. The TLS field of cfg must not be nil.
func redirPlaintextHost(cfg *SiteConfig) *SiteConfig { func redirPlaintextHost(cfg *SiteConfig) *SiteConfig {
redirPort := cfg.Addr.Port redirPort := cfg.Addr.Port
if redirPort == HTTPSPort { if redirPort == strconv.Itoa(certmagic.HTTPSPort) {
// By default, HTTPSPort should be DefaultHTTPSPort, // By default, HTTPSPort should be DefaultHTTPSPort,
// which of course doesn't need to be explicitly stated // which of course doesn't need to be explicitly stated
// in the Location header. Even if HTTPSPort is changed // in the Location header. Even if HTTPSPort is changed
@ -210,7 +213,7 @@ func redirPlaintextHost(cfg *SiteConfig) *SiteConfig {
} }
host := cfg.Addr.Host host := cfg.Addr.Host
port := HTTPPort port := strconv.Itoa(certmagic.HTTPPort)
addr := net.JoinHostPort(host, port) addr := net.JoinHostPort(host, port)
return &SiteConfig{ return &SiteConfig{

View file

@ -38,8 +38,8 @@ import (
const serverType = "http" const serverType = "http"
func init() { func init() {
flag.StringVar(&HTTPPort, "http-port", HTTPPort, "Default port to use for HTTP") flag.IntVar(&certmagic.HTTPPort, "http-port", certmagic.HTTPPort, "Default port to use for HTTP")
flag.StringVar(&HTTPSPort, "https-port", HTTPSPort, "Default port to use for HTTPS") flag.IntVar(&certmagic.HTTPSPort, "https-port", certmagic.HTTPSPort, "Default port to use for HTTPS")
flag.StringVar(&Host, "host", DefaultHost, "Default host") flag.StringVar(&Host, "host", DefaultHost, "Default host")
flag.StringVar(&Port, "port", DefaultPort, "Default port") flag.StringVar(&Port, "port", DefaultPort, "Default port")
flag.StringVar(&Root, "root", DefaultRoot, "Root path of default site") flag.StringVar(&Root, "root", DefaultRoot, "Root path of default site")
@ -128,6 +128,8 @@ func (h *httpContext) saveConfig(key string, cfg *SiteConfig) {
// be parsed and executed. // be parsed and executed.
func (h *httpContext) InspectServerBlocks(sourceFile string, serverBlocks []caddyfile.ServerBlock) ([]caddyfile.ServerBlock, error) { func (h *httpContext) InspectServerBlocks(sourceFile string, serverBlocks []caddyfile.ServerBlock) ([]caddyfile.ServerBlock, error) {
siteAddrs := make(map[string]string) siteAddrs := make(map[string]string)
httpPort := strconv.Itoa(certmagic.HTTPPort)
httpsPort := strconv.Itoa(certmagic.HTTPSPort)
// For each address in each server block, make a new config // For each address in each server block, make a new config
for _, sb := range serverBlocks { for _, sb := range serverBlocks {
@ -172,15 +174,15 @@ func (h *httpContext) InspectServerBlocks(sourceFile string, serverBlocks []cadd
// If default HTTP or HTTPS ports have been customized, // If default HTTP or HTTPS ports have been customized,
// make sure the ACME challenge ports match // make sure the ACME challenge ports match
var altHTTPPort, altTLSALPNPort int var altHTTPPort, altTLSALPNPort int
if HTTPPort != DefaultHTTPPort { if httpPort != DefaultHTTPPort {
portInt, err := strconv.Atoi(HTTPPort) portInt, err := strconv.Atoi(httpPort)
if err != nil { if err != nil {
return nil, err return nil, err
} }
altHTTPPort = portInt altHTTPPort = portInt
} }
if HTTPSPort != DefaultHTTPSPort { if httpsPort != DefaultHTTPSPort {
portInt, err := strconv.Atoi(HTTPSPort) portInt, err := strconv.Atoi(httpsPort)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -228,6 +230,9 @@ func (h *httpContext) InspectServerBlocks(sourceFile string, serverBlocks []cadd
// MakeServers uses the newly-created siteConfigs to // MakeServers uses the newly-created siteConfigs to
// create and return a list of server instances. // create and return a list of server instances.
func (h *httpContext) MakeServers() ([]caddy.Server, error) { func (h *httpContext) MakeServers() ([]caddy.Server, error) {
httpPort := strconv.Itoa(certmagic.HTTPPort)
httpsPort := strconv.Itoa(certmagic.HTTPSPort)
// make a rough estimate as to whether we're in a "production // make a rough estimate as to whether we're in a "production
// environment/system" - start by assuming that most production // environment/system" - start by assuming that most production
// servers will set their default CA endpoint to a public, // servers will set their default CA endpoint to a public,
@ -266,7 +271,7 @@ func (h *httpContext) MakeServers() ([]caddy.Server, error) {
if !cfg.TLS.Enabled { if !cfg.TLS.Enabled {
continue continue
} }
if cfg.Addr.Port == HTTPPort || cfg.Addr.Scheme == "http" { if cfg.Addr.Port == httpPort || cfg.Addr.Scheme == "http" {
cfg.TLS.Enabled = false cfg.TLS.Enabled = false
log.Printf("[WARNING] TLS disabled for %s", cfg.Addr) log.Printf("[WARNING] TLS disabled for %s", cfg.Addr)
} else if cfg.Addr.Scheme == "" { } else if cfg.Addr.Scheme == "" {
@ -281,7 +286,7 @@ func (h *httpContext) MakeServers() ([]caddy.Server, error) {
// this is vital, otherwise the function call below that // this is vital, otherwise the function call below that
// sets the listener address will use the default port // sets the listener address will use the default port
// instead of 443 because it doesn't know about TLS. // instead of 443 because it doesn't know about TLS.
cfg.Addr.Port = HTTPSPort cfg.Addr.Port = httpsPort
} }
if cfg.TLS.ClientAuth != tls.NoClientCert { if cfg.TLS.ClientAuth != tls.NoClientCert {
if QUIC { if QUIC {
@ -421,7 +426,7 @@ func (a Address) String() string {
} }
scheme := a.Scheme scheme := a.Scheme
if scheme == "" { if scheme == "" {
if a.Port == HTTPSPort { if a.Port == strconv.Itoa(certmagic.HTTPSPort) {
scheme = "https" scheme = "https"
} else { } else {
scheme = "http" scheme = "http"
@ -502,6 +507,9 @@ func (a Address) Key() string {
func standardizeAddress(str string) (Address, error) { func standardizeAddress(str string) (Address, error) {
input := str input := str
httpPort := strconv.Itoa(certmagic.HTTPPort)
httpsPort := strconv.Itoa(certmagic.HTTPSPort)
// Split input into components (prepend with // to assert host by default) // Split input into components (prepend with // to assert host by default)
if !strings.Contains(str, "//") && !strings.HasPrefix(str, "/") { if !strings.Contains(str, "//") && !strings.HasPrefix(str, "/") {
str = "//" + str str = "//" + str
@ -523,9 +531,9 @@ func standardizeAddress(str string) (Address, error) {
// see if we can set port based off scheme // see if we can set port based off scheme
if port == "" { if port == "" {
if u.Scheme == "http" { if u.Scheme == "http" {
port = HTTPPort port = httpPort
} else if u.Scheme == "https" { } else if u.Scheme == "https" {
port = HTTPSPort port = httpsPort
} }
} }
@ -535,17 +543,17 @@ func standardizeAddress(str string) (Address, error) {
} }
// error if scheme and port combination violate convention // error if scheme and port combination violate convention
if (u.Scheme == "http" && port == HTTPSPort) || (u.Scheme == "https" && port == HTTPPort) { if (u.Scheme == "http" && port == httpsPort) || (u.Scheme == "https" && port == httpPort) {
return Address{}, fmt.Errorf("[%s] scheme and port violate convention", input) return Address{}, fmt.Errorf("[%s] scheme and port violate convention", input)
} }
// standardize http and https ports to their respective port numbers // standardize http and https ports to their respective port numbers
if port == "http" { if port == "http" {
u.Scheme = "http" u.Scheme = "http"
port = HTTPPort port = httpPort
} else if port == "https" { } else if port == "https" {
u.Scheme = "https" u.Scheme = "https"
port = HTTPSPort port = httpsPort
} }
return Address{Original: input, Scheme: u.Scheme, Host: host, Port: port, Path: u.Path}, err return Address{Original: input, Scheme: u.Scheme, Host: host, Port: port, Path: u.Path}, err
@ -723,10 +731,4 @@ var (
// QUIC indicates whether QUIC is enabled or not. // QUIC indicates whether QUIC is enabled or not.
QUIC bool QUIC bool
// HTTPPort is the port to use for HTTP.
HTTPPort = DefaultHTTPPort
// HTTPSPort is the port to use for HTTPS.
HTTPSPort = DefaultHTTPSPort
) )

View file

@ -25,6 +25,7 @@ import (
"net/http" "net/http"
"net/url" "net/url"
"path" "path"
"strconv"
"strings" "strings"
"sync" "sync"
"text/template" "text/template"
@ -33,6 +34,7 @@ import (
"os" "os"
"github.com/mholt/caddy/caddytls" "github.com/mholt/caddy/caddytls"
"github.com/mholt/certmagic"
"github.com/russross/blackfriday" "github.com/russross/blackfriday"
) )
@ -178,7 +180,7 @@ func (c Context) Port() (string, error) {
if err != nil { if err != nil {
if !strings.Contains(c.Req.Host, ":") { if !strings.Contains(c.Req.Host, ":") {
// common with sites served on the default port 80 // common with sites served on the default port 80
return HTTPPort, nil return strconv.Itoa(certmagic.HTTPPort), nil
} }
return "", err return "", err
} }