Copyright 2014 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
TODO: turn off the serve goroutine when idle, so an idle conn only has the readFrames goroutine active. (which could also be optimized probably to pin less memory in crypto/tls). This would involve tracking when the serve goroutine is active (atomic int32 read/CAS probably?) and starting it up when frames arrive, and shutting it down when all handlers exit. the occasional PING packets could use time.AfterFunc to call sc.wakeStartServeLoop() (which is a no-op if already running) and then queue the PING write as normal. The serve loop would then exit in most cases (if no Handlers running) and not be woken up again until the PING packet returns.
TODO (maybe): add a mechanism for Handlers to going into half-closed-local mode (rw.(io.Closer) test?) but not exit their handler, and continue to be able to read from the Request.Body. This would be a somewhat semantic change from HTTP/1 (or at least what we expose in net/http), so I'd probably want to add it there too. For now, this package says that returning from the Handler ServeHTTP function means you're both done reading and done writing, without a way to stop just one or the other.

package http2

import (
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	

	
	
)

const (
	prefaceTimeout         = 10 * time.Second
	firstSettingsTimeout   = 2 * time.Second // should be in-flight with preface anyway
	handlerChunkWriteSize  = 4 << 10
	defaultMaxStreams      = 250 // TODO: make this 100 as the GFE seems to?
	maxQueuedControlFrames = 10000
)

var (
	errClientDisconnected = errors.New("client disconnected")
	errClosedBody         = errors.New("body closed by handler")
	errHandlerComplete    = errors.New("http2: request body closed due to handler exiting")
	errStreamClosed       = errors.New("http2: stream closed")
)

var responseWriterStatePool = sync.Pool{
	New: func() interface{} {
		 := &responseWriterState{}
		.bw = bufio.NewWriterSize(chunkWriter{}, handlerChunkWriteSize)
		return 
	},
}
Test hooks.
var (
	testHookOnConn        func()
	testHookGetServerConn func(*serverConn)
	testHookOnPanicMu     *sync.Mutex // nil except in tests
	testHookOnPanic       func(sc *serverConn, panicVal interface{}) (rePanic bool)
)
Server is an HTTP/2 server.
MaxHandlers limits the number of http.Handler ServeHTTP goroutines which may run at a time over all connections. Negative or zero no limit. TODO: implement
MaxConcurrentStreams optionally specifies the number of concurrent streams that each client may have open at a time. This is unrelated to the number of http.Handler goroutines which may be active globally, which is MaxHandlers. If zero, MaxConcurrentStreams defaults to at least 100, per the HTTP/2 spec's recommendations.
MaxReadFrameSize optionally specifies the largest frame this server is willing to read. A valid value is between 16k and 16M, inclusive. If zero or otherwise invalid, a default value is used.
PermitProhibitedCipherSuites, if true, permits the use of cipher suites prohibited by the HTTP/2 spec.
IdleTimeout specifies how long until idle clients should be closed with a GOAWAY frame. PING frames are not considered activity for the purposes of IdleTimeout.
MaxUploadBufferPerConnection is the size of the initial flow control window for each connections. The HTTP/2 spec does not allow this to be smaller than 65535 or larger than 2^32-1. If the value is outside this range, a default value will be used instead.
MaxUploadBufferPerStream is the size of the initial flow control window for each stream. The HTTP/2 spec does not allow this to be larger than 2^32-1. If the value is zero or larger than the maximum, a default value will be used instead.
NewWriteScheduler constructs a write scheduler for a connection. If nil, a default scheduler is chosen.
Internal state. This is a pointer (rather than embedded directly) so that we don't embed a Mutex in this struct, which will make the struct non-copyable, which might break some callers.
maxQueuedControlFrames is the maximum number of control frames like SETTINGS, PING and RST_STREAM that will be queued for writing before the connection is closed to prevent memory exhaustion attacks.
TODO: if anybody asks, add a Server field, and remember to define the behavior of negative values.
	return maxQueuedControlFrames
}

type serverInternalState struct {
	mu          sync.Mutex
	activeConns map[*serverConn]struct{}
}

func ( *serverInternalState) ( *serverConn) {
	if  == nil {
		return // if the Server was used without calling ConfigureServer
	}
	.mu.Lock()
	.activeConns[] = struct{}{}
	.mu.Unlock()
}

func ( *serverInternalState) ( *serverConn) {
	if  == nil {
		return // if the Server was used without calling ConfigureServer
	}
	.mu.Lock()
	delete(.activeConns, )
	.mu.Unlock()
}

func ( *serverInternalState) () {
	if  == nil {
		return // if the Server was used without calling ConfigureServer
	}
	.mu.Lock()
	for  := range .activeConns {
		.startGracefulShutdown()
	}
	.mu.Unlock()
}
ConfigureServer adds HTTP/2 support to a net/http Server. The configuration conf may be nil. ConfigureServer must be called before s begins serving.
func ( *http.Server,  *Server) error {
	if  == nil {
		panic("nil *http.Server")
	}
	if  == nil {
		 = new(Server)
	}
	.state = &serverInternalState{activeConns: make(map[*serverConn]struct{})}
	if ,  := , ; .IdleTimeout == 0 {
		if .IdleTimeout != 0 {
			.IdleTimeout = .IdleTimeout
		} else {
			.IdleTimeout = .ReadTimeout
		}
	}
	.RegisterOnShutdown(.state.startGracefulShutdown)

	if .TLSConfig == nil {
		.TLSConfig = new(tls.Config)
If they already provided a CipherSuite list, return an error if it has a bad order or is missing ECDHE_RSA_WITH_AES_128_GCM_SHA256 or ECDHE_ECDSA_WITH_AES_128_GCM_SHA256.
		 := false
		 := false
		for ,  := range .TLSConfig.CipherSuites {
			switch  {
Alternative MTI cipher to not discourage ECDSA-only servers. See http://golang.org/cl/30721 for further information.
				tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
				 = true
			}
			if isBadCipher() {
				 = true
			} else if  {
				return fmt.Errorf("http2: TLSConfig.CipherSuites index %d contains an HTTP/2-approved cipher suite (%#04x), but it comes after unapproved cipher suites. With this configuration, clients that don't support previous, approved cipher suites may be given an unapproved one and reject the connection.", , )
			}
		}
		if ! {
			return fmt.Errorf("http2: TLSConfig.CipherSuites is missing an HTTP/2-required AES_128_GCM_SHA256 cipher (need at least one of TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 or TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256).")
		}
	}
Note: not setting MinVersion to tls.VersionTLS12, as we don't want to interfere with HTTP/1.1 traffic on the user's server. We enforce TLS 1.2 later once we accept a connection. Ideally this should be done during next-proto selection, but using TLS <1.2 with HTTP/2 is still the client's bug.

	.TLSConfig.PreferServerCipherSuites = true

	 := false
	for ,  := range .TLSConfig.NextProtos {
		if  == NextProtoTLS {
			 = true
			break
		}
	}
	if ! {
		.TLSConfig.NextProtos = append(.TLSConfig.NextProtos, NextProtoTLS)
	}

	if .TLSNextProto == nil {
		.TLSNextProto = map[string]func(*http.Server, *tls.Conn, http.Handler){}
	}
	 := func( *http.Server,  *tls.Conn,  http.Handler) {
		if testHookOnConn != nil {
			testHookOnConn()
The TLSNextProto interface predates contexts, so the net/http package passes down its per-connection base context via an exported but unadvertised method on the Handler. This is for internal net/http<=>http2 use only.
		var  context.Context
		type  interface {
			() context.Context
		}
		if ,  := .();  {
			 = .()
		}
		.ServeConn(, &ServeConnOpts{
			Context:    ,
			Handler:    ,
			BaseConfig: ,
		})
	}
	.TLSNextProto[NextProtoTLS] = 
	return nil
}
ServeConnOpts are options for the Server.ServeConn method.
Context is the base context to use. If nil, context.Background is used.
BaseConfig optionally sets the base configuration for values. If nil, defaults are used.
Handler specifies which handler to use for processing requests. If nil, BaseConfig.Handler is used. If BaseConfig or BaseConfig.Handler is nil, http.DefaultServeMux is used.
	Handler http.Handler
}

func ( *ServeConnOpts) () context.Context {
	if  != nil && .Context != nil {
		return .Context
	}
	return context.Background()
}

func ( *ServeConnOpts) () *http.Server {
	if  != nil && .BaseConfig != nil {
		return .BaseConfig
	}
	return new(http.Server)
}

func ( *ServeConnOpts) () http.Handler {
	if  != nil {
		if .Handler != nil {
			return .Handler
		}
		if .BaseConfig != nil && .BaseConfig.Handler != nil {
			return .BaseConfig.Handler
		}
	}
	return http.DefaultServeMux
}
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.
func ( *Server) ( net.Conn,  *ServeConnOpts) {
	,  := serverConnBaseContext(, )
	defer ()

	 := &serverConn{
		srv:                         ,
		hs:                          .baseConfig(),
		conn:                        ,
		baseCtx:                     ,
		remoteAddrStr:               .RemoteAddr().String(),
		bw:                          newBufferedWriter(),
		handler:                     .handler(),
		streams:                     make(map[uint32]*stream),
		readFrameCh:                 make(chan readFrameResult),
		wantWriteFrameCh:            make(chan FrameWriteRequest, 8),
		serveMsgCh:                  make(chan interface{}, 8),
		wroteFrameCh:                make(chan frameWriteResult, 1), // buffered; one send in writeFrameAsync
		bodyReadCh:                  make(chan bodyReadMsg),         // buffering doesn't matter either way
		doneServing:                 make(chan struct{}),
		clientMaxStreams:            math.MaxUint32, // Section 6.5.2: "Initially, there is no limit to this value"
		advMaxStreams:               .maxConcurrentStreams(),
		initialStreamSendWindowSize: initialWindowSize,
		maxFrameSize:                initialMaxFrameSize,
		headerTableSize:             initialHeaderTableSize,
		serveG:                      newGoroutineLock(),
		pushEnabled:                 true,
	}

	.state.registerConn()
	defer .state.unregisterConn()
The net/http package sets the write deadline from the http.Server.WriteTimeout during the TLS handshake, but then passes the connection off to us with the deadline already set. Write deadlines are set per stream in serverConn.newStream. Disarm the net.Conn write deadline here.
These start at the RFC-specified defaults. If there is a higher configured value for inflow, that will be updated when we send a WINDOW_UPDATE shortly after sending SETTINGS.
9.2 Use of TLS Features An implementation of HTTP/2 over TLS MUST use TLS 1.2 or higher with the restrictions on feature set and cipher suite described in this section. Due to implementation limitations, it might not be possible to fail TLS negotiation. An endpoint MUST immediately terminate an HTTP/2 connection that does not meet the TLS requirements described in this section with a connection error (Section 5.4.1) of type INADEQUATE_SECURITY.
		if .tlsState.Version < tls.VersionTLS12 {
			.rejectConn(ErrCodeInadequateSecurity, "TLS version too low")
			return
		}

Client must use SNI, but we don't enforce that anymore, since it was causing problems when connecting to bare IP addresses during development. TODO: optionally enforce? Or enforce at the time we receive a new request, and verify the ServerName matches the :authority? But that precludes proxy situations, perhaps. So for now, do nothing here again.
		}

