mirror of
https://github.com/caddyserver/caddy.git
synced 2025-10-19 07:43:17 +00:00
caddyhttp: wrap accepted connection to suppress tls.ConnectionState (#7247)
This commit is contained in:
parent
d7185fd002
commit
1ce2a13ad1
4 changed files with 166 additions and 11 deletions
|
@ -466,7 +466,14 @@ func (app *App) Start() error {
|
|||
ErrorLog: serverLogger,
|
||||
Protocols: new(http.Protocols),
|
||||
ConnContext: func(ctx context.Context, c net.Conn) context.Context {
|
||||
return context.WithValue(ctx, ConnCtxKey, c)
|
||||
if nc, ok := c.(interface{ tlsNetConn() net.Conn }); ok {
|
||||
getTlsConStateFunc := sync.OnceValue(func() *tls.ConnectionState {
|
||||
tlsConnState := nc.tlsNetConn().(connectionStater).ConnectionState()
|
||||
return &tlsConnState
|
||||
})
|
||||
ctx = context.WithValue(ctx, tlsConnectionStateFuncCtxKey, getTlsConStateFunc)
|
||||
}
|
||||
return ctx
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,12 @@ func (h *http2Listener) Accept() (net.Conn, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// *tls.Conn doesn't need to be wrapped because we already removed unwanted alpns
|
||||
// and handshake won't succeed without mutually supported alpns
|
||||
if tlsConn, ok := conn.(*tls.Conn); ok {
|
||||
return tlsConn, nil
|
||||
}
|
||||
|
||||
_, isConnectionStater := conn.(connectionStater)
|
||||
// emit a warning
|
||||
if h.useTLS && !isConnectionStater {
|
||||
|
@ -46,6 +52,9 @@ func (h *http2Listener) Accept() (net.Conn, error) {
|
|||
|
||||
// if both h1 and h2 are enabled, we don't need to check the preface
|
||||
if h.useH1 && h.useH2 {
|
||||
if isConnectionStater {
|
||||
return tlsStateConn{conn}, nil
|
||||
}
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
|
@ -53,14 +62,26 @@ func (h *http2Listener) Accept() (net.Conn, error) {
|
|||
// or else the listener wouldn't be created
|
||||
h2Conn := &http2Conn{
|
||||
h2Expected: h.useH2,
|
||||
logger: h.logger,
|
||||
Conn: conn,
|
||||
}
|
||||
if isConnectionStater {
|
||||
return http2StateConn{h2Conn}, nil
|
||||
return tlsStateConn{http2StateConn{h2Conn}}, nil
|
||||
}
|
||||
return h2Conn, nil
|
||||
}
|
||||
|
||||
// tlsStateConn wraps a net.Conn that implements connectionStater to hide that method
|
||||
// we can call netConn to get the original net.Conn and get the tls connection state
|
||||
// golang 1.25 will call that method, and it breaks h2 with connections other than *tls.Conn
|
||||
type tlsStateConn struct {
|
||||
net.Conn
|
||||
}
|
||||
|
||||
func (conn tlsStateConn) tlsNetConn() net.Conn {
|
||||
return conn.Conn
|
||||
}
|
||||
|
||||
type http2StateConn struct {
|
||||
*http2Conn
|
||||
}
|
||||
|
|
|
@ -288,14 +288,9 @@ type Server struct {
|
|||
// ServeHTTP is the entry point for all HTTP requests.
|
||||
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
// If there are listener wrappers that process tls connections but don't return a *tls.Conn, this field will be nil.
|
||||
// TODO: Scheduled to be removed later because https://github.com/golang/go/pull/56110 has been merged.
|
||||
if r.TLS == nil {
|
||||
// not all requests have a conn (like virtual requests) - see #5698
|
||||
if conn, ok := r.Context().Value(ConnCtxKey).(net.Conn); ok {
|
||||
if csc, ok := conn.(connectionStater); ok {
|
||||
r.TLS = new(tls.ConnectionState)
|
||||
*r.TLS = csc.ConnectionState()
|
||||
}
|
||||
if tlsConnStateFunc, ok := r.Context().Value(tlsConnectionStateFuncCtxKey).(func() *tls.ConnectionState); ok {
|
||||
r.TLS = tlsConnStateFunc()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1115,11 +1110,14 @@ const (
|
|||
// originally came into the server's entry handler
|
||||
OriginalRequestCtxKey caddy.CtxKey = "original_request"
|
||||
|
||||
// For referencing underlying net.Conn
|
||||
// This will eventually be deprecated and not used. To refer to the underlying connection, implement a middleware plugin
|
||||
// DEPRECATED: not used anymore.
|
||||
// To refer to the underlying connection, implement a middleware plugin
|
||||
// that RegisterConnContext during provisioning.
|
||||
ConnCtxKey caddy.CtxKey = "conn"
|
||||
|
||||
// used to get the tls connection state in the context, if available
|
||||
tlsConnectionStateFuncCtxKey caddy.CtxKey = "tls_connection_state_func"
|
||||
|
||||
// For tracking whether the client is a trusted proxy
|
||||
TrustedProxyVarKey string = "trusted_proxy"
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue