@marcel91200 / caddy Mirror · read-only / commits / 186fdba9
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 13, 21:45 UTC

caddyhttp: Move HTTP redirect listener to an optional module (#4585)

Francis Lavoie committed Feb 19, 2022 at 17:36 UTC 186fdba916a128fc2a837852d2ab04ac2efba413
3 files changed +46 -5
caddytest/integration/caddyfile_adapt/global_server_options_single.txt
+4
@@ -1,6 +1,7 @@
1 {
2 servers {
3 listener_wrappers {
4 + http_redirect
5 tls
6 }
7 timeouts {
@@ -32,6 +33,9 @@ foo.com {
33 ":443"
34 ],
35 "listener_wrappers": [
36 + {
37 + "wrapper": "http_redirect"
38 + },
39 {
40 "wrapper": "tls"
41 }
modules/caddyhttp/app.go
-5
@@ -343,11 +343,6 @@ func (app *App) Start() error {
343 // enable TLS if there is a policy and if this is not the HTTP port
344 useTLS := len(srv.TLSConnPolicies) > 0 && int(listenAddr.StartPort+portOffset) != app.httpPort()
345 if useTLS {
346 - // create HTTP redirect wrapper, which detects if
347 - // the request had HTTP bytes on the HTTPS port, and
348 - // triggers a redirect if so.
349 - ln = &httpRedirectListener{Listener: ln}
350 -
346 // create TLS listener
347 tlsCfg := srv.TLSConnPolicies.TLSConfig(app.ctx)
348 ln = tls.NewListener(ln, tlsCfg)
modules/caddyhttp/httpredirectlistener.go
+42
@@ -20,8 +20,45 @@ import (
20 "net"
21 "net/http"
22 "sync"
23 +
24 + "github.com/caddyserver/caddy/v2"
25 + "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
26 )
27
28 +func init() {
29 + caddy.RegisterModule(HTTPRedirectListenerWrapper{})
30 +}
31 +
32 +// HTTPRedirectListenerWrapper provides HTTP->HTTPS redirects for
33 +// connections that come on the TLS port as an HTTP request,
34 +// by detecting using the first few bytes that it's not a TLS
35 +// handshake, but instead an HTTP request.
36 +//
37 +// This is especially useful when using a non-standard HTTPS port.
38 +// A user may simply type the address in their browser without the
39 +// https:// scheme, which would cause the browser to attempt the
40 +// connection over HTTP, but this would cause a "Client sent an
41 +// HTTP request to an HTTPS server" error response.
42 +//
43 +// This listener wrapper must be placed BEFORE the "tls" listener
44 +// wrapper, for it to work properly.
45 +type HTTPRedirectListenerWrapper struct{}
46 +
47 +func (HTTPRedirectListenerWrapper) CaddyModule() caddy.ModuleInfo {
48 + return caddy.ModuleInfo{
49 + ID: "caddy.listeners.http_redirect",
50 + New: func() caddy.Module { return new(HTTPRedirectListenerWrapper) },
51 + }
52 +}
53 +
54 +func (h *HTTPRedirectListenerWrapper) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
55 + return nil
56 +}
57 +
58 +func (h *HTTPRedirectListenerWrapper) WrapListener(l net.Listener) net.Listener {
59 + return &httpRedirectListener{l}
60 +}
61 +
62 // httpRedirectListener is listener that checks the first few bytes
63 // of the request when the server is intended to accept HTTPS requests,
64 // to respond to an HTTP request with a redirect.
@@ -112,3 +149,8 @@ func firstBytesLookLikeHTTP(hdr []byte) bool {
149 }
150 return false
151 }
152 +
153 +var (
154 + _ caddy.ListenerWrapper = (*HTTPRedirectListenerWrapper)(nil)
155 + _ caddyfile.Unmarshaler = (*HTTPRedirectListenerWrapper)(nil)
156 +)