"Endpoints MAY choose to generate a connection error (Section 5.4.1) of type INADEQUATE_SECURITY if one of the prohibited cipher suites are negotiated." We choose that. In my opinion, the spec is weak here. It also says both parties must support at least TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 so there's no excuses here. If we really must, we could allow an "AllowInsecureWeakCiphers" option on the server later. Let's see how it plays out first.
			.rejectConn(ErrCodeInadequateSecurity, fmt.Sprintf("Prohibited TLS 1.2 Cipher Suite: %x", .tlsState.CipherSuite))
			return
		}
	}

	if  := testHookGetServerConn;  != nil {
		()
	}
	.serve()
}

func ( net.Conn,  *ServeConnOpts) ( context.Context,  func()) {
	,  = context.WithCancel(.context())
	 = context.WithValue(, http.LocalAddrContextKey, .LocalAddr())
	if  := .baseConfig();  != nil {
		 = context.WithValue(, http.ServerContextKey, )
	}
	return
}

func ( *serverConn) ( ErrCode,  string) {
ignoring errors. hanging up anyway.
	.framer.WriteGoAway(0, , []byte())
	.bw.Flush()
	.conn.Close()
}

Immutable:
	srv              *Server
	hs               *http.Server
	conn             net.Conn
	bw               *bufferedWriter // writing to conn
	handler          http.Handler
	baseCtx          context.Context
	framer           *Framer
	doneServing      chan struct{}          // closed when serverConn.serve ends
	readFrameCh      chan readFrameResult   // written by serverConn.readFrames
	wantWriteFrameCh chan FrameWriteRequest // from handlers -> serve
	wroteFrameCh     chan frameWriteResult  // from writeFrameAsync -> serve, tickles more frame writes
	bodyReadCh       chan bodyReadMsg       // from handlers -> serve
	serveMsgCh       chan interface{}       // misc messages & code to send to / run on the serve loop
	flow             flow                   // conn-wide (not stream-specific) outbound flow control
	inflow           flow                   // conn-wide inbound flow control
	tlsState         *tls.ConnectionState   // shared by all handlers, like net/http
	remoteAddrStr    string
	writeSched       WriteScheduler
Everything following is owned by the serve loop; use serveG.check():
	serveG                      goroutineLock // used to verify funcs are on serve()
	pushEnabled                 bool
	sawFirstSettings            bool // got the initial SETTINGS frame after the preface
	needToSendSettingsAck       bool
	unackedSettings             int    // how many SETTINGS have we sent without ACKs?
	queuedControlFrames         int    // control frames in the writeSched queue
	clientMaxStreams            uint32 // SETTINGS_MAX_CONCURRENT_STREAMS from client (our PUSH_PROMISE limit)
	advMaxStreams               uint32 // our SETTINGS_MAX_CONCURRENT_STREAMS advertised the client
	curClientStreams            uint32 // number of open streams initiated by the client
	curPushedStreams            uint32 // number of open streams initiated by server push
	maxClientStreamID           uint32 // max ever seen from client (odd), or 0 if there have been no client requests
	maxPushPromiseID            uint32 // ID of the last push promise (even), or 0 if there have been no pushes
	streams                     map[uint32]*stream
	initialStreamSendWindowSize int32
	maxFrameSize                int32
	headerTableSize             uint32
	peerMaxHeaderListSize       uint32            // zero means unknown (default)
	canonHeader                 map[string]string // http2-lower-case -> Go-Canonical-Case
	writingFrame                bool              // started writing a frame (on serve goroutine or separate)
	writingFrameAsync           bool              // started a frame on its own goroutine but haven't heard back on wroteFrameCh
	needsFrameFlush             bool              // last frame write wasn't a flush
	inGoAway                    bool              // we've started to or sent GOAWAY
	inFrameScheduleLoop         bool              // whether we're in the scheduleFrameWrite loop
	needToSendGoAway            bool              // we need to schedule a GOAWAY frame write
	goAwayCode                  ErrCode
	shutdownTimer               *time.Timer // nil until used
	idleTimer                   *time.Timer // nil if unused
Owned by the writeFrameAsync goroutine:
Used by startGracefulShutdown.
http2's count is in a slightly different unit and includes 32 bytes per pair. So, take the net/http.Server value and pad it up a bit, assuming 10 headers.
	const  = 32 // per http2 spec
	const  = 10   // conservative
	return uint32( + *)
}

func ( *serverConn) () uint32 {
	.serveG.check()
	return .curClientStreams + .curPushedStreams
}
stream represents a stream. This is the minimal metadata needed by the serve goroutine. Most of the actual stream state is owned by the http.Handler's goroutine in the responseWriter. Because the responseWriter's responseWriterState is recycled at the end of a handler, this struct intentionally has no pointer to the *responseWriter{,State} itself, as the Handler ending nils out the responseWriter's state field.
immutable:
	sc        *serverConn
	id        uint32
	body      *pipe       // non-nil if expecting DATA frames
	cw        closeWaiter // closed wait stream transitions to closed state
	ctx       context.Context
	cancelCtx func()
owned by serverConn's serve loop:
	bodyBytes        int64 // body bytes seen so far
	declBodyBytes    int64 // or -1 if undeclared
	flow             flow  // limits writing from Handler to client
	inflow           flow  // what the client is allowed to POST/etc to us
	state            streamState
	resetQueued      bool        // RST_STREAM queued for write; set by sc.resetStream
	gotTrailerHeader bool        // HEADER frame for trailers was seen
	wroteHeaders     bool        // whether we wrote headers (not status 100)
	writeDeadline    *time.Timer // nil if unused

	trailer    http.Header // accumulated trailers
	reqTrailer http.Header // handler's Request.Trailer
}

func ( *serverConn) () *Framer  { return .framer }
func ( *serverConn) () error { return .conn.Close() }
func ( *serverConn) () error     { return .bw.Flush() }
func ( *serverConn) () (*hpack.Encoder, *bytes.Buffer) {
	return .hpackEncoder, &.headerWriteBuf
}

func ( *serverConn) ( uint32) (streamState, *stream) {
http://tools.ietf.org/html/rfc7540#section-5.1
	if ,  := .streams[];  {
		return .state, 
"The first use of a new stream identifier implicitly closes all streams in the "idle" state that might have been initiated by that peer with a lower-valued stream identifier. For example, if a client sends a HEADERS frame on stream 7 without ever sending a frame on stream 5, then stream 5 transitions to the "closed" state when the first frame for stream 7 is sent or received."
	if %2 == 1 {
		if  <= .maxClientStreamID {
			return stateClosed, nil
		}
	} else {
		if  <= .maxPushPromiseID {
			return stateClosed, nil
		}
	}
	return stateIdle, nil
}
setConnState calls the net/http ConnState hook for this connection, if configured. Note that the net/http package does StateNew and StateClosed for us. There is currently no plan for StateHijacked or hijacking HTTP/2 connections.
func ( *serverConn) ( http.ConnState) {
	if .hs.ConnState != nil {
		.hs.ConnState(.conn, )
	}
}

func ( *serverConn) ( string,  ...interface{}) {
	if VerboseLogs {
		.logf(, ...)
	}
}

func ( *serverConn) ( string,  ...interface{}) {
	if  := .hs.ErrorLog;  != nil {
		.Printf(, ...)
	} else {
		log.Printf(, ...)
	}
}
errno returns v's underlying uintptr, else 0. TODO: remove this helper function once http2 can use build tags. See comment in isClosedConnError.
func ( error) uintptr {
	if  := reflect.ValueOf(); .Kind() == reflect.Uintptr {
		return uintptr(.Uint())
	}
	return 0
}
isClosedConnError reports whether err is an error from use of a closed network connection.
func ( error) bool {
	if  == nil {
		return false
	}
TODO: remove this string search and be more like the Windows case below. That might involve modifying the standard library to return better error types.
	 := .Error()
	if strings.Contains(, "use of closed network connection") {
		return true
	}
TODO(bradfitz): x/tools/cmd/bundle doesn't really support build tags, so I can't make an http2_windows.go file with Windows-specific stuff. Fix that and move this, once we have a way to bundle this into std's net/http somehow.
	if runtime.GOOS == "windows" {
		if ,  := .(*net.OpError);  && .Op == "read" {
			if ,  := .Err.(*os.SyscallError);  && .Syscall == "wsarecv" {
				const  = 10053
				const  = 10054
				if  := errno(.Err);  ==  ||  ==  {
					return true
				}
			}
		}
	}
	return false
}

func ( *serverConn) ( error,  string,  ...interface{}) {
	if  == nil {
		return
	}
Boring, expected errors.
		.vlogf(, ...)
	} else {
		.logf(, ...)
	}
}

func ( *serverConn) ( string) string {
	.serveG.check()
	buildCommonHeaderMapsOnce()
	,  := commonCanonHeader[]
	if  {
		return 
	}
	,  = .canonHeader[]
	if  {
		return 
	}
	if .canonHeader == nil {
		.canonHeader = make(map[string]string)
	}
	 = http.CanonicalHeaderKey()
	.canonHeader[] = 
	return 
}

