go: x/net/http2/h2c: http BaseContext/ConnContext methods are not used

What version of Go are you using (go version)?

go version go1.13.7 darwin/amd64

Does this issue reproduce with the latest release?

Yes

What did you do? What did you expect to see? What did you see instead?

Currently, the http2/h2c package does not use the http.Server.BaseContext or http.Server.ConnContext methods. This means if I use the h2c package to upgrade a connection, the context for the user’s is inherited from the background context rather than any context returned from the BaseContext or ConnContext functions.

A possible fix would be something like this:

diff --git a/http2/h2c/h2c.go b/http2/h2c/h2c.go
index 07c5c9a..349a5e6 100644
--- a/http2/h2c/h2c.go
+++ b/http2/h2c/h2c.go
@@ -11,6 +11,7 @@ package h2c
 import (
        "bufio"
        "bytes"
+       "context"
        "encoding/base64"
        "encoding/binary"
        "errors"
@@ -84,6 +85,10 @@ func (s h2cHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
                }
                defer conn.Close()

+               ctx := context.Background()
+               if server, ok := r.Context().Value(http.ServerContextKey).(*http.Server); ok && server.ConnContext != nil {
+                       ctx = server.ConnContext(ctx, conn)
+               }
                s.s.ServeConn(conn, &http2.ServeConnOpts{Handler: s.Handler})
                return
        }
@@ -91,6 +96,10 @@ func (s h2cHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
        if conn, err := h2cUpgrade(w, r); err == nil {
                defer conn.Close()

+               ctx := context.Background()
+               if server, ok := r.Context().Value(http.ServerContextKey).(*http.Server); ok && server.ConnContext != nil {
+                       ctx = server.ConnContext(ctx, conn)
+               }
                s.s.ServeConn(conn, &http2.ServeConnOpts{Handler: s.Handler})
                return
        }

Does this seem reasonable?

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 15 (5 by maintainers)

Commits related to this issue

Most upvoted comments

we’re implementing an auth system which uses ConnContext to extract some per-connection information that is used later for auth purposes:

  • when we receive a TCP connection, we do some expensive operations and store the result in the context to be used by all subsequent requests.
  • This is currently being done via ConnContext for HTTP1, and it’s working great, but doesn’t work when we use an h2c handler with HTTP/2.

we’d like to help make this change and have a preliminary patch ready. would that be something folks here would consider?