ServeConn serves HTTP/2 requests on the provided connection and blocks until the connection is no longer readable.

ServeConn starts speaking HTTP/2 assuming that c has not had any reads or writes. It writes its initial settings frame and expects to be able to read the preface and settings frame from the client. If c has a ConnectionState method like a *tls.Conn, the ConnectionState is used to verify the TLS ciphersuite and to set the Request.TLS field in Handlers.

ServeConn does not support h2c by itself. Any h2c support must be implemented in terms of providing a suitably-behaving net.Conn.

The opts parameter is optional. If nil, default values are used.

ServeConn is referenced in 1 repository


func (s *http2Server) ServeConn(c net.Conn, opts *http2ServeConnOpts) {
	baseCtx, cancel := http2serverConnBaseContext(c, opts)
	defer cancel()

	sc := &http2serverConn{
		srv:              s,
		hs:               opts.baseConfig(),
		conn:             c,
		baseCtx:          baseCtx,
		remoteAddrStr:    c.RemoteAddr().String(),
		bw:               http2newBufferedWriter(c),
		handler:          opts.handler(),
		streams:          make(map[uint32]*http2stream),
		readFrameCh:      make(chan http2readFrameResult),
		wantWriteFrameCh: make(chan http2frameWriteMsg, 8),
		wroteFrameCh:     make(chan http2frameWriteResult, 1),
		bodyReadCh:       make(chan http2bodyReadMsg),
		doneServing:      make(chan struct{}),
		advMaxStreams:    s.maxConcurrentStreams(),
		writeSched: http2writeScheduler{
			maxFrameSize: http2initialMaxFrameSize,
		initialWindowSize: http2initialWindowSize,
		headerTableSize:   http2initialHeaderTableSize,
		serveG:            http2newGoroutineLock(),
		pushEnabled:       true,

	sc.hpackEncoder = hpack.NewEncoder(&sc.headerWriteBuf)

	fr := http2NewFramer(, c)
	fr.ReadMetaHeaders = hpack.NewDecoder(http2initialHeaderTableSize, nil)
	fr.MaxHeaderListSize = sc.maxHeaderListSize()
	sc.framer = fr

	if tc, ok := c.(http2connectionStater); ok {
		sc.tlsState = new(tls.ConnectionState)
		*sc.tlsState = tc.ConnectionState()

		if sc.tlsState.Version < tls.VersionTLS12 {
			sc.rejectConn(http2ErrCodeInadequateSecurity, "TLS version too low")

		if sc.tlsState.ServerName == "" {


		if !s.PermitProhibitedCipherSuites && http2isBadCipher(sc.tlsState.CipherSuite) {

			sc.rejectConn(http2ErrCodeInadequateSecurity, fmt.Sprintf("Prohibited TLS 1.2 Cipher Suite: %x", sc.tlsState.CipherSuite))

	if hook := http2testHookGetServerConn; hook != nil {