type readFrameResult struct {
	f   Frame // valid until readMore is called
	err error
readMore should be called once the consumer no longer needs or retains f. After readMore, f is invalid and more frames can be read.
	readMore func()
}
readFrames is the loop that reads incoming frames. It takes care to only read one frame at a time, blocking until the consumer is done with the frame. It's run on its own goroutine.
func ( *serverConn) () {
	 := make(gate)
	 := .Done
	for {
		,  := .framer.ReadFrame()
		select {
		case .readFrameCh <- readFrameResult{, , }:
		case <-.doneServing:
			return
		}
		select {
		case <-:
		case <-.doneServing:
			return
		}
		if terminalReadFrameError() {
			return
		}
	}
}
frameWriteResult is the message passed from writeFrameAsync to the serve goroutine.
type frameWriteResult struct {
	_   incomparable
	wr  FrameWriteRequest // what was written (or attempted)
	err error             // result of the writeFrame call
}
writeFrameAsync runs in its own goroutine and writes a single frame and then reports when it's done. At most one goroutine can be running writeFrameAsync at a time per serverConn.
func ( *serverConn) ( FrameWriteRequest) {
	 := .write.writeFrame()
	.wroteFrameCh <- frameWriteResult{wr: , err: }
}

func ( *serverConn) () {
	.serveG.check()
	for ,  := range .streams {
		.closeStream(, errClientDisconnected)
	}
}

func ( *serverConn) () {
	.serveG.check()
	if  := .shutdownTimer;  != nil {
		.Stop()
	}
}

Note: this is for serverConn.serve panicking, not http.Handler code.
	if testHookOnPanicMu != nil {
		testHookOnPanicMu.Lock()
		defer testHookOnPanicMu.Unlock()
	}
	if testHookOnPanic != nil {
		if  := recover();  != nil {
			if testHookOnPanic(, ) {
				panic()
			}
		}
	}
}

func ( *serverConn) () {
	.serveG.check()
	defer .notePanic()
	defer .conn.Close()
	defer .closeAllStreamsOnConnClose()
	defer .stopShutdownTimer()
	defer close(.doneServing) // unblocks handlers trying to send

	if VerboseLogs {
		.vlogf("http2: server connection from %v on %p", .conn.RemoteAddr(), .hs)
	}

	.writeFrame(FrameWriteRequest{
		write: writeSettings{
			{SettingMaxFrameSize, .srv.maxReadFrameSize()},
			{SettingMaxConcurrentStreams, .advMaxStreams},
			{SettingMaxHeaderListSize, .maxHeaderListSize()},
			{SettingInitialWindowSize, uint32(.srv.initialStreamRecvWindowSize())},
		},
	})
	.unackedSettings++
Each connection starts with intialWindowSize inflow tokens. If a higher value is configured, we add more tokens.
	if  := .srv.initialConnRecvWindowSize() - initialWindowSize;  > 0 {
		.sendWindowUpdate(nil, int())
	}

	if  := .readPreface();  != nil {
		.condlogf(, "http2: server: error reading preface from client %v: %v", .conn.RemoteAddr(), )
		return
Now that we've got the preface, get us out of the "StateNew" state. We can't go directly to idle, though. Active means we read some data and anticipate a request. We'll do another Active when we get a HEADERS frame.
	.setConnState(http.StateActive)
	.setConnState(http.StateIdle)

	if .srv.IdleTimeout != 0 {
		.idleTimer = time.AfterFunc(.srv.IdleTimeout, .onIdleTimer)
		defer .idleTimer.Stop()
	}

	go .readFrames() // closed by defer sc.conn.Close above

	 := time.AfterFunc(firstSettingsTimeout, .onSettingsTimer)
	defer .Stop()

	 := 0
	for {
		++
		select {
		case  := <-.wantWriteFrameCh:
			if ,  := .write.(StreamError);  {
				.resetStream()
				break
			}
			.writeFrame()
		case  := <-.wroteFrameCh:
			.wroteFrame()
		case  := <-.readFrameCh:
			if !.processFrameFromReader() {
				return
			}
			.readMore()
			if  != nil {
				.Stop()
				 = nil
			}
		case  := <-.bodyReadCh:
			.noteBodyRead(.st, .n)
		case  := <-.serveMsgCh:
			switch v := .(type) {
			case func(int):
				() // for testing
			case *serverMessage:
				switch  {
				case settingsTimerMsg:
					.logf("timeout waiting for SETTINGS frames from %v", .conn.RemoteAddr())
					return
				case idleTimerMsg:
					.vlogf("connection is idle")
					.goAway(ErrCodeNo)
				case shutdownTimerMsg:
					.vlogf("GOAWAY close timer fired; closing conn from %v", .conn.RemoteAddr())
					return
				case gracefulShutdownMsg:
					.startGracefulShutdownInternal()
				default:
					panic("unknown timer")
				}
			case *startPushRequest:
				.startPush()
			default:
				panic(fmt.Sprintf("unexpected type %T", ))
			}
		}
If the peer is causing us to generate a lot of control frames, but not reading them from us, assume they are trying to make us run out of memory.
		if .queuedControlFrames > .srv.maxQueuedControlFrames() {
			.vlogf("http2: too many control frames in send queue, closing connection")
			return
		}
Start the shutdown timer after sending a GOAWAY. When sending GOAWAY with no error code (graceful shutdown), don't start the timer until all open streams have been completed.
		 := .inGoAway && !.needToSendGoAway && !.writingFrame
		 := .goAwayCode == ErrCodeNo && .curOpenStreams() == 0
		if  && .shutdownTimer == nil && (.goAwayCode != ErrCodeNo || ) {
			.shutDownIn(goAwayTimeout)
		}
	}
}

func ( *serverConn) ( <-chan struct{},  chan struct{}) {
	select {
	case <-.doneServing:
	case <-:
		close()
	}
}

type serverMessage int
Message values sent to serveMsgCh.
readPreface reads the ClientPreface greeting from the peer or returns errPrefaceTimeout on timeout, or an error if the greeting is invalid.
func ( *serverConn) () error {
	 := make(chan error, 1)
Read the client preface
		 := make([]byte, len(ClientPreface))
		if ,  := io.ReadFull(.conn, );  != nil {
			 <- 
		} else if !bytes.Equal(, clientPreface) {
			 <- fmt.Errorf("bogus greeting %q", )
		} else {
			 <- nil
		}
	}()
	 := time.NewTimer(prefaceTimeout) // TODO: configurable on *Server?
	defer .Stop()
	select {
	case <-.C:
		return errPrefaceTimeout
	case  := <-:
		if  == nil {
			if VerboseLogs {
				.vlogf("http2: server: client %v said hello", .conn.RemoteAddr())
			}
		}
		return 
	}
}

var errChanPool = sync.Pool{
	New: func() interface{} { return make(chan error, 1) },
}

var writeDataPool = sync.Pool{
	New: func() interface{} { return new(writeData) },
}
writeDataFromHandler writes DATA response frames from a handler on the given stream.
func ( *serverConn) ( *stream,  []byte,  bool) error {
	 := errChanPool.Get().(chan error)
	 := writeDataPool.Get().(*writeData)
	* = writeData{.id, , }
	 := .writeFrameFromHandler(FrameWriteRequest{
		write:  ,
		stream: ,
		done:   ,
	})
	if  != nil {
		return 
	}
	var  bool // the frame write is done (successfully or not)
	select {
	case  = <-:
		 = true
	case <-.doneServing:
		return errClientDisconnected
If both ch and stream.cw were ready (as might happen on the final Write after an http.Handler ends), prefer the write result. Otherwise this might just be us successfully closing the stream. The writeFrameAsync and serve goroutines guarantee that the ch send will happen before the stream.cw close.
		select {
		case  = <-:
			 = true
		default:
			return errStreamClosed
		}
	}
	errChanPool.Put()
	if  {
		writeDataPool.Put()
	}
	return 
}
writeFrameFromHandler sends wr to sc.wantWriteFrameCh, but aborts if the connection has gone away. This must not be run from the serve goroutine itself, else it might deadlock writing to sc.wantWriteFrameCh (which is only mildly buffered and is read by serve itself). If you're on the serve goroutine, call writeFrame instead.
Serve loop is gone. Client has closed their connection to the server.
writeFrame schedules a frame to write and sends it if there's nothing already being written. There is no pushback here (the serve goroutine never blocks). It's the http.Handlers that block, waiting for their previous frames to make it onto the wire If you're not on the serve goroutine, use writeFrameFromHandler instead.
If true, wr will not be written and wr.done will not be signaled.
	var  bool
We are not allowed to write frames on closed streams. RFC 7540 Section 5.1.1 says: "An endpoint MUST NOT send frames other than PRIORITY on a closed stream." Our server never sends PRIORITY, so that exception does not apply. The serverConn might close an open stream while the stream's handler is still running. For example, the server might close a stream when it receives bad data from the client. If this happens, the handler might attempt to write a frame after the stream has been closed (since the handler hasn't yet been notified of the close). In this case, we simply ignore the frame. The handler will notice that the stream is closed when it waits for the frame to be written. As an exception to this rule, we allow sending RST_STREAM after close. This allows us to immediately reject new streams without tracking any state for those streams (except for the queued RST_STREAM frame). This may result in duplicate RST_STREAMs in some cases, but the client should ignore those.
	if .StreamID() != 0 {
		,  := .write.(StreamError)
		if ,  := .state(.StreamID());  == stateClosed && ! {
			 = true
		}
	}
