From eaf987c66aa221f535cbd2b1dafc4f59688b925d Mon Sep 17 00:00:00 2001 From: Nathan Caza Date: Sun, 5 Feb 2017 15:51:40 -0600 Subject: [PATCH 1/4] add support for listener middleware --- caddyhttp/httpserver/middleware.go | 5 +++++ caddyhttp/httpserver/server.go | 12 +++++++++++- caddyhttp/httpserver/siteconfig.go | 13 +++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/caddyhttp/httpserver/middleware.go b/caddyhttp/httpserver/middleware.go index 91fbbf5b0ca..b7243e6e95f 100644 --- a/caddyhttp/httpserver/middleware.go +++ b/caddyhttp/httpserver/middleware.go @@ -2,6 +2,7 @@ package httpserver import ( "fmt" + "net" "net/http" "os" "path" @@ -18,6 +19,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(net.Listener) net.Listener + // Handler is like http.Handler except ServeHTTP may return a status // code and/or error. // diff --git a/caddyhttp/httpserver/server.go b/caddyhttp/httpserver/server.go index 2384b1602c8..15be60e3b8f 100644 --- a/caddyhttp/httpserver/server.go +++ b/caddyhttp/httpserver/server.go @@ -122,9 +122,19 @@ func (s *Server) Listen() (net.Listener, error) { } } + if tcpLn, ok := ln.(*net.TCPListener); ok { + ln = tcpKeepAliveListener{TCPListener: tcpLn} + } + + for _, site := range s.sites { + for _, m := range site.listenerMiddleware { + ln = m(ln) + } + } + // Very important to return a concrete caddy.Listener // implementation for graceful restarts. - return ln.(*net.TCPListener), nil + return ln.(caddy.Listener), nil } // ListenPacket creates udp connection for QUIC if it is enabled, diff --git a/caddyhttp/httpserver/siteconfig.go b/caddyhttp/httpserver/siteconfig.go index e98801923e5..de18bd4771c 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 +} From a77f339130e67aa4b267f9d0ea27a9644a95ab4f Mon Sep 17 00:00:00 2001 From: Nathan Caza Date: Mon, 13 Feb 2017 23:24:51 -0600 Subject: [PATCH 2/4] add proxyprotocol directive --- caddyhttp/httpserver/plugin.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/caddyhttp/httpserver/plugin.go b/caddyhttp/httpserver/plugin.go index c1bd6a5703b..c9ab32cce40 100644 --- a/caddyhttp/httpserver/plugin.go +++ b/caddyhttp/httpserver/plugin.go @@ -425,6 +425,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", From 9107466685fafa24fc87bb5c7cd99e5da7f0dfc7 Mon Sep 17 00:00:00 2001 From: Nathan Caza Date: Wed, 15 Feb 2017 23:11:39 -0600 Subject: [PATCH 3/4] make caddy.Listener interface required --- caddyhttp/httpserver/middleware.go | 5 +++-- caddyhttp/httpserver/server.go | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/caddyhttp/httpserver/middleware.go b/caddyhttp/httpserver/middleware.go index b7243e6e95f..e6b8ff963c9 100644 --- a/caddyhttp/httpserver/middleware.go +++ b/caddyhttp/httpserver/middleware.go @@ -2,11 +2,12 @@ package httpserver import ( "fmt" - "net" "net/http" "os" "path" "time" + + "github.com/mholt/caddy" ) func init() { @@ -21,7 +22,7 @@ type ( // ListenerMiddleware is similar to the Middleware type, except it // chains one net.Listener to the next. - ListenerMiddleware func(net.Listener) net.Listener + 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/server.go b/caddyhttp/httpserver/server.go index 15be60e3b8f..3e856a80c88 100644 --- a/caddyhttp/httpserver/server.go +++ b/caddyhttp/httpserver/server.go @@ -126,15 +126,16 @@ func (s *Server) Listen() (net.Listener, error) { ln = tcpKeepAliveListener{TCPListener: tcpLn} } + cln := ln.(caddy.Listener) for _, site := range s.sites { for _, m := range site.listenerMiddleware { - ln = m(ln) + cln = m(cln) } } // Very important to return a concrete caddy.Listener // implementation for graceful restarts. - return ln.(caddy.Listener), nil + return cln.(caddy.Listener), nil } // ListenPacket creates udp connection for QUIC if it is enabled, From 10c6de51b670efa2721a44990f3dacff4457bc61 Mon Sep 17 00:00:00 2001 From: Nathan Caza Date: Thu, 9 Mar 2017 20:39:23 -0600 Subject: [PATCH 4/4] Remove tcpKeepAliveListener wrapper from Serve() This is now done in the Listen() function, along with other potential middleware. --- caddyhttp/httpserver/server.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/caddyhttp/httpserver/server.go b/caddyhttp/httpserver/server.go index d6c6fd4bc4f..2a3ed7c9bac 100644 --- a/caddyhttp/httpserver/server.go +++ b/caddyhttp/httpserver/server.go @@ -245,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()