diff --git a/caddyhttp/httpserver/middleware.go b/caddyhttp/httpserver/middleware.go index 91fbbf5b..e6b8ff96 100644 --- a/caddyhttp/httpserver/middleware.go +++ b/caddyhttp/httpserver/middleware.go @@ -6,6 +6,8 @@ import ( "os" "path" "time" + + "github.com/mholt/caddy" ) func init() { @@ -18,6 +20,10 @@ type ( // passed the next Handler in the chain. Middleware func(Handler) Handler + // ListenerMiddleware is similar to the Middleware type, except it + // chains one net.Listener to the next. + ListenerMiddleware func(caddy.Listener) caddy.Listener + // Handler is like http.Handler except ServeHTTP may return a status // code and/or error. // diff --git a/caddyhttp/httpserver/plugin.go b/caddyhttp/httpserver/plugin.go index 4c7caa3e..65d0a552 100644 --- a/caddyhttp/httpserver/plugin.go +++ b/caddyhttp/httpserver/plugin.go @@ -445,6 +445,9 @@ var directives = []string{ "realip", // github.com/captncraig/caddy-realip "git", // github.com/abiosoft/caddy-git + // directives that add listener middleware to the stack + "proxyprotocol", // github.com/mastercactapus/caddy-proxyprotocol + // directives that add middleware to the stack "locale", // github.com/simia-tech/caddy-locale "log", diff --git a/caddyhttp/httpserver/server.go b/caddyhttp/httpserver/server.go index ec4f0af3..2a3ed7c9 100644 --- a/caddyhttp/httpserver/server.go +++ b/caddyhttp/httpserver/server.go @@ -215,9 +215,20 @@ func (s *Server) Listen() (net.Listener, error) { } } + if tcpLn, ok := ln.(*net.TCPListener); ok { + ln = tcpKeepAliveListener{TCPListener: tcpLn} + } + + cln := ln.(caddy.Listener) + for _, site := range s.sites { + for _, m := range site.listenerMiddleware { + cln = m(cln) + } + } + // Very important to return a concrete caddy.Listener // implementation for graceful restarts. - return ln.(*net.TCPListener), nil + return cln.(caddy.Listener), nil } // ListenPacket creates udp connection for QUIC if it is enabled, @@ -234,10 +245,6 @@ func (s *Server) ListenPacket() (net.PacketConn, error) { // Serve serves requests on ln. It blocks until ln is closed. func (s *Server) Serve(ln net.Listener) error { - if tcpLn, ok := ln.(*net.TCPListener); ok { - ln = tcpKeepAliveListener{TCPListener: tcpLn} - } - s.listenerMu.Lock() s.listener = ln s.listenerMu.Unlock() diff --git a/caddyhttp/httpserver/siteconfig.go b/caddyhttp/httpserver/siteconfig.go index e9880192..de18bd47 100644 --- a/caddyhttp/httpserver/siteconfig.go +++ b/caddyhttp/httpserver/siteconfig.go @@ -25,6 +25,9 @@ type SiteConfig struct { // Compiled middleware stack middlewareChain Handler + // listener middleware stack + listenerMiddleware []ListenerMiddleware + // Directory from which to serve files Root string @@ -80,6 +83,11 @@ func (s *SiteConfig) AddMiddleware(m Middleware) { s.middleware = append(s.middleware, m) } +// AddListenerMiddleware adds a listener middleware to a site's listenerMiddleware stack. +func (s *SiteConfig) AddListenerMiddleware(l ListenerMiddleware) { + s.listenerMiddleware = append(s.listenerMiddleware, l) +} + // TLSConfig returns s.TLS. func (s SiteConfig) TLSConfig() *caddytls.Config { return s.TLS @@ -99,3 +107,8 @@ func (s SiteConfig) Port() string { func (s SiteConfig) Middleware() []Middleware { return s.middleware } + +// ListenerMiddleware returns s.listenerMiddleware +func (s SiteConfig) ListenerMiddleware() []ListenerMiddleware { + return s.listenerMiddleware +}