Don't send a 100-continue response if we've already sent headers. See golang.org/issue/14030.
We do not need to notify wr.done because this frame is never written with wr.done != nil.
			if .done != nil {
				panic("wr.done != nil for write100ContinueHeadersFrame")
			}
			 = true
		}
	}

	if ! {
		if .isControl() {
For extra safety, detect wraparounds, which should not happen, and pull the plug.
			if .queuedControlFrames < 0 {
				.conn.Close()
			}
		}
		.writeSched.Push()
	}
	.scheduleFrameWrite()
}
startFrameWrite starts a goroutine to write wr (in a separate goroutine since that might block on the network), and updates the serve goroutine's state about the world, updated from info in wr.
func ( *serverConn) ( FrameWriteRequest) {
	.serveG.check()
	if .writingFrame {
		panic("internal error: can only be writing one frame at a time")
	}

	 := .stream
	if  != nil {
		switch .state {
		case stateHalfClosedLocal:
			switch .write.(type) {
RFC 7540 Section 5.1 allows sending RST_STREAM, PRIORITY, and WINDOW_UPDATE in this state. (We never send PRIORITY from the server, so that is not checked.)
			default:
				panic(fmt.Sprintf("internal error: attempt to send frame on a half-closed-local stream: %v", ))
			}
		case stateClosed:
			panic(fmt.Sprintf("internal error: attempt to send frame on a closed stream: %v", ))
		}
	}
	if ,  := .write.(*writePushPromise);  {
		var  error
		.promisedID,  = .allocatePromisedID()
		if  != nil {
			.writingFrameAsync = false
			.replyToWriter()
			return
		}
	}

	.writingFrame = true
	.needsFrameFlush = true
	if .write.staysWithinBuffer(.bw.Available()) {
		.writingFrameAsync = false
		 := .write.writeFrame()
		.wroteFrame(frameWriteResult{wr: , err: })
	} else {
		.writingFrameAsync = true
		go .writeFrameAsync()
	}
}
errHandlerPanicked is the error given to any callers blocked in a read from Request.Body when the main goroutine panics. Since most handlers read in the main ServeHTTP goroutine, this will show up rarely.
var errHandlerPanicked = errors.New("http2: handler panicked")
wroteFrame is called on the serve goroutine with the result of whatever happened on writeFrameAsync.
func ( *serverConn) ( frameWriteResult) {
	.serveG.check()
	if !.writingFrame {
		panic("internal error: expected to be already writing a frame")
	}
	.writingFrame = false
	.writingFrameAsync = false

	 := .wr

	if writeEndsStream(.write) {
		 := .stream
		if  == nil {
			panic("internal error: expecting non-nil stream")
		}
		switch .state {
Here we would go to stateHalfClosedLocal in theory, but since our handler is done and the net/http package provides no mechanism for closing a ResponseWriter while still reading data (see possible TODO at top of this file), we go into closed state here anyway, after telling the peer we're hanging up on them. We'll transition to stateClosed after the RST_STREAM frame is written.
Section 8.1: a server MAY request that the client abort transmission of a request without error by sending a RST_STREAM with an error code of NO_ERROR after sending a complete response.
			.resetStream(streamError(.id, ErrCodeNo))
		case stateHalfClosedRemote:
			.closeStream(, errHandlerComplete)
		}
	} else {
		switch v := .write.(type) {
st may be unknown if the RST_STREAM was generated to reject bad input.
			if ,  := .streams[.StreamID];  {
				.closeStream(, )
			}
		case handlerPanicRST:
			.closeStream(.stream, errHandlerPanicked)
		}
	}
Reply (if requested) to unblock the ServeHTTP goroutine.
scheduleFrameWrite tickles the frame writing scheduler. If a frame is already being written, nothing happens. This will be called again when the frame is done being written. If a frame isn't being written and we need to send one, the best frame to send is selected by writeSched. If a frame isn't being written and there's nothing else to send, we flush the write buffer.
func ( *serverConn) () {
	.serveG.check()
	if .writingFrame || .inFrameScheduleLoop {
		return
	}
	.inFrameScheduleLoop = true
	for !.writingFrameAsync {
		if .needToSendGoAway {
			.needToSendGoAway = false
			.startFrameWrite(FrameWriteRequest{
				write: &writeGoAway{
					maxStreamID: .maxClientStreamID,
					code:        .goAwayCode,
				},
			})
			continue
		}
		if .needToSendSettingsAck {
			.needToSendSettingsAck = false
			.startFrameWrite(FrameWriteRequest{write: writeSettingsAck{}})
			continue
		}
		if !.inGoAway || .goAwayCode == ErrCodeNo {
			if ,  := .writeSched.Pop();  {
				if .isControl() {
					.queuedControlFrames--
				}
				.startFrameWrite()
				continue
			}
		}
		if .needsFrameFlush {
			.startFrameWrite(FrameWriteRequest{write: flushFrameWriter{}})
			.needsFrameFlush = false // after startFrameWrite, since it sets this true
			continue
		}
		break
	}
	.inFrameScheduleLoop = false
}
startGracefulShutdown gracefully shuts down a connection. This sends GOAWAY with ErrCodeNo to tell the client we're gracefully shutting down. The connection isn't closed until all current streams are done. startGracefulShutdown returns immediately; it does not wait until the connection has shut down.
After sending GOAWAY with an error code (non-graceful shutdown), the connection will close after goAwayTimeout. If we close the connection immediately after sending GOAWAY, there may be unsent data in our kernel receive buffer, which will cause the kernel to send a TCP RST on close() instead of a FIN. This RST will abort the connection immediately, whether or not the client had received the GOAWAY. Ideally we should delay for at least 1 RTT + epsilon so the client has a chance to read the GOAWAY and stop sending messages. Measuring RTT is hard, so we approximate with 1 second. See golang.org/issue/18701. This is a var so it can be shorter in tests, where all requests uses the loopback interface making the expected RTT very small. TODO: configurable?
processFrameFromReader processes the serve loop's read from readFrameCh from the frame-reading goroutine. processFrameFromReader returns whether the connection should be kept open.
func ( *serverConn) ( readFrameResult) bool {
	.serveG.check()
	 := .err
	if  != nil {
		if  == ErrFrameTooLarge {
			.goAway(ErrCodeFrameSize)
			return true // goAway will close the loop
		}
		 :=  == io.EOF ||  == io.ErrUnexpectedEOF || isClosedConnError()
TODO: could we also get into this state if the peer does a half close (e.g. CloseWrite) because they're done sending frames but they're still wanting our open replies? Investigate. TODO: add CloseWrite to crypto/tls.Conn first so we have a way to test this? I suppose just for testing we could have a non-TLS mode.
			return false
		}
	} else {
		 := .f
		if VerboseLogs {
			.vlogf("http2: server read frame %v", summarizeFrame())
		}
		 = .processFrame()
		if  == nil {
			return true
		}
	}

	switch ev := .(type) {
	case StreamError:
		.resetStream()
		return true
	case goAwayFlowError:
		.goAway(ErrCodeFlowControl)
		return true
	case ConnectionError:
		.logf("http2: server connection error from %v: %v", .conn.RemoteAddr(), )
		.goAway(ErrCode())
		return true // goAway will handle shutdown
	default:
		if .err != nil {
			.vlogf("http2: server closing client connection; error reading frame from client %s: %v", .conn.RemoteAddr(), )
		} else {
			.logf("http2: server closing client connection: %v", )
		}
		return false
	}
}

func ( *serverConn) ( Frame) error {
	.serveG.check()
First frame received must be SETTINGS.
	if !.sawFirstSettings {
		if ,  := .(*SettingsFrame); ! {
			return ConnectionError(ErrCodeProtocol)
		}
		.sawFirstSettings = true
	}

	switch f := .(type) {
	case *SettingsFrame:
		return .processSettings()
	case *MetaHeadersFrame:
		return .processHeaders()
	case *WindowUpdateFrame:
		return .processWindowUpdate()
	case *PingFrame:
		return .processPing()
	case *DataFrame:
		return .processData()
	case *RSTStreamFrame:
		return .processResetStream()
	case *PriorityFrame:
		return .processPriority()
	case *GoAwayFrame:
		return .processGoAway()
A client cannot push. Thus, servers MUST treat the receipt of a PUSH_PROMISE frame as a connection error (Section 5.4.1) of type PROTOCOL_ERROR.
		return ConnectionError(ErrCodeProtocol)
	default:
		.vlogf("http2: server ignoring frame: %v", .Header())
		return nil
	}
}

func ( *serverConn) ( *PingFrame) error {
	.serveG.check()
6.7 PING: " An endpoint MUST NOT respond to PING frames containing this flag."
		return nil
	}
"PING frames are not associated with any individual stream. If a PING frame is received with a stream identifier field value other than 0x0, the recipient MUST respond with a connection error (Section 5.4.1) of type PROTOCOL_ERROR."
		return ConnectionError(ErrCodeProtocol)
	}
	if .inGoAway && .goAwayCode != ErrCodeNo {
		return nil
	}
	.writeFrame(FrameWriteRequest{write: writePingAck{}})
	return nil
}

func ( *serverConn) ( *WindowUpdateFrame) error {
	.serveG.check()
	switch {
	case .StreamID != 0: // stream-level flow control
		,  := .state(.StreamID)
Section 5.1: "Receiving any frame other than HEADERS or PRIORITY on a stream in this state MUST be treated as a connection error (Section 5.4.1) of type PROTOCOL_ERROR."
"WINDOW_UPDATE can be sent by a peer that has sent a frame bearing the END_STREAM flag. This means that a receiver could receive a WINDOW_UPDATE frame on a "half closed (remote)" or "closed" stream. A receiver MUST NOT treat this as an error, see Section 5.1."
			return nil
		}
		if !.flow.add(int32(.Increment)) {
			return streamError(.StreamID, ErrCodeFlowControl)
		}
	default: // connection-level flow control
		if !.flow.add(int32(.Increment)) {
			return goAwayFlowError{}
		}
	}
	.scheduleFrameWrite()
	return nil
}

func ( *serverConn) ( *RSTStreamFrame) error {
	.serveG.check()

	,  := .state(.StreamID)
6.4 "RST_STREAM frames MUST NOT be sent for a stream in the "idle" state. If a RST_STREAM frame identifying an idle stream is received, the recipient MUST treat this as a connection error (Section 5.4.1) of type PROTOCOL_ERROR.
		return ConnectionError(ErrCodeProtocol)
	}
	if  != nil {
		.cancelCtx()
		.closeStream(, streamError(.StreamID, .ErrCode))
	}
	return nil
}

