summaryrefslogtreecommitdiff
path: root/modules/caddyhttp
diff options
context:
space:
mode:
authorFrancis Lavoie <lavofr@gmail.com>2022-02-19 17:36:36 -0500
committerGitHub <noreply@github.com>2022-02-19 15:36:36 -0700
commit186fdba916a128fc2a837852d2ab04ac2efba413 (patch)
treec08c2a684b31ba32fcbb4ff1f81fdbcfaab1e2bb /modules/caddyhttp
parent7778912d4eb51b5ae2c7af584c42fc85e1e09f2c (diff)
caddyhttp: Move HTTP redirect listener to an optional module (#4585)
Diffstat (limited to 'modules/caddyhttp')
-rw-r--r--modules/caddyhttp/app.go5
-rw-r--r--modules/caddyhttp/httpredirectlistener.go42
2 files changed, 42 insertions, 5 deletions
diff --git a/modules/caddyhttp/app.go b/modules/caddyhttp/app.go
index 67f9d1d..64cc540 100644
--- a/modules/caddyhttp/app.go
+++ b/modules/caddyhttp/app.go
@@ -343,11 +343,6 @@ func (app *App) Start() error {
// enable TLS if there is a policy and if this is not the HTTP port
useTLS := len(srv.TLSConnPolicies) > 0 && int(listenAddr.StartPort+portOffset) != app.httpPort()
if useTLS {
- // create HTTP redirect wrapper, which detects if
- // the request had HTTP bytes on the HTTPS port, and
- // triggers a redirect if so.
- ln = &httpRedirectListener{Listener: ln}
-
// create TLS listener
tlsCfg := srv.TLSConnPolicies.TLSConfig(app.ctx)
ln = tls.NewListener(ln, tlsCfg)
diff --git a/modules/caddyhttp/httpredirectlistener.go b/modules/caddyhttp/httpredirectlistener.go
index 38225a3..3ff79ff 100644
--- a/modules/caddyhttp/httpredirectlistener.go
+++ b/modules/caddyhttp/httpredirectlistener.go
@@ -20,8 +20,45 @@ import (
"net"
"net/http"
"sync"
+
+ "github.com/caddyserver/caddy/v2"
+ "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
)
+func init() {
+ caddy.RegisterModule(HTTPRedirectListenerWrapper{})
+}
+
+// HTTPRedirectListenerWrapper provides HTTP->HTTPS redirects for
+// connections that come on the TLS port as an HTTP request,
+// by detecting using the first few bytes that it's not a TLS
+// handshake, but instead an HTTP request.
+//
+// This is especially useful when using a non-standard HTTPS port.
+// A user may simply type the address in their browser without the
+// https:// scheme, which would cause the browser to attempt the
+// connection over HTTP, but this would cause a "Client sent an
+// HTTP request to an HTTPS server" error response.
+//
+// This listener wrapper must be placed BEFORE the "tls" listener
+// wrapper, for it to work properly.
+type HTTPRedirectListenerWrapper struct{}
+
+func (HTTPRedirectListenerWrapper) CaddyModule() caddy.ModuleInfo {
+ return caddy.ModuleInfo{
+ ID: "caddy.listeners.http_redirect",
+ New: func() caddy.Module { return new(HTTPRedirectListenerWrapper) },
+ }
+}
+
+func (h *HTTPRedirectListenerWrapper) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
+ return nil
+}
+
+func (h *HTTPRedirectListenerWrapper) WrapListener(l net.Listener) net.Listener {
+ return &httpRedirectListener{l}
+}
+
// httpRedirectListener is listener that checks the first few bytes
// of the request when the server is intended to accept HTTPS requests,
// to respond to an HTTP request with a redirect.
@@ -112,3 +149,8 @@ func firstBytesLookLikeHTTP(hdr []byte) bool {
}
return false
}
+
+var (
+ _ caddy.ListenerWrapper = (*HTTPRedirectListenerWrapper)(nil)
+ _ caddyfile.Unmarshaler = (*HTTPRedirectListenerWrapper)(nil)
+)