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
+)