func ( *serverConn) ( *stream,  error) {
	.serveG.check()
	if .state == stateIdle || .state == stateClosed {
		panic(fmt.Sprintf("invariant; can't close stream in state %v", .state))
	}
	.state = stateClosed
	if .writeDeadline != nil {
		.writeDeadline.Stop()
	}
	if .isPushed() {
		.curPushedStreams--
	} else {
		.curClientStreams--
	}
	delete(.streams, .id)
	if len(.streams) == 0 {
		.setConnState(http.StateIdle)
		if .srv.IdleTimeout != 0 {
			.idleTimer.Reset(.srv.IdleTimeout)
		}
		if h1ServerKeepAlivesDisabled(.hs) {
			.startGracefulShutdownInternal()
		}
	}
Return any buffered unread bytes worth of conn-level flow control. See golang.org/issue/16481
		.sendWindowUpdate(nil, .Len())

		.CloseWithError()
	}
	.cw.Close() // signals Handler's CloseNotifier, unblocks writes, etc
	.writeSched.CloseStream(.id)
}

func ( *serverConn) ( *SettingsFrame) error {
	.serveG.check()
	if .IsAck() {
		.unackedSettings--
Why is the peer ACKing settings we never sent? The spec doesn't mention this case, but hang up on them anyway.
			return ConnectionError(ErrCodeProtocol)
		}
		return nil
	}
This isn't actually in the spec, but hang up on suspiciously large settings frames or those with duplicate entries.
		return ConnectionError(ErrCodeProtocol)
	}
	if  := .ForeachSetting(.processSetting);  != nil {
		return 
TODO: judging by RFC 7540, Section 6.5.3 each SETTINGS frame should be acknowledged individually, even if multiple are received before the ACK.
	.needToSendSettingsAck = true
	.scheduleFrameWrite()
	return nil
}

func ( *serverConn) ( Setting) error {
	.serveG.check()
	if  := .Valid();  != nil {
		return 
	}
	if VerboseLogs {
		.vlogf("http2: server processing setting %v", )
	}
	switch .ID {
	case SettingHeaderTableSize:
		.headerTableSize = .Val
		.hpackEncoder.SetMaxDynamicTableSize(.Val)
	case SettingEnablePush:
		.pushEnabled = .Val != 0
	case SettingMaxConcurrentStreams:
		.clientMaxStreams = .Val
	case SettingInitialWindowSize:
		return .processSettingInitialWindowSize(.Val)
	case SettingMaxFrameSize:
		.maxFrameSize = int32(.Val) // the maximum valid s.Val is < 2^31
	case SettingMaxHeaderListSize:
		.peerMaxHeaderListSize = .Val
Unknown setting: "An endpoint that receives a SETTINGS frame with any unknown or unsupported identifier MUST ignore that setting."
		if VerboseLogs {
			.vlogf("http2: server ignoring unknown setting %v", )
		}
	}
	return nil
}

func ( *serverConn) ( uint32) error {
Note: val already validated to be within range by processSetting's Valid call.
"A SETTINGS frame can alter the initial flow control window size for all current streams. When the value of SETTINGS_INITIAL_WINDOW_SIZE changes, a receiver MUST adjust the size of all stream flow control windows that it maintains by the difference between the new value and the old value."
	 := .initialStreamSendWindowSize
	.initialStreamSendWindowSize = int32()
	 := int32() -  // may be negative
	for ,  := range .streams {
6.9.2 Initial Flow Control Window Size "An endpoint MUST treat a change to SETTINGS_INITIAL_WINDOW_SIZE that causes any flow control window to exceed the maximum size as a connection error (Section 5.4.1) of type FLOW_CONTROL_ERROR."
			return ConnectionError(ErrCodeFlowControl)
		}
	}
	return nil
}

func ( *serverConn) ( *DataFrame) error {
	.serveG.check()
	 := .Header().StreamID
Discard all DATA frames if the GOAWAY is due to an error, or: Section 6.8: After sending a GOAWAY frame, the sender can discard frames for streams initiated by the receiver with identifiers higher than the identified last stream.
		return nil
	}

	 := .Data()
	,  := .state()
Section 6.1: "DATA frames MUST be associated with a stream. If a DATA frame is received whose stream identifier field is 0x0, the recipient MUST respond with a connection error (Section 5.4.1) of type PROTOCOL_ERROR." Section 5.1: "Receiving any frame other than HEADERS or PRIORITY on a stream in this state MUST be treated as a connection error (Section 5.4.1) of type PROTOCOL_ERROR."
"If a DATA frame is received whose stream is not in "open" or "half closed (local)" state, the recipient MUST respond with a stream error (Section 5.4.2) of type STREAM_CLOSED."
This includes sending a RST_STREAM if the stream is in stateHalfClosedLocal (which currently means that the http.Handler returned, so it's done reading & done writing). Try to stop the client from sending more DATA.
But still enforce their connection-level flow control, and return any flow control bytes since we're not going to consume them.
Deduct the flow control from inflow, since we're going to immediately add it back in sendWindowUpdate, which also schedules sending the frames.
		.inflow.take(int32(.Length))
		.sendWindowUpdate(nil, int(.Length)) // conn-level

Already have a stream error in flight. Don't send another.
			return nil
		}
		return streamError(, ErrCodeStreamClosed)
	}
	if .body == nil {
		panic("internal error: should have a body in this state")
	}
Sender sending more than they'd declared?
	if .declBodyBytes != -1 && .bodyBytes+int64(len()) > .declBodyBytes {
RFC 7540, sec 8.1.2.6: A request or response is also malformed if the value of a content-length header field does not equal the sum of the DATA frame payload lengths that form the body.
Check whether the client has flow control quota.
		if .inflow.available() < int32(.Length) {
			return streamError(, ErrCodeFlowControl)
		}
		.inflow.take(int32(.Length))

		if len() > 0 {
			,  := .body.Write()
			if  != nil {
				.sendWindowUpdate(nil, int(.Length)-)
				return streamError(, ErrCodeStreamClosed)
			}
			if  != len() {
				panic("internal error: bad Writer")
			}
			.bodyBytes += int64(len())
		}
Return any padded flow control now, since we won't refund it later on body reads.
		if  := int32(.Length) - int32(len());  > 0 {
			.sendWindowUpdate32(nil, )
			.sendWindowUpdate32(, )
		}
	}
	if .StreamEnded() {
		.endStream()
	}
	return nil
}

func ( *serverConn) ( *GoAwayFrame) error {
	.serveG.check()
	if .ErrCode != ErrCodeNo {
		.logf("http2: received GOAWAY %+v, starting graceful shutdown", )
	} else {
		.vlogf("http2: received GOAWAY %+v, starting graceful shutdown", )
	}
http://tools.ietf.org/html/rfc7540#section-6.8 We should not create any new streams, which means we should disable push.
	.pushEnabled = false
	return nil
}
isPushed reports whether the stream is server-initiated.
func ( *stream) () bool {
	return .id%2 == 0
}
endStream closes a Request.Body's pipe. It is called when a DATA frame says a request body is over (or after trailers).
func ( *stream) () {
	 := .sc
	.serveG.check()

	if .declBodyBytes != -1 && .declBodyBytes != .bodyBytes {
		.body.CloseWithError(fmt.Errorf("request declared a Content-Length of %d but only wrote %d bytes",
			.declBodyBytes, .bodyBytes))
	} else {
		.body.closeWithErrorAndCode(io.EOF, .copyTrailersToHandlerRequest)
		.body.CloseWithError(io.EOF)
	}
	.state = stateHalfClosedRemote
}
copyTrailersToHandlerRequest is run in the Handler's goroutine in its Request.Body.Read just before it gets io.EOF.
func ( *stream) () {
	for ,  := range .trailer {
Only copy it over it was pre-declared.
			.reqTrailer[] = 
		}
	}
}
onWriteTimeout is run on its own goroutine (from time.AfterFunc) when the stream's WriteTimeout has fired.
Ignore.
		return nil
http://tools.ietf.org/html/rfc7540#section-5.1.1 Streams initiated by a client MUST use odd-numbered stream identifiers. [...] An endpoint that receives an unexpected stream identifier MUST respond with a connection error (Section 5.4.1) of type PROTOCOL_ERROR.
	if %2 != 1 {
		return ConnectionError(ErrCodeProtocol)
A HEADERS frame can be used to create a new stream or send a trailer for an open one. If we already have a stream open, let it process its own HEADERS frame (trailers at this point, if it's valid).
	if  := .streams[.StreamID];  != nil {
We're sending RST_STREAM to close the stream, so don't bother processing this frame.
			return nil
RFC 7540, sec 5.1: If an endpoint receives additional frames, other than WINDOW_UPDATE, PRIORITY, or RST_STREAM, for a stream that is in this state, it MUST respond with a stream error (Section 5.4.2) of type STREAM_CLOSED.
[...] The identifier of a newly established stream MUST be numerically greater than all streams that the initiating endpoint has opened or reserved. [...] An endpoint that receives an unexpected stream identifier MUST respond with a connection error (Section 5.4.1) of type PROTOCOL_ERROR.
http://tools.ietf.org/html/rfc7540#section-5.1.2 [...] Endpoints MUST NOT exceed the limit set by their peer. An endpoint that receives a HEADERS frame that causes their advertised concurrent stream limit to be exceeded MUST treat this as a stream error (Section 5.4.2) of type PROTOCOL_ERROR or REFUSED_STREAM.
They should know better.
Assume it's a network race, where they just haven't received our last SETTINGS update. But actually this can't happen yet, because we don't yet provide a way for users to adjust server parameters at runtime.
		return streamError(, ErrCodeRefusedStream)
	}

	 := stateOpen
	if .StreamEnded() {
		 = stateHalfClosedRemote
	}
	 := .newStream(, 0, )

	if .HasPriority() {
		if  := checkPriority(.StreamID, .Priority);  != nil {
			return 
		}
		.writeSched.AdjustStream(.id, .Priority)
	}

	, ,  := .newWriterAndRequest(, )
	if  != nil {
		return 
	}
	.reqTrailer = .Trailer
	if .reqTrailer != nil {
		.trailer = make(http.Header)
	}
	.body = .Body.(*requestBody).pipe // may be nil
	.declBodyBytes = .ContentLength

	 := .handler.ServeHTTP
Their header list was too long. Send a 431 error.
		 = handleHeaderListTooLong
	} else if  := checkValidHTTP2RequestHeaders(.Header);  != nil {
		 = new400Handler()
	}
The net/http package sets the read deadline from the http.Server.ReadTimeout during the TLS handshake, but then passes the connection off to us with the deadline already set. Disarm it here after the request headers are read, similar to how the http1 server works. Here it's technically more like the http1 Server's ReadHeaderTimeout (in Go 1.8), though. That's a more sane option anyway.
	if .hs.ReadTimeout != 0 {
		.conn.SetReadDeadline(time.Time{})
	}

	go .runHandler(, , )
	return nil
}

