diff --git a/modules/caddyhttp/app.go b/modules/caddyhttp/app.go index e586556ca..a76da0413 100644 --- a/modules/caddyhttp/app.go +++ b/modules/caddyhttp/app.go @@ -439,6 +439,9 @@ func (app *App) Start() error { Handler: srv, ErrorLog: serverLogger, Protocols: new(http.Protocols), + ConnContext: func(ctx context.Context, c net.Conn) context.Context { + return context.WithValue(ctx, ConnCtxKey, c) + }, } // disable HTTP/2, which we enabled by default during provisioning diff --git a/modules/caddyhttp/server.go b/modules/caddyhttp/server.go index 32b06b271..242d7f99a 100644 --- a/modules/caddyhttp/server.go +++ b/modules/caddyhttp/server.go @@ -263,6 +263,18 @@ 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() + } + } + } + w.Header().Set("Server", "Caddy") // advertise HTTP/3, if enabled @@ -1067,7 +1079,7 @@ const ( OriginalRequestCtxKey caddy.CtxKey = "original_request" // For referencing underlying net.Conn - // DEPRECATED: Not used anymore. To refer to the underlying connection, implement a middleware plugin + // This will eventually be deprecated and not used. To refer to the underlying connection, implement a middleware plugin // that RegisterConnContext during provisioning. ConnCtxKey caddy.CtxKey = "conn"