func ( *stream) ( *MetaHeadersFrame) error {
	 := .sc
	.serveG.check()
	if .gotTrailerHeader {
		return ConnectionError(ErrCodeProtocol)
	}
	.gotTrailerHeader = true
	if !.StreamEnded() {
		return streamError(.id, ErrCodeProtocol)
	}

	if len(.PseudoFields()) > 0 {
		return streamError(.id, ErrCodeProtocol)
	}
	if .trailer != nil {
		for ,  := range .RegularFields() {
			 := .canonicalHeader(.Name)
TODO: send more details to the peer somehow. But http2 has no way to send debug data at a stream level. Discuss with HTTP folk.
				return streamError(.id, ErrCodeProtocol)
			}
			.trailer[] = append(.trailer[], .Value)
		}
	}
	.endStream()
	return nil
}

func ( uint32,  PriorityParam) error {
Section 5.3.1: "A stream cannot depend on itself. An endpoint MUST treat this as a stream error (Section 5.4.2) of type PROTOCOL_ERROR." Section 5.3.3 says that a stream can depend on one of its dependencies, so it's only self-dependencies that are forbidden.
		return streamError(, ErrCodeProtocol)
	}
	return nil
}

func ( *serverConn) ( *PriorityFrame) error {
	if .inGoAway {
		return nil
	}
	if  := checkPriority(.StreamID, .PriorityParam);  != nil {
		return 
	}
	.writeSched.AdjustStream(.StreamID, .PriorityParam)
	return nil
}

func ( *serverConn) (,  uint32,  streamState) *stream {
	.serveG.check()
	if  == 0 {
		panic("internal error: cannot create stream with id 0")
	}

	,  := context.WithCancel(.baseCtx)
	 := &stream{
		sc:        ,
		id:        ,
		state:     ,
		ctx:       ,
		cancelCtx: ,
	}
	.cw.Init()
	.flow.conn = &.flow // link to conn-level counter
	.flow.add(.initialStreamSendWindowSize)
	.inflow.conn = &.inflow // link to conn-level counter
	.inflow.add(.srv.initialStreamRecvWindowSize())
	if .hs.WriteTimeout != 0 {
		.writeDeadline = time.AfterFunc(.hs.WriteTimeout, .onWriteTimeout)
	}

	.streams[] = 
	.writeSched.OpenStream(.id, OpenStreamOptions{PusherID: })
	if .isPushed() {
		.curPushedStreams++
	} else {
		.curClientStreams++
	}
	if .curOpenStreams() == 1 {
		.setConnState(http.StateActive)
	}

	return 
}

func ( *serverConn) ( *stream,  *MetaHeadersFrame) (*responseWriter, *http.Request, error) {
	.serveG.check()

	 := requestParam{
		method:    .PseudoValue("method"),
		scheme:    .PseudoValue("scheme"),
		authority: .PseudoValue("authority"),
		path:      .PseudoValue("path"),
	}

	 := .method == "CONNECT"
	if  {
		if .path != "" || .scheme != "" || .authority == "" {
			return nil, nil, streamError(.StreamID, ErrCodeProtocol)
		}
See 8.1.2.6 Malformed Requests and Responses: Malformed requests or responses that are detected MUST be treated as a stream error (Section 5.4.2) of type PROTOCOL_ERROR." 8.1.2.3 Request Pseudo-Header Fields "All HTTP/2 requests MUST include exactly one valid value for the :method, :scheme, and :path pseudo-header fields"
		return nil, nil, streamError(.StreamID, ErrCodeProtocol)
	}

	 := !.StreamEnded()
HEAD requests can't have bodies
		return nil, nil, streamError(.StreamID, ErrCodeProtocol)
	}

	.header = make(http.Header)
	for ,  := range .RegularFields() {
		.header.Add(.canonicalHeader(.Name), .Value)
	}
	if .authority == "" {
		.authority = .header.Get("Host")
	}

	, ,  := .newWriterAndRequestNoBody(, )
	if  != nil {
		return nil, nil, 
	}
	if  {
		if ,  := .header["Content-Length"];  {
			if ,  := strconv.ParseUint([0], 10, 63);  == nil {
				.ContentLength = int64()
			} else {
				.ContentLength = 0
			}
		} else {
			.ContentLength = -1
		}
		.Body.(*requestBody).pipe = &pipe{
			b: &dataBuffer{expected: .ContentLength},
		}
	}
	return , , nil
}

type requestParam struct {
	method                  string
	scheme, authority, path string
	header                  http.Header
}

func ( *serverConn) ( *stream,  requestParam) (*responseWriter, *http.Request, error) {
	.serveG.check()

	var  *tls.ConnectionState // nil if not scheme https
	if .scheme == "https" {
		 = .tlsState
	}

	 := .header.Get("Expect") == "100-continue"
	if  {
		.header.Del("Expect")
Merge Cookie headers into one "; "-delimited value.
	if  := .header["Cookie"]; len() > 1 {
		.header.Set("Cookie", strings.Join(, "; "))
	}
Setup Trailers
	var  http.Header
	for ,  := range .header["Trailer"] {
		for ,  := range strings.Split(, ",") {
			 = http.CanonicalHeaderKey(textproto.TrimString())
			switch  {
Bogus. (copy of http1 rules) Ignore.
			default:
				if  == nil {
					 = make(http.Header)
				}
				[] = nil
			}
		}
	}
	delete(.header, "Trailer")

	var  *url.URL
	var  string
	if .method == "CONNECT" {
		 = &url.URL{Host: .authority}
		 = .authority // mimic HTTP/1 server behavior
	} else {
		var  error
		,  = url.ParseRequestURI(.path)
		if  != nil {
			return nil, nil, streamError(.id, ErrCodeProtocol)
		}
		 = .path
	}

	 := &requestBody{
		conn:          ,
		stream:        ,
		needsContinue: ,
	}
	 := &http.Request{
		Method:     .method,
		URL:        ,
		RemoteAddr: .remoteAddrStr,
		Header:     .header,
		RequestURI: ,
		Proto:      "HTTP/2.0",
		ProtoMajor: 2,
		ProtoMinor: 0,
		TLS:        ,
		Host:       .authority,
		Body:       ,
		Trailer:    ,
	}
	 = .WithContext(.ctx)

	 := responseWriterStatePool.Get().(*responseWriterState)
	 := .bw
	* = responseWriterState{} // zero all the fields
	.conn = 
	.bw = 
	.bw.Reset(chunkWriter{})
	.stream = 
	.req = 
	.body = 

	 := &responseWriter{rws: }
	return , , nil
}
Run on its own goroutine.
func ( *serverConn) ( *responseWriter,  *http.Request,  func(http.ResponseWriter, *http.Request)) {
	 := true
	defer func() {
		.rws.stream.cancelCtx()
		if  {
			 := recover()
			.writeFrameFromHandler(FrameWriteRequest{
				write:  handlerPanicRST{.rws.stream.id},
				stream: .rws.stream,
Same as net/http:
			if  != nil &&  != http.ErrAbortHandler {
				const  = 64 << 10
				 := make([]byte, )
				 = [:runtime.Stack(, false)]
				.logf("http2: panic serving %v: %v\n%s", .conn.RemoteAddr(), , )
			}
			return
		}
		.handlerDone()
	}()
	(, )
	 = false
}

10.5.1 Limits on Header Block Size: .. "A server that receives a larger header block than it is willing to handle can send an HTTP 431 (Request Header Fields Too Large) status code"
	const  = 431 // only in Go 1.6+
	.WriteHeader()
	io.WriteString(, "<h1>HTTP Error 431</h1><p>Request Header Field(s) Too Large</p>")
}
called from handler goroutines. h may be nil.
func ( *serverConn) ( *stream,  *writeResHeaders) error {
	.serveG.checkNotOn() // NOT on
	var  chan error
If there's a header map (which we don't own), so we have to block on waiting for this frame to be written, so an http.Flush mid-handler writes out the correct value of keys, before a handler later potentially mutates it.
		 = errChanPool.Get().(chan error)
	}
	if  := .writeFrameFromHandler(FrameWriteRequest{
		write:  ,
		stream: ,
		done:   ,
	});  != nil {
		return 
	}
	if  != nil {
		select {
		case  := <-:
			errChanPool.Put()
			return 
		case <-.doneServing:
			return errClientDisconnected
		case <-.cw:
			return errStreamClosed
		}
	}
	return nil
}
called from handler goroutines.
A bodyReadMsg tells the server loop that the http.Handler read n bytes of the DATA from the client on the given stream.
type bodyReadMsg struct {
	st *stream
	n  int
}
called from handler goroutines. Notes that the handler for the given stream ID read n bytes of its body and schedules flow control tokens to be sent.
func ( *serverConn) ( *stream,  int,  error) {
	.serveG.checkNotOn() // NOT on
	if  > 0 {
		select {
		case .bodyReadCh <- bodyReadMsg{, }:
		case <-.doneServing:
		}
	}
}

func ( *serverConn) ( *stream,  int) {
	.serveG.check()
	.sendWindowUpdate(nil, ) // conn-level
Don't send this WINDOW_UPDATE if the stream is closed remotely.
		.sendWindowUpdate(, )
	}
}
st may be nil for conn-level
func ( *serverConn) ( *stream,  int) {
"The legal range for the increment to the flow control window is 1 to 2^31-1 (2,147,483,647) octets." A Go Read call on 64-bit machines could in theory read a larger Read than this. Very unlikely, but we handle it here rather than elsewhere for now.
	const  = 1<<31 - 1
	for  >=  {
		.sendWindowUpdate32(, )
		 -= 
	}
	.sendWindowUpdate32(, int32())
}
st may be nil for conn-level
func ( *serverConn) ( *stream,  int32) {
	.serveG.check()
	if  == 0 {
		return
	}
	if  < 0 {
		panic("negative update")
	}
	var  uint32
	if  != nil {
		 = .id
	}
	.writeFrame(FrameWriteRequest{
		write:  writeWindowUpdate{streamID: , n: uint32()},
		stream: ,
	})
	var  bool
	if  == nil {
		 = .inflow.add()
	} else {
		 = .inflow.add()
	}
	if ! {
		panic("internal error; sent too many window updates without decrements?")
	}
}
requestBody is the Handler's Request.Body type. Read and Close may be called concurrently.
type requestBody struct {
	_             incomparable
	stream        *stream
	conn          *serverConn
	closed        bool  // for use by Close only
	sawEOF        bool  // for use by Read only
	pipe          *pipe // non-nil if we have a HTTP entity message body
	needsContinue bool  // need to send a 100-continue
}

func ( *requestBody) () error {
	if .pipe != nil && !.closed {
		.pipe.BreakWithError(errClosedBody)
	}
	.closed = true
	return nil
}

func ( *requestBody) ( []byte) ( int,  error) {
	if .needsContinue {
		.needsContinue = false
		.conn.write100ContinueHeaders(.stream)
	}
	if .pipe == nil || .sawEOF {
		return 0, io.EOF
	}
	,  = .pipe.Read()
	if  == io.EOF {
		.sawEOF = true
	}
	if .conn == nil && inTests {
		return
	}
	.conn.noteBodyReadFromHandler(.stream, , )
	return
}
responseWriter is the http.ResponseWriter implementation. It's intentionally small (1 pointer wide) to minimize garbage. The responseWriterState pointer inside is zeroed at the end of a request (in handlerDone) and calls on the responseWriter thereafter simply crash (caller's mistake), but the much larger responseWriterState and buffers are reused between multiple requests.
Optional http.ResponseWriter interfaces implemented.
immutable within a request:
	stream *stream
	req    *http.Request
	body   *requestBody // to close at end of request, if DATA frames didn't
	conn   *serverConn
TODO: adjust buffer writing sizes based on server config, frame size updates from peer, etc
	bw *bufio.Writer // writing to a chunkWriter{this *responseWriterState}
mutated by http.Handler goroutine:
	handlerHeader http.Header // nil until called
	snapHeader    http.Header // snapshot of handlerHeader at WriteHeader time
	trailers      []string    // set in writeChunk
	status        int         // status code passed to WriteHeader
	wroteHeader   bool        // WriteHeader called (explicitly or implicitly). Not necessarily sent to user yet.
	sentHeader    bool        // have we sent the header frame?
	handlerDone   bool        // handler has finished
	dirty         bool        // a Write failed; don't reuse this responseWriterState

	sentContentLen int64 // non-zero if handler set a Content-Length header
	wroteBytes     int64

	closeNotifierMu sync.Mutex // guards closeNotifierCh
	closeNotifierCh chan bool  // nil until first used
}

type chunkWriter struct{ rws *responseWriterState }

func ( chunkWriter) ( []byte) ( int,  error) { return .rws.writeChunk() }

func ( *responseWriterState) () bool { return len(.trailers) > 0 }

func ( *responseWriterState) () bool {
	for ,  := range .trailers {
		if ,  := .handlerHeader[];  {
			return true
		}
	}
	return false
}
declareTrailer is called for each Trailer header when the response header is written. It notes that a header will need to be written in the trailers at the end of the response.
Forbidden by RFC 7230, section 4.1.2.
		.conn.logf("ignoring invalid trailer %q", )
		return
	}
	if !strSliceContains(.trailers, ) {
		.trailers = append(.trailers, )
	}
}
writeChunk writes chunks from the bufio.Writer. But because bufio.Writer may bypass its chunking, sometimes p may be arbitrarily large. writeChunk is also responsible (on the first chunk) for sending the HEADER response.
func ( *responseWriterState) ( []byte) ( int,  error) {
	if !.wroteHeader {
		.writeHeader(200)
	}

	 := .req.Method == "HEAD"
	if !.sentHeader {
		.sentHeader = true
		var ,  string
		if  = .snapHeader.Get("Content-Length");  != "" {
			.snapHeader.Del("Content-Length")
			if ,  := strconv.ParseUint(, 10, 63);  == nil {
				.sentContentLen = int64()
			} else {
				 = ""
			}
		}
		if  == "" && .handlerDone && bodyAllowedForStatus(.status) && (len() > 0 || !) {
			 = strconv.Itoa(len())
		}
If the Content-Encoding is non-blank, we shouldn't sniff the body. See Issue golang.org/issue/31753.
		 := .snapHeader.Get("Content-Encoding")
		 := len() > 0
		if ! && ! && bodyAllowedForStatus(.status) && len() > 0 {
			 = http.DetectContentType()
		}
		var  string
TODO(bradfitz): be faster here, like net/http? measure.
			 = time.Now().UTC().Format(http.TimeFormat)
		}

		for ,  := range .snapHeader["Trailer"] {
			foreachHeaderElement(, .declareTrailer)
		}
"Connection" headers aren't allowed in HTTP/2 (RFC 7540, 8.1.2.2), but respect "Connection" == "close" to mean sending a GOAWAY and tearing down the TCP connection when idle, like we do for HTTP/1. TODO: remove more Connection-specific header fields here, in addition to "Connection".
		if ,  := .snapHeader["Connection"];  {
			 := .snapHeader.Get("Connection")
			delete(.snapHeader, "Connection")
			if  == "close" {
				.conn.startGracefulShutdown()
			}
		}

		 := (.handlerDone && !.hasTrailers() && len() == 0) || 
		 = .conn.writeHeaders(.stream, &writeResHeaders{
			streamID:      .stream.id,
			httpResCode:   .status,
			h:             .snapHeader,
			endStream:     ,
			contentType:   ,
			contentLength: ,
			date:          ,
		})
		if  != nil {
			.dirty = true
			return 0, 
		}
		if  {
			return 0, nil
		}
	}
	if  {
		return len(), nil
	}
	if len() == 0 && !.handlerDone {
		return 0, nil
	}

	if .handlerDone {
		.promoteUndeclaredTrailers()
	}
only send trailers if they have actually been defined by the server handler.
	 := .hasNonemptyTrailers()
	 := .handlerDone && !
only send a 0 byte DATA frame if we're ending the stream.
		if  := .conn.writeDataFromHandler(.stream, , );  != nil {
			.dirty = true
			return 0, 
		}
	}

	if .handlerDone &&  {
		 = .conn.writeHeaders(.stream, &writeResHeaders{
			streamID:  .stream.id,
			h:         .handlerHeader,
			trailers:  .trailers,
			endStream: true,
		})
		if  != nil {
			.dirty = true
		}
		return len(), 
	}
	return len(), nil
}
TrailerPrefix is a magic prefix for ResponseWriter.Header map keys that, if present, signals that the map entry is actually for the response trailers, and not the response headers. The prefix is stripped after the ServeHTTP call finishes and the values are sent in the trailers. This mechanism is intended only for trailers that are not known prior to the headers being written. If the set of trailers is fixed or known before the header is written, the normal Go trailers mechanism is preferred: https://golang.org/pkg/net/http/#ResponseWriter https://golang.org/pkg/net/http/#example_ResponseWriter_trailers
const TrailerPrefix = "Trailer:"
promoteUndeclaredTrailers permits http.Handlers to set trailers after the header has already been flushed. Because the Go ResponseWriter interface has no way to set Trailers (only the Header), and because we didn't want to expand the ResponseWriter interface, and because nobody used trailers, and because RFC 7230 says you SHOULD (but not must) predeclare any trailers in the header, the official ResponseWriter rules said trailers in Go must be predeclared, and then we reuse the same ResponseWriter.Header() map to mean both Headers and Trailers. When it's time to write the Trailers, we pick out the fields of Headers that were declared as trailers. That worked for a while, until we found the first major user of Trailers in the wild: gRPC (using them only over http2), and gRPC libraries permit setting trailers mid-stream without predeclaring them. So: change of plans. We still permit the old way, but we also permit this hack: if a Header() key begins with "Trailer:", the suffix of that key is a Trailer. Because ':' is an invalid token byte anyway, there is no ambiguity. (And it's already filtered out) It's mildly hacky, but not terrible. This method runs after the Handler is done and promotes any Header fields to be trailers.
func ( *responseWriterState) () {
	for ,  := range .handlerHeader {
		if !strings.HasPrefix(, TrailerPrefix) {
			continue
		}
		 := strings.TrimPrefix(, TrailerPrefix)
		.declareTrailer()
		.handlerHeader[http.CanonicalHeaderKey()] = 
	}

	if len(.trailers) > 1 {
		 := sorterPool.Get().(*sorter)
		.SortStrings(.trailers)
		sorterPool.Put()
	}
}

func ( *responseWriter) () {
	 := .rws
	if  == nil {
		panic("Header called after Handler finished")
	}
	if .bw.Buffered() > 0 {
Ignore the error. The frame writer already knows.
			return
		}
The bufio.Writer won't call chunkWriter.Write (writeChunk with zero bytes, so we have to do it ourselves to force the HTTP response header and/or final DATA frame (with END_STREAM) to be sent.
		.writeChunk(nil)
	}
}

func ( *responseWriter) () <-chan bool {
	 := .rws
	if  == nil {
		panic("CloseNotify called after Handler finished")
	}
	.closeNotifierMu.Lock()
	 := .closeNotifierCh
	if  == nil {
		 = make(chan bool, 1)
		.closeNotifierCh = 
		 := .stream.cw
		go func() {
			.Wait() // wait for close
			 <- true
		}()
	}
	.closeNotifierMu.Unlock()
	return 
}

func ( *responseWriter) () http.Header {
	 := .rws
	if  == nil {
		panic("Header called after Handler finished")
	}
	if .handlerHeader == nil {
		.handlerHeader = make(http.Header)
	}
	return .handlerHeader
}
checkWriteHeaderCode is a copy of net/http's checkWriteHeaderCode.
Issue 22880: require valid WriteHeader status codes. For now we only enforce that it's three digits. In the future we might block things over 599 (600 and above aren't defined at http://httpwg.org/specs/rfc7231.html#status.codes) and we might block under 200 (once we have more mature 1xx support). But for now any three digits. We used to send "HTTP/1.1 000 0" on the wire in responses but there's no equivalent bogus thing we can realistically send in HTTP/2, so we'll consistently panic instead and help people find their bugs early. (We can't return an error from WriteHeader even if we wanted to.)
	if  < 100 ||  > 999 {
		panic(fmt.Sprintf("invalid WriteHeader code %v", ))
	}
}

func ( *responseWriter) ( int) {
	 := .rws
	if  == nil {
		panic("WriteHeader called after Handler finished")
	}
	.writeHeader()
}

func ( *responseWriterState) ( int) {
	if !.wroteHeader {
		checkWriteHeaderCode()
		.wroteHeader = true
		.status = 
		if len(.handlerHeader) > 0 {
			.snapHeader = cloneHeader(.handlerHeader)
		}
	}
}

func ( http.Header) http.Header {
	 := make(http.Header, len())
	for ,  := range  {
		 := make([]string, len())
		copy(, )
		[] = 
	}
	return 
}
The Life Of A Write is like this: * Handler calls w.Write or w.WriteString -> * -> rws.bw (*bufio.Writer) -> * (Handler might call Flush) * -> chunkWriter{rws} * -> responseWriterState.writeChunk(p []byte) * -> responseWriterState.writeChunk (most of the magic; see comment there)
func ( *responseWriter) ( []byte) ( int,  error) {
	return .write(len(), , "")
}

func ( *responseWriter) ( string) ( int,  error) {
	return .write(len(), nil, )
}
either dataB or dataS is non-zero.
func ( *responseWriter) ( int,  []byte,  string) ( int,  error) {
	 := .rws
	if  == nil {
		panic("Write called after Handler finished")
	}
	if !.wroteHeader {
		.WriteHeader(200)
	}
	if !bodyAllowedForStatus(.status) {
		return 0, http.ErrBodyNotAllowed
	}
	.wroteBytes += int64(len()) + int64(len()) // only one can be set
TODO: send a RST_STREAM
		return 0, errors.New("http2: handler wrote more than declared Content-Length")
	}

	if  != nil {
		return .bw.Write()
	} else {
		return .bw.WriteString()
	}
}

func ( *responseWriter) () {
	 := .rws
	 := .dirty
	.handlerDone = true
	.Flush()
	.rws = nil
Only recycle the pool if all prior Write calls to the serverConn goroutine completed successfully. If they returned earlier due to resets from the peer there might still be write goroutines outstanding from the serverConn referencing the rws memory. See issue 20704.
Push errors.
var (
	ErrRecursivePush    = errors.New("http2: recursive push not allowed")
	ErrPushLimitReached = errors.New("http2: push would exceed peer's SETTINGS_MAX_CONCURRENT_STREAMS")
)

var _ http.Pusher = (*responseWriter)(nil)

func ( *responseWriter) ( string,  *http.PushOptions) error {
	 := .rws.stream
	 := .sc
	.serveG.checkNotOn()
No recursive pushes: "PUSH_PROMISE frames MUST only be sent on a peer-initiated stream." http://tools.ietf.org/html/rfc7540#section-6.6
	if .isPushed() {
		return ErrRecursivePush
	}

	if  == nil {
		 = new(http.PushOptions)
	}
Default options.
	if .Method == "" {
		.Method = "GET"
	}
	if .Header == nil {
		.Header = http.Header{}
	}
	 := "http"
	if .rws.req.TLS != nil {
		 = "https"
	}
Validate the request.
	,  := url.Parse()
	if  != nil {
		return 
	}
	if .Scheme == "" {
		if !strings.HasPrefix(, "/") {
			return fmt.Errorf("target must be an absolute URL or an absolute path: %q", )
		}
		.Scheme = 
		.Host = .rws.req.Host
	} else {
		if .Scheme !=  {
			return fmt.Errorf("cannot push URL with scheme %q from request with scheme %q", .Scheme, )
		}
		if .Host == "" {
			return errors.New("URL must have a host")
		}
	}
	for  := range .Header {
		if strings.HasPrefix(, ":") {
			return fmt.Errorf("promised request headers cannot include pseudo header %q", )
These headers are meaningful only if the request has a body, but PUSH_PROMISE requests cannot have a body. http://tools.ietf.org/html/rfc7540#section-8.2 Also disallow Host, since the promised URL must be absolute.
		switch strings.ToLower() {
		case "content-length", "content-encoding", "trailer", "te", "expect", "host":
			return fmt.Errorf("promised request headers cannot include %q", )
		}
	}
	if  := checkValidHTTP2RequestHeaders(.Header);  != nil {
		return 
	}
The RFC effectively limits promised requests to GET and HEAD: "Promised requests MUST be cacheable [GET, HEAD, or POST], and MUST be safe [GET or HEAD]" http://tools.ietf.org/html/rfc7540#section-8.2
	if .Method != "GET" && .Method != "HEAD" {
		return fmt.Errorf("method %q must be GET or HEAD", .Method)
	}

	 := &startPushRequest{
		parent: ,
		method: .Method,
		url:    ,
		header: cloneHeader(.Header),
		done:   errChanPool.Get().(chan error),
	}

	select {
	case <-.doneServing:
		return errClientDisconnected
	case <-.cw:
		return errStreamClosed
	case .serveMsgCh <- :
	}

	select {
	case <-.doneServing:
		return errClientDisconnected
	case <-.cw:
		return errStreamClosed
	case  := <-.done:
		errChanPool.Put(.done)
		return 
	}
}

type startPushRequest struct {
	parent *stream
	method string
	url    *url.URL
	header http.Header
	done   chan error
}

func ( *serverConn) ( *startPushRequest) {
	.serveG.check()
http://tools.ietf.org/html/rfc7540#section-6.6. PUSH_PROMISE frames MUST only be sent on a peer-initiated stream that is in either the "open" or "half-closed (remote)" state.
responseWriter.Push checks that the stream is peer-initiated.
		.done <- errStreamClosed
		return
	}
http://tools.ietf.org/html/rfc7540#section-6.6.
	if !.pushEnabled {
		.done <- http.ErrNotSupported
		return
	}
PUSH_PROMISE frames must be sent in increasing order by stream ID, so we allocate an ID for the promised stream lazily, when the PUSH_PROMISE is written. Once the ID is allocated, we start the request handler.
	 := func() (uint32, error) {
		.serveG.check()
Check this again, just in case. Technically, we might have received an updated SETTINGS by the time we got around to writing this frame.
		if !.pushEnabled {
			return 0, http.ErrNotSupported
http://tools.ietf.org/html/rfc7540#section-6.5.2.
http://tools.ietf.org/html/rfc7540#section-5.1.1. Streams initiated by the server MUST use even-numbered identifiers. A server that is unable to establish a new stream identifier can send a GOAWAY frame so that the client is forced to open a new connection for new streams.
		if .maxPushPromiseID+2 >= 1<<31 {
			.startGracefulShutdownInternal()
			return 0, ErrPushLimitReached
		}
		.maxPushPromiseID += 2
		 := .maxPushPromiseID
http://tools.ietf.org/html/rfc7540#section-8.2. Strictly speaking, the new stream should start in "reserved (local)", then transition to "half closed (remote)" after sending the initial HEADERS, but we start in "half closed (remote)" for simplicity. See further comments at the definition of stateHalfClosedRemote.
		 := .newStream(, .parent.id, stateHalfClosedRemote)
		, ,  := .newWriterAndRequestNoBody(, requestParam{
			method:    .method,
			scheme:    .url.Scheme,
			authority: .url.Host,
			path:      .url.RequestURI(),
			header:    cloneHeader(.header), // clone since handler runs concurrently with writing the PUSH_PROMISE
		})
Should not happen, since we've already validated msg.url.
			panic(fmt.Sprintf("newWriterAndRequestNoBody(%+v): %v", .url, ))
		}

		go .runHandler(, , .handler.ServeHTTP)
		return , nil
	}

	.writeFrame(FrameWriteRequest{
		write: &writePushPromise{
			streamID:           .parent.id,
			method:             .method,
			url:                .url,
			h:                  .header,
			allocatePromisedID: ,
		},
		stream: .parent,
		done:   .done,
	})
}
foreachHeaderElement splits v according to the "#rule" construction in RFC 7230 section 7 and calls fn for each non-empty element.
func ( string,  func(string)) {
	 = textproto.TrimString()
	if  == "" {
		return
	}
	if !strings.Contains(, ",") {
		()
		return
	}
	for ,  := range strings.Split(, ",") {
		if  = textproto.TrimString();  != "" {
			()
		}
	}
}
From http://httpwg.org/specs/rfc7540.html#rfc.section.8.1.2.2
var connHeaders = []string{
	"Connection",
	"Keep-Alive",
	"Proxy-Connection",
	"Transfer-Encoding",
	"Upgrade",
}
checkValidHTTP2RequestHeaders checks whether h is a valid HTTP/2 request, per RFC 7540 Section 8.1.2.2. The returned error is reported to users.
func ( http.Header) error {
	for ,  := range connHeaders {
		if ,  := [];  {
			return fmt.Errorf("request header %q is not valid in HTTP/2", )
		}
	}
	 := ["Te"]
	if len() > 0 && (len() > 1 || ([0] != "trailers" && [0] != "")) {
		return errors.New(`request header "TE" may only be "trailers" in HTTP/2`)
	}
	return nil
}

func ( error) http.HandlerFunc {
	return func( http.ResponseWriter,  *http.Request) {
		http.Error(, .Error(), http.StatusBadRequest)
	}
}
h1ServerKeepAlivesDisabled reports whether hs has its keep-alives disabled. See comments on h1ServerShutdownChan above for why the code is written this way.
func ( *http.Server) bool {
	var  interface{} = 
	type  interface {
		() bool
	}
	if ,  := .();  {
		return !.()
	}
	return false