blob: b640deb0e0aac7ad4041131e44388cbac5dfe946 [file] [log] [blame]
khenaidooac637102019-01-14 15:44:34 -05001// Copyright 2014 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// TODO: turn off the serve goroutine when idle, so
6// an idle conn only has the readFrames goroutine active. (which could
7// also be optimized probably to pin less memory in crypto/tls). This
8// would involve tracking when the serve goroutine is active (atomic
9// int32 read/CAS probably?) and starting it up when frames arrive,
10// and shutting it down when all handlers exit. the occasional PING
11// packets could use time.AfterFunc to call sc.wakeStartServeLoop()
12// (which is a no-op if already running) and then queue the PING write
13// as normal. The serve loop would then exit in most cases (if no
14// Handlers running) and not be woken up again until the PING packet
15// returns.
16
17// TODO (maybe): add a mechanism for Handlers to going into
18// half-closed-local mode (rw.(io.Closer) test?) but not exit their
19// handler, and continue to be able to read from the
20// Request.Body. This would be a somewhat semantic change from HTTP/1
21// (or at least what we expose in net/http), so I'd probably want to
22// add it there too. For now, this package says that returning from
23// the Handler ServeHTTP function means you're both done reading and
24// done writing, without a way to stop just one or the other.
25
26package http2
27
28import (
29 "bufio"
30 "bytes"
31 "context"
mgouda64be8822025-05-30 10:44:00 +053032 "crypto/rand"
khenaidooac637102019-01-14 15:44:34 -050033 "crypto/tls"
34 "errors"
35 "fmt"
36 "io"
37 "log"
38 "math"
39 "net"
40 "net/http"
41 "net/textproto"
42 "net/url"
43 "os"
44 "reflect"
45 "runtime"
46 "strconv"
47 "strings"
48 "sync"
49 "time"
50
51 "golang.org/x/net/http/httpguts"
52 "golang.org/x/net/http2/hpack"
mgouda64be8822025-05-30 10:44:00 +053053 "golang.org/x/net/internal/httpcommon"
khenaidooac637102019-01-14 15:44:34 -050054)
55
56const (
mgouda64be8822025-05-30 10:44:00 +053057 prefaceTimeout = 10 * time.Second
58 firstSettingsTimeout = 2 * time.Second // should be in-flight with preface anyway
59 handlerChunkWriteSize = 4 << 10
60 defaultMaxStreams = 250 // TODO: make this 100 as the GFE seems to?
61
62 // maxQueuedControlFrames is the maximum number of control frames like
63 // SETTINGS, PING and RST_STREAM that will be queued for writing before
64 // the connection is closed to prevent memory exhaustion attacks.
Scott Baker8461e152019-10-01 14:44:30 -070065 maxQueuedControlFrames = 10000
khenaidooac637102019-01-14 15:44:34 -050066)
67
68var (
69 errClientDisconnected = errors.New("client disconnected")
70 errClosedBody = errors.New("body closed by handler")
71 errHandlerComplete = errors.New("http2: request body closed due to handler exiting")
72 errStreamClosed = errors.New("http2: stream closed")
73)
74
75var responseWriterStatePool = sync.Pool{
76 New: func() interface{} {
77 rws := &responseWriterState{}
78 rws.bw = bufio.NewWriterSize(chunkWriter{rws}, handlerChunkWriteSize)
79 return rws
80 },
81}
82
83// Test hooks.
84var (
85 testHookOnConn func()
86 testHookGetServerConn func(*serverConn)
87 testHookOnPanicMu *sync.Mutex // nil except in tests
88 testHookOnPanic func(sc *serverConn, panicVal interface{}) (rePanic bool)
89)
90
91// Server is an HTTP/2 server.
92type Server struct {
93 // MaxHandlers limits the number of http.Handler ServeHTTP goroutines
94 // which may run at a time over all connections.
95 // Negative or zero no limit.
96 // TODO: implement
97 MaxHandlers int
98
99 // MaxConcurrentStreams optionally specifies the number of
100 // concurrent streams that each client may have open at a
101 // time. This is unrelated to the number of http.Handler goroutines
102 // which may be active globally, which is MaxHandlers.
103 // If zero, MaxConcurrentStreams defaults to at least 100, per
104 // the HTTP/2 spec's recommendations.
105 MaxConcurrentStreams uint32
106
mgouda64be8822025-05-30 10:44:00 +0530107 // MaxDecoderHeaderTableSize optionally specifies the http2
108 // SETTINGS_HEADER_TABLE_SIZE to send in the initial settings frame. It
109 // informs the remote endpoint of the maximum size of the header compression
110 // table used to decode header blocks, in octets. If zero, the default value
111 // of 4096 is used.
112 MaxDecoderHeaderTableSize uint32
113
114 // MaxEncoderHeaderTableSize optionally specifies an upper limit for the
115 // header compression table used for encoding request headers. Received
116 // SETTINGS_HEADER_TABLE_SIZE settings are capped at this limit. If zero,
117 // the default value of 4096 is used.
118 MaxEncoderHeaderTableSize uint32
119
khenaidooac637102019-01-14 15:44:34 -0500120 // MaxReadFrameSize optionally specifies the largest frame
121 // this server is willing to read. A valid value is between
122 // 16k and 16M, inclusive. If zero or otherwise invalid, a
123 // default value is used.
124 MaxReadFrameSize uint32
125
126 // PermitProhibitedCipherSuites, if true, permits the use of
127 // cipher suites prohibited by the HTTP/2 spec.
128 PermitProhibitedCipherSuites bool
129
130 // IdleTimeout specifies how long until idle clients should be
131 // closed with a GOAWAY frame. PING frames are not considered
132 // activity for the purposes of IdleTimeout.
mgouda64be8822025-05-30 10:44:00 +0530133 // If zero or negative, there is no timeout.
khenaidooac637102019-01-14 15:44:34 -0500134 IdleTimeout time.Duration
135
mgouda64be8822025-05-30 10:44:00 +0530136 // ReadIdleTimeout is the timeout after which a health check using a ping
137 // frame will be carried out if no frame is received on the connection.
138 // If zero, no health check is performed.
139 ReadIdleTimeout time.Duration
140
141 // PingTimeout is the timeout after which the connection will be closed
142 // if a response to a ping is not received.
143 // If zero, a default of 15 seconds is used.
144 PingTimeout time.Duration
145
146 // WriteByteTimeout is the timeout after which a connection will be
147 // closed if no data can be written to it. The timeout begins when data is
148 // available to write, and is extended whenever any bytes are written.
149 // If zero or negative, there is no timeout.
150 WriteByteTimeout time.Duration
151
khenaidooac637102019-01-14 15:44:34 -0500152 // MaxUploadBufferPerConnection is the size of the initial flow
153 // control window for each connections. The HTTP/2 spec does not
154 // allow this to be smaller than 65535 or larger than 2^32-1.
155 // If the value is outside this range, a default value will be
156 // used instead.
157 MaxUploadBufferPerConnection int32
158
159 // MaxUploadBufferPerStream is the size of the initial flow control
160 // window for each stream. The HTTP/2 spec does not allow this to
161 // be larger than 2^32-1. If the value is zero or larger than the
162 // maximum, a default value will be used instead.
163 MaxUploadBufferPerStream int32
164
165 // NewWriteScheduler constructs a write scheduler for a connection.
166 // If nil, a default scheduler is chosen.
167 NewWriteScheduler func() WriteScheduler
168
mgouda64be8822025-05-30 10:44:00 +0530169 // CountError, if non-nil, is called on HTTP/2 server errors.
170 // It's intended to increment a metric for monitoring, such
171 // as an expvar or Prometheus metric.
172 // The errType consists of only ASCII word characters.
173 CountError func(errType string)
174
khenaidooac637102019-01-14 15:44:34 -0500175 // Internal state. This is a pointer (rather than embedded directly)
176 // so that we don't embed a Mutex in this struct, which will make the
177 // struct non-copyable, which might break some callers.
178 state *serverInternalState
mgouda64be8822025-05-30 10:44:00 +0530179
180 // Synchronization group used for testing.
181 // Outside of tests, this is nil.
182 group synctestGroupInterface
khenaidooac637102019-01-14 15:44:34 -0500183}
184
mgouda64be8822025-05-30 10:44:00 +0530185func (s *Server) markNewGoroutine() {
186 if s.group != nil {
187 s.group.Join()
khenaidooac637102019-01-14 15:44:34 -0500188 }
khenaidooac637102019-01-14 15:44:34 -0500189}
190
mgouda64be8822025-05-30 10:44:00 +0530191func (s *Server) now() time.Time {
192 if s.group != nil {
193 return s.group.Now()
khenaidooac637102019-01-14 15:44:34 -0500194 }
mgouda64be8822025-05-30 10:44:00 +0530195 return time.Now()
khenaidooac637102019-01-14 15:44:34 -0500196}
197
mgouda64be8822025-05-30 10:44:00 +0530198// newTimer creates a new time.Timer, or a synthetic timer in tests.
199func (s *Server) newTimer(d time.Duration) timer {
200 if s.group != nil {
201 return s.group.NewTimer(d)
khenaidooac637102019-01-14 15:44:34 -0500202 }
mgouda64be8822025-05-30 10:44:00 +0530203 return timeTimer{time.NewTimer(d)}
khenaidooac637102019-01-14 15:44:34 -0500204}
205
mgouda64be8822025-05-30 10:44:00 +0530206// afterFunc creates a new time.AfterFunc timer, or a synthetic timer in tests.
207func (s *Server) afterFunc(d time.Duration, f func()) timer {
208 if s.group != nil {
209 return s.group.AfterFunc(d, f)
khenaidooac637102019-01-14 15:44:34 -0500210 }
mgouda64be8822025-05-30 10:44:00 +0530211 return timeTimer{time.AfterFunc(d, f)}
Scott Baker8461e152019-10-01 14:44:30 -0700212}
213
khenaidooac637102019-01-14 15:44:34 -0500214type serverInternalState struct {
215 mu sync.Mutex
216 activeConns map[*serverConn]struct{}
217}
218
219func (s *serverInternalState) registerConn(sc *serverConn) {
220 if s == nil {
221 return // if the Server was used without calling ConfigureServer
222 }
223 s.mu.Lock()
224 s.activeConns[sc] = struct{}{}
225 s.mu.Unlock()
226}
227
228func (s *serverInternalState) unregisterConn(sc *serverConn) {
229 if s == nil {
230 return // if the Server was used without calling ConfigureServer
231 }
232 s.mu.Lock()
233 delete(s.activeConns, sc)
234 s.mu.Unlock()
235}
236
237func (s *serverInternalState) startGracefulShutdown() {
238 if s == nil {
239 return // if the Server was used without calling ConfigureServer
240 }
241 s.mu.Lock()
242 for sc := range s.activeConns {
243 sc.startGracefulShutdown()
244 }
245 s.mu.Unlock()
246}
247
248// ConfigureServer adds HTTP/2 support to a net/http Server.
249//
250// The configuration conf may be nil.
251//
252// ConfigureServer must be called before s begins serving.
253func ConfigureServer(s *http.Server, conf *Server) error {
254 if s == nil {
255 panic("nil *http.Server")
256 }
257 if conf == nil {
258 conf = new(Server)
259 }
260 conf.state = &serverInternalState{activeConns: make(map[*serverConn]struct{})}
261 if h1, h2 := s, conf; h2.IdleTimeout == 0 {
262 if h1.IdleTimeout != 0 {
263 h2.IdleTimeout = h1.IdleTimeout
264 } else {
265 h2.IdleTimeout = h1.ReadTimeout
266 }
267 }
268 s.RegisterOnShutdown(conf.state.startGracefulShutdown)
269
270 if s.TLSConfig == nil {
271 s.TLSConfig = new(tls.Config)
khenaidood948f772021-08-11 17:49:24 -0400272 } else if s.TLSConfig.CipherSuites != nil && s.TLSConfig.MinVersion < tls.VersionTLS13 {
273 // If they already provided a TLS 1.0–1.2 CipherSuite list, return an
274 // error if it is missing ECDHE_RSA_WITH_AES_128_GCM_SHA256 or
275 // ECDHE_ECDSA_WITH_AES_128_GCM_SHA256.
khenaidooac637102019-01-14 15:44:34 -0500276 haveRequired := false
khenaidood948f772021-08-11 17:49:24 -0400277 for _, cs := range s.TLSConfig.CipherSuites {
khenaidooac637102019-01-14 15:44:34 -0500278 switch cs {
279 case tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
280 // Alternative MTI cipher to not discourage ECDSA-only servers.
281 // See http://golang.org/cl/30721 for further information.
282 tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
283 haveRequired = true
284 }
khenaidooac637102019-01-14 15:44:34 -0500285 }
286 if !haveRequired {
khenaidood948f772021-08-11 17:49:24 -0400287 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)")
khenaidooac637102019-01-14 15:44:34 -0500288 }
289 }
290
291 // Note: not setting MinVersion to tls.VersionTLS12,
292 // as we don't want to interfere with HTTP/1.1 traffic
293 // on the user's server. We enforce TLS 1.2 later once
294 // we accept a connection. Ideally this should be done
295 // during next-proto selection, but using TLS <1.2 with
296 // HTTP/2 is still the client's bug.
297
298 s.TLSConfig.PreferServerCipherSuites = true
299
khenaidood948f772021-08-11 17:49:24 -0400300 if !strSliceContains(s.TLSConfig.NextProtos, NextProtoTLS) {
khenaidooac637102019-01-14 15:44:34 -0500301 s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, NextProtoTLS)
302 }
khenaidood948f772021-08-11 17:49:24 -0400303 if !strSliceContains(s.TLSConfig.NextProtos, "http/1.1") {
304 s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, "http/1.1")
305 }
khenaidooac637102019-01-14 15:44:34 -0500306
307 if s.TLSNextProto == nil {
308 s.TLSNextProto = map[string]func(*http.Server, *tls.Conn, http.Handler){}
309 }
mgouda64be8822025-05-30 10:44:00 +0530310 protoHandler := func(hs *http.Server, c net.Conn, h http.Handler, sawClientPreface bool) {
khenaidooac637102019-01-14 15:44:34 -0500311 if testHookOnConn != nil {
312 testHookOnConn()
313 }
Scott Baker8461e152019-10-01 14:44:30 -0700314 // The TLSNextProto interface predates contexts, so
315 // the net/http package passes down its per-connection
316 // base context via an exported but unadvertised
317 // method on the Handler. This is for internal
318 // net/http<=>http2 use only.
319 var ctx context.Context
320 type baseContexter interface {
321 BaseContext() context.Context
322 }
323 if bc, ok := h.(baseContexter); ok {
324 ctx = bc.BaseContext()
325 }
khenaidooac637102019-01-14 15:44:34 -0500326 conf.ServeConn(c, &ServeConnOpts{
mgouda64be8822025-05-30 10:44:00 +0530327 Context: ctx,
328 Handler: h,
329 BaseConfig: hs,
330 SawClientPreface: sawClientPreface,
khenaidooac637102019-01-14 15:44:34 -0500331 })
332 }
mgouda64be8822025-05-30 10:44:00 +0530333 s.TLSNextProto[NextProtoTLS] = func(hs *http.Server, c *tls.Conn, h http.Handler) {
334 protoHandler(hs, c, h, false)
335 }
336 // The "unencrypted_http2" TLSNextProto key is used to pass off non-TLS HTTP/2 conns.
337 //
338 // A connection passed in this method has already had the HTTP/2 preface read from it.
339 s.TLSNextProto[nextProtoUnencryptedHTTP2] = func(hs *http.Server, c *tls.Conn, h http.Handler) {
340 nc, err := unencryptedNetConnFromTLSConn(c)
341 if err != nil {
342 if lg := hs.ErrorLog; lg != nil {
343 lg.Print(err)
344 } else {
345 log.Print(err)
346 }
347 go c.Close()
348 return
349 }
350 protoHandler(hs, nc, h, true)
351 }
khenaidooac637102019-01-14 15:44:34 -0500352 return nil
353}
354
355// ServeConnOpts are options for the Server.ServeConn method.
356type ServeConnOpts struct {
Scott Baker8461e152019-10-01 14:44:30 -0700357 // Context is the base context to use.
358 // If nil, context.Background is used.
359 Context context.Context
360
khenaidooac637102019-01-14 15:44:34 -0500361 // BaseConfig optionally sets the base configuration
362 // for values. If nil, defaults are used.
363 BaseConfig *http.Server
364
365 // Handler specifies which handler to use for processing
366 // requests. If nil, BaseConfig.Handler is used. If BaseConfig
367 // or BaseConfig.Handler is nil, http.DefaultServeMux is used.
368 Handler http.Handler
mgouda64be8822025-05-30 10:44:00 +0530369
370 // UpgradeRequest is an initial request received on a connection
371 // undergoing an h2c upgrade. The request body must have been
372 // completely read from the connection before calling ServeConn,
373 // and the 101 Switching Protocols response written.
374 UpgradeRequest *http.Request
375
376 // Settings is the decoded contents of the HTTP2-Settings header
377 // in an h2c upgrade request.
378 Settings []byte
379
380 // SawClientPreface is set if the HTTP/2 connection preface
381 // has already been read from the connection.
382 SawClientPreface bool
khenaidooac637102019-01-14 15:44:34 -0500383}
384
Scott Baker8461e152019-10-01 14:44:30 -0700385func (o *ServeConnOpts) context() context.Context {
386 if o != nil && o.Context != nil {
387 return o.Context
388 }
389 return context.Background()
390}
391
khenaidooac637102019-01-14 15:44:34 -0500392func (o *ServeConnOpts) baseConfig() *http.Server {
393 if o != nil && o.BaseConfig != nil {
394 return o.BaseConfig
395 }
396 return new(http.Server)
397}
398
399func (o *ServeConnOpts) handler() http.Handler {
400 if o != nil {
401 if o.Handler != nil {
402 return o.Handler
403 }
404 if o.BaseConfig != nil && o.BaseConfig.Handler != nil {
405 return o.BaseConfig.Handler
406 }
407 }
408 return http.DefaultServeMux
409}
410
411// ServeConn serves HTTP/2 requests on the provided connection and
412// blocks until the connection is no longer readable.
413//
414// ServeConn starts speaking HTTP/2 assuming that c has not had any
415// reads or writes. It writes its initial settings frame and expects
416// to be able to read the preface and settings frame from the
417// client. If c has a ConnectionState method like a *tls.Conn, the
418// ConnectionState is used to verify the TLS ciphersuite and to set
419// the Request.TLS field in Handlers.
420//
421// ServeConn does not support h2c by itself. Any h2c support must be
422// implemented in terms of providing a suitably-behaving net.Conn.
423//
424// The opts parameter is optional. If nil, default values are used.
425func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) {
mgouda64be8822025-05-30 10:44:00 +0530426 s.serveConn(c, opts, nil)
427}
428
429func (s *Server) serveConn(c net.Conn, opts *ServeConnOpts, newf func(*serverConn)) {
khenaidooac637102019-01-14 15:44:34 -0500430 baseCtx, cancel := serverConnBaseContext(c, opts)
431 defer cancel()
432
mgouda64be8822025-05-30 10:44:00 +0530433 http1srv := opts.baseConfig()
434 conf := configFromServer(http1srv, s)
khenaidooac637102019-01-14 15:44:34 -0500435 sc := &serverConn{
436 srv: s,
mgouda64be8822025-05-30 10:44:00 +0530437 hs: http1srv,
khenaidooac637102019-01-14 15:44:34 -0500438 conn: c,
439 baseCtx: baseCtx,
440 remoteAddrStr: c.RemoteAddr().String(),
mgouda64be8822025-05-30 10:44:00 +0530441 bw: newBufferedWriter(s.group, c, conf.WriteByteTimeout),
khenaidooac637102019-01-14 15:44:34 -0500442 handler: opts.handler(),
443 streams: make(map[uint32]*stream),
444 readFrameCh: make(chan readFrameResult),
445 wantWriteFrameCh: make(chan FrameWriteRequest, 8),
446 serveMsgCh: make(chan interface{}, 8),
447 wroteFrameCh: make(chan frameWriteResult, 1), // buffered; one send in writeFrameAsync
448 bodyReadCh: make(chan bodyReadMsg), // buffering doesn't matter either way
449 doneServing: make(chan struct{}),
450 clientMaxStreams: math.MaxUint32, // Section 6.5.2: "Initially, there is no limit to this value"
mgouda64be8822025-05-30 10:44:00 +0530451 advMaxStreams: conf.MaxConcurrentStreams,
khenaidooac637102019-01-14 15:44:34 -0500452 initialStreamSendWindowSize: initialWindowSize,
mgouda64be8822025-05-30 10:44:00 +0530453 initialStreamRecvWindowSize: conf.MaxUploadBufferPerStream,
khenaidooac637102019-01-14 15:44:34 -0500454 maxFrameSize: initialMaxFrameSize,
mgouda64be8822025-05-30 10:44:00 +0530455 pingTimeout: conf.PingTimeout,
456 countErrorFunc: conf.CountError,
khenaidooac637102019-01-14 15:44:34 -0500457 serveG: newGoroutineLock(),
458 pushEnabled: true,
mgouda64be8822025-05-30 10:44:00 +0530459 sawClientPreface: opts.SawClientPreface,
460 }
461 if newf != nil {
462 newf(sc)
khenaidooac637102019-01-14 15:44:34 -0500463 }
464
465 s.state.registerConn(sc)
466 defer s.state.unregisterConn(sc)
467
468 // The net/http package sets the write deadline from the
469 // http.Server.WriteTimeout during the TLS handshake, but then
470 // passes the connection off to us with the deadline already set.
471 // Write deadlines are set per stream in serverConn.newStream.
472 // Disarm the net.Conn write deadline here.
mgouda64be8822025-05-30 10:44:00 +0530473 if sc.hs.WriteTimeout > 0 {
khenaidooac637102019-01-14 15:44:34 -0500474 sc.conn.SetWriteDeadline(time.Time{})
475 }
476
477 if s.NewWriteScheduler != nil {
478 sc.writeSched = s.NewWriteScheduler()
479 } else {
mgouda64be8822025-05-30 10:44:00 +0530480 sc.writeSched = newRoundRobinWriteScheduler()
khenaidooac637102019-01-14 15:44:34 -0500481 }
482
483 // These start at the RFC-specified defaults. If there is a higher
484 // configured value for inflow, that will be updated when we send a
485 // WINDOW_UPDATE shortly after sending SETTINGS.
486 sc.flow.add(initialWindowSize)
mgouda64be8822025-05-30 10:44:00 +0530487 sc.inflow.init(initialWindowSize)
khenaidooac637102019-01-14 15:44:34 -0500488 sc.hpackEncoder = hpack.NewEncoder(&sc.headerWriteBuf)
mgouda64be8822025-05-30 10:44:00 +0530489 sc.hpackEncoder.SetMaxDynamicTableSizeLimit(conf.MaxEncoderHeaderTableSize)
khenaidooac637102019-01-14 15:44:34 -0500490
491 fr := NewFramer(sc.bw, c)
mgouda64be8822025-05-30 10:44:00 +0530492 if conf.CountError != nil {
493 fr.countError = conf.CountError
494 }
495 fr.ReadMetaHeaders = hpack.NewDecoder(conf.MaxDecoderHeaderTableSize, nil)
khenaidooac637102019-01-14 15:44:34 -0500496 fr.MaxHeaderListSize = sc.maxHeaderListSize()
mgouda64be8822025-05-30 10:44:00 +0530497 fr.SetMaxReadFrameSize(conf.MaxReadFrameSize)
khenaidooac637102019-01-14 15:44:34 -0500498 sc.framer = fr
499
500 if tc, ok := c.(connectionStater); ok {
501 sc.tlsState = new(tls.ConnectionState)
502 *sc.tlsState = tc.ConnectionState()
503 // 9.2 Use of TLS Features
504 // An implementation of HTTP/2 over TLS MUST use TLS
505 // 1.2 or higher with the restrictions on feature set
506 // and cipher suite described in this section. Due to
507 // implementation limitations, it might not be
508 // possible to fail TLS negotiation. An endpoint MUST
509 // immediately terminate an HTTP/2 connection that
510 // does not meet the TLS requirements described in
511 // this section with a connection error (Section
512 // 5.4.1) of type INADEQUATE_SECURITY.
513 if sc.tlsState.Version < tls.VersionTLS12 {
514 sc.rejectConn(ErrCodeInadequateSecurity, "TLS version too low")
515 return
516 }
517
518 if sc.tlsState.ServerName == "" {
519 // Client must use SNI, but we don't enforce that anymore,
520 // since it was causing problems when connecting to bare IP
521 // addresses during development.
522 //
523 // TODO: optionally enforce? Or enforce at the time we receive
524 // a new request, and verify the ServerName matches the :authority?
525 // But that precludes proxy situations, perhaps.
526 //
527 // So for now, do nothing here again.
528 }
529
mgouda64be8822025-05-30 10:44:00 +0530530 if !conf.PermitProhibitedCipherSuites && isBadCipher(sc.tlsState.CipherSuite) {
khenaidooac637102019-01-14 15:44:34 -0500531 // "Endpoints MAY choose to generate a connection error
532 // (Section 5.4.1) of type INADEQUATE_SECURITY if one of
533 // the prohibited cipher suites are negotiated."
534 //
535 // We choose that. In my opinion, the spec is weak
536 // here. It also says both parties must support at least
537 // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 so there's no
538 // excuses here. If we really must, we could allow an
539 // "AllowInsecureWeakCiphers" option on the server later.
540 // Let's see how it plays out first.
541 sc.rejectConn(ErrCodeInadequateSecurity, fmt.Sprintf("Prohibited TLS 1.2 Cipher Suite: %x", sc.tlsState.CipherSuite))
542 return
543 }
544 }
545
mgouda64be8822025-05-30 10:44:00 +0530546 if opts.Settings != nil {
547 fr := &SettingsFrame{
548 FrameHeader: FrameHeader{valid: true},
549 p: opts.Settings,
550 }
551 if err := fr.ForeachSetting(sc.processSetting); err != nil {
552 sc.rejectConn(ErrCodeProtocol, "invalid settings")
553 return
554 }
555 opts.Settings = nil
556 }
557
khenaidooac637102019-01-14 15:44:34 -0500558 if hook := testHookGetServerConn; hook != nil {
559 hook(sc)
560 }
mgouda64be8822025-05-30 10:44:00 +0530561
562 if opts.UpgradeRequest != nil {
563 sc.upgradeRequest(opts.UpgradeRequest)
564 opts.UpgradeRequest = nil
565 }
566
567 sc.serve(conf)
khenaidooac637102019-01-14 15:44:34 -0500568}
569
570func serverConnBaseContext(c net.Conn, opts *ServeConnOpts) (ctx context.Context, cancel func()) {
Scott Baker8461e152019-10-01 14:44:30 -0700571 ctx, cancel = context.WithCancel(opts.context())
khenaidooac637102019-01-14 15:44:34 -0500572 ctx = context.WithValue(ctx, http.LocalAddrContextKey, c.LocalAddr())
573 if hs := opts.baseConfig(); hs != nil {
574 ctx = context.WithValue(ctx, http.ServerContextKey, hs)
575 }
576 return
577}
578
579func (sc *serverConn) rejectConn(err ErrCode, debug string) {
580 sc.vlogf("http2: server rejecting conn: %v, %s", err, debug)
581 // ignoring errors. hanging up anyway.
582 sc.framer.WriteGoAway(0, err, []byte(debug))
583 sc.bw.Flush()
584 sc.conn.Close()
585}
586
587type serverConn struct {
588 // Immutable:
589 srv *Server
590 hs *http.Server
591 conn net.Conn
592 bw *bufferedWriter // writing to conn
593 handler http.Handler
594 baseCtx context.Context
595 framer *Framer
596 doneServing chan struct{} // closed when serverConn.serve ends
597 readFrameCh chan readFrameResult // written by serverConn.readFrames
598 wantWriteFrameCh chan FrameWriteRequest // from handlers -> serve
599 wroteFrameCh chan frameWriteResult // from writeFrameAsync -> serve, tickles more frame writes
600 bodyReadCh chan bodyReadMsg // from handlers -> serve
601 serveMsgCh chan interface{} // misc messages & code to send to / run on the serve loop
mgouda64be8822025-05-30 10:44:00 +0530602 flow outflow // conn-wide (not stream-specific) outbound flow control
603 inflow inflow // conn-wide inbound flow control
khenaidooac637102019-01-14 15:44:34 -0500604 tlsState *tls.ConnectionState // shared by all handlers, like net/http
605 remoteAddrStr string
606 writeSched WriteScheduler
mgouda64be8822025-05-30 10:44:00 +0530607 countErrorFunc func(errType string)
khenaidooac637102019-01-14 15:44:34 -0500608
609 // Everything following is owned by the serve loop; use serveG.check():
610 serveG goroutineLock // used to verify funcs are on serve()
611 pushEnabled bool
mgouda64be8822025-05-30 10:44:00 +0530612 sawClientPreface bool // preface has already been read, used in h2c upgrade
khenaidooac637102019-01-14 15:44:34 -0500613 sawFirstSettings bool // got the initial SETTINGS frame after the preface
614 needToSendSettingsAck bool
615 unackedSettings int // how many SETTINGS have we sent without ACKs?
Scott Baker8461e152019-10-01 14:44:30 -0700616 queuedControlFrames int // control frames in the writeSched queue
khenaidooac637102019-01-14 15:44:34 -0500617 clientMaxStreams uint32 // SETTINGS_MAX_CONCURRENT_STREAMS from client (our PUSH_PROMISE limit)
618 advMaxStreams uint32 // our SETTINGS_MAX_CONCURRENT_STREAMS advertised the client
619 curClientStreams uint32 // number of open streams initiated by the client
620 curPushedStreams uint32 // number of open streams initiated by server push
mgouda64be8822025-05-30 10:44:00 +0530621 curHandlers uint32 // number of running handler goroutines
khenaidooac637102019-01-14 15:44:34 -0500622 maxClientStreamID uint32 // max ever seen from client (odd), or 0 if there have been no client requests
623 maxPushPromiseID uint32 // ID of the last push promise (even), or 0 if there have been no pushes
624 streams map[uint32]*stream
mgouda64be8822025-05-30 10:44:00 +0530625 unstartedHandlers []unstartedHandler
khenaidooac637102019-01-14 15:44:34 -0500626 initialStreamSendWindowSize int32
mgouda64be8822025-05-30 10:44:00 +0530627 initialStreamRecvWindowSize int32
khenaidooac637102019-01-14 15:44:34 -0500628 maxFrameSize int32
khenaidooac637102019-01-14 15:44:34 -0500629 peerMaxHeaderListSize uint32 // zero means unknown (default)
630 canonHeader map[string]string // http2-lower-case -> Go-Canonical-Case
mgouda64be8822025-05-30 10:44:00 +0530631 canonHeaderKeysSize int // canonHeader keys size in bytes
khenaidooac637102019-01-14 15:44:34 -0500632 writingFrame bool // started writing a frame (on serve goroutine or separate)
633 writingFrameAsync bool // started a frame on its own goroutine but haven't heard back on wroteFrameCh
634 needsFrameFlush bool // last frame write wasn't a flush
635 inGoAway bool // we've started to or sent GOAWAY
636 inFrameScheduleLoop bool // whether we're in the scheduleFrameWrite loop
637 needToSendGoAway bool // we need to schedule a GOAWAY frame write
mgouda64be8822025-05-30 10:44:00 +0530638 pingSent bool
639 sentPingData [8]byte
khenaidooac637102019-01-14 15:44:34 -0500640 goAwayCode ErrCode
mgouda64be8822025-05-30 10:44:00 +0530641 shutdownTimer timer // nil until used
642 idleTimer timer // nil if unused
643 readIdleTimeout time.Duration
644 pingTimeout time.Duration
645 readIdleTimer timer // nil if unused
khenaidooac637102019-01-14 15:44:34 -0500646
647 // Owned by the writeFrameAsync goroutine:
648 headerWriteBuf bytes.Buffer
649 hpackEncoder *hpack.Encoder
650
651 // Used by startGracefulShutdown.
652 shutdownOnce sync.Once
653}
654
655func (sc *serverConn) maxHeaderListSize() uint32 {
656 n := sc.hs.MaxHeaderBytes
657 if n <= 0 {
658 n = http.DefaultMaxHeaderBytes
659 }
mgouda64be8822025-05-30 10:44:00 +0530660 return uint32(adjustHTTP1MaxHeaderSize(int64(n)))
khenaidooac637102019-01-14 15:44:34 -0500661}
662
663func (sc *serverConn) curOpenStreams() uint32 {
664 sc.serveG.check()
665 return sc.curClientStreams + sc.curPushedStreams
666}
667
668// stream represents a stream. This is the minimal metadata needed by
669// the serve goroutine. Most of the actual stream state is owned by
670// the http.Handler's goroutine in the responseWriter. Because the
671// responseWriter's responseWriterState is recycled at the end of a
672// handler, this struct intentionally has no pointer to the
673// *responseWriter{,State} itself, as the Handler ending nils out the
674// responseWriter's state field.
675type stream struct {
676 // immutable:
677 sc *serverConn
678 id uint32
679 body *pipe // non-nil if expecting DATA frames
680 cw closeWaiter // closed wait stream transitions to closed state
681 ctx context.Context
682 cancelCtx func()
683
684 // owned by serverConn's serve loop:
mgouda64be8822025-05-30 10:44:00 +0530685 bodyBytes int64 // body bytes seen so far
686 declBodyBytes int64 // or -1 if undeclared
687 flow outflow // limits writing from Handler to client
688 inflow inflow // what the client is allowed to POST/etc to us
khenaidooac637102019-01-14 15:44:34 -0500689 state streamState
mgouda64be8822025-05-30 10:44:00 +0530690 resetQueued bool // RST_STREAM queued for write; set by sc.resetStream
691 gotTrailerHeader bool // HEADER frame for trailers was seen
692 wroteHeaders bool // whether we wrote headers (not status 100)
693 readDeadline timer // nil if unused
694 writeDeadline timer // nil if unused
695 closeErr error // set before cw is closed
khenaidooac637102019-01-14 15:44:34 -0500696
697 trailer http.Header // accumulated trailers
698 reqTrailer http.Header // handler's Request.Trailer
699}
700
701func (sc *serverConn) Framer() *Framer { return sc.framer }
702func (sc *serverConn) CloseConn() error { return sc.conn.Close() }
703func (sc *serverConn) Flush() error { return sc.bw.Flush() }
704func (sc *serverConn) HeaderEncoder() (*hpack.Encoder, *bytes.Buffer) {
705 return sc.hpackEncoder, &sc.headerWriteBuf
706}
707
708func (sc *serverConn) state(streamID uint32) (streamState, *stream) {
709 sc.serveG.check()
710 // http://tools.ietf.org/html/rfc7540#section-5.1
711 if st, ok := sc.streams[streamID]; ok {
712 return st.state, st
713 }
714 // "The first use of a new stream identifier implicitly closes all
715 // streams in the "idle" state that might have been initiated by
716 // that peer with a lower-valued stream identifier. For example, if
717 // a client sends a HEADERS frame on stream 7 without ever sending a
718 // frame on stream 5, then stream 5 transitions to the "closed"
719 // state when the first frame for stream 7 is sent or received."
720 if streamID%2 == 1 {
721 if streamID <= sc.maxClientStreamID {
722 return stateClosed, nil
723 }
724 } else {
725 if streamID <= sc.maxPushPromiseID {
726 return stateClosed, nil
727 }
728 }
729 return stateIdle, nil
730}
731
732// setConnState calls the net/http ConnState hook for this connection, if configured.
733// Note that the net/http package does StateNew and StateClosed for us.
734// There is currently no plan for StateHijacked or hijacking HTTP/2 connections.
735func (sc *serverConn) setConnState(state http.ConnState) {
736 if sc.hs.ConnState != nil {
737 sc.hs.ConnState(sc.conn, state)
738 }
739}
740
741func (sc *serverConn) vlogf(format string, args ...interface{}) {
742 if VerboseLogs {
743 sc.logf(format, args...)
744 }
745}
746
747func (sc *serverConn) logf(format string, args ...interface{}) {
748 if lg := sc.hs.ErrorLog; lg != nil {
749 lg.Printf(format, args...)
750 } else {
751 log.Printf(format, args...)
752 }
753}
754
755// errno returns v's underlying uintptr, else 0.
756//
757// TODO: remove this helper function once http2 can use build
758// tags. See comment in isClosedConnError.
759func errno(v error) uintptr {
760 if rv := reflect.ValueOf(v); rv.Kind() == reflect.Uintptr {
761 return uintptr(rv.Uint())
762 }
763 return 0
764}
765
766// isClosedConnError reports whether err is an error from use of a closed
767// network connection.
768func isClosedConnError(err error) bool {
769 if err == nil {
770 return false
771 }
772
mgouda64be8822025-05-30 10:44:00 +0530773 if errors.Is(err, net.ErrClosed) {
khenaidooac637102019-01-14 15:44:34 -0500774 return true
775 }
776
777 // TODO(bradfitz): x/tools/cmd/bundle doesn't really support
778 // build tags, so I can't make an http2_windows.go file with
779 // Windows-specific stuff. Fix that and move this, once we
780 // have a way to bundle this into std's net/http somehow.
781 if runtime.GOOS == "windows" {
782 if oe, ok := err.(*net.OpError); ok && oe.Op == "read" {
783 if se, ok := oe.Err.(*os.SyscallError); ok && se.Syscall == "wsarecv" {
784 const WSAECONNABORTED = 10053
785 const WSAECONNRESET = 10054
786 if n := errno(se.Err); n == WSAECONNRESET || n == WSAECONNABORTED {
787 return true
788 }
789 }
790 }
791 }
792 return false
793}
794
795func (sc *serverConn) condlogf(err error, format string, args ...interface{}) {
796 if err == nil {
797 return
798 }
799 if err == io.EOF || err == io.ErrUnexpectedEOF || isClosedConnError(err) || err == errPrefaceTimeout {
800 // Boring, expected errors.
801 sc.vlogf(format, args...)
802 } else {
803 sc.logf(format, args...)
804 }
805}
806
mgouda64be8822025-05-30 10:44:00 +0530807// maxCachedCanonicalHeadersKeysSize is an arbitrarily-chosen limit on the size
808// of the entries in the canonHeader cache.
809// This should be larger than the size of unique, uncommon header keys likely to
810// be sent by the peer, while not so high as to permit unreasonable memory usage
811// if the peer sends an unbounded number of unique header keys.
812const maxCachedCanonicalHeadersKeysSize = 2048
813
khenaidooac637102019-01-14 15:44:34 -0500814func (sc *serverConn) canonicalHeader(v string) string {
815 sc.serveG.check()
mgouda64be8822025-05-30 10:44:00 +0530816 cv, ok := httpcommon.CachedCanonicalHeader(v)
khenaidooac637102019-01-14 15:44:34 -0500817 if ok {
818 return cv
819 }
820 cv, ok = sc.canonHeader[v]
821 if ok {
822 return cv
823 }
824 if sc.canonHeader == nil {
825 sc.canonHeader = make(map[string]string)
826 }
827 cv = http.CanonicalHeaderKey(v)
mgouda64be8822025-05-30 10:44:00 +0530828 size := 100 + len(v)*2 // 100 bytes of map overhead + key + value
829 if sc.canonHeaderKeysSize+size <= maxCachedCanonicalHeadersKeysSize {
830 sc.canonHeader[v] = cv
831 sc.canonHeaderKeysSize += size
832 }
khenaidooac637102019-01-14 15:44:34 -0500833 return cv
834}
835
836type readFrameResult struct {
837 f Frame // valid until readMore is called
838 err error
839
840 // readMore should be called once the consumer no longer needs or
841 // retains f. After readMore, f is invalid and more frames can be
842 // read.
843 readMore func()
844}
845
846// readFrames is the loop that reads incoming frames.
847// It takes care to only read one frame at a time, blocking until the
848// consumer is done with the frame.
849// It's run on its own goroutine.
850func (sc *serverConn) readFrames() {
mgouda64be8822025-05-30 10:44:00 +0530851 sc.srv.markNewGoroutine()
852 gate := make(chan struct{})
853 gateDone := func() { gate <- struct{}{} }
khenaidooac637102019-01-14 15:44:34 -0500854 for {
855 f, err := sc.framer.ReadFrame()
856 select {
857 case sc.readFrameCh <- readFrameResult{f, err, gateDone}:
858 case <-sc.doneServing:
859 return
860 }
861 select {
862 case <-gate:
863 case <-sc.doneServing:
864 return
865 }
866 if terminalReadFrameError(err) {
867 return
868 }
869 }
870}
871
872// frameWriteResult is the message passed from writeFrameAsync to the serve goroutine.
873type frameWriteResult struct {
Andrea Campanella3614a922021-02-25 12:40:42 +0100874 _ incomparable
khenaidooac637102019-01-14 15:44:34 -0500875 wr FrameWriteRequest // what was written (or attempted)
876 err error // result of the writeFrame call
877}
878
879// writeFrameAsync runs in its own goroutine and writes a single frame
880// and then reports when it's done.
881// At most one goroutine can be running writeFrameAsync at a time per
882// serverConn.
mgouda64be8822025-05-30 10:44:00 +0530883func (sc *serverConn) writeFrameAsync(wr FrameWriteRequest, wd *writeData) {
884 sc.srv.markNewGoroutine()
885 var err error
886 if wd == nil {
887 err = wr.write.writeFrame(sc)
888 } else {
889 err = sc.framer.endWrite()
890 }
Andrea Campanella3614a922021-02-25 12:40:42 +0100891 sc.wroteFrameCh <- frameWriteResult{wr: wr, err: err}
khenaidooac637102019-01-14 15:44:34 -0500892}
893
894func (sc *serverConn) closeAllStreamsOnConnClose() {
895 sc.serveG.check()
896 for _, st := range sc.streams {
897 sc.closeStream(st, errClientDisconnected)
898 }
899}
900
901func (sc *serverConn) stopShutdownTimer() {
902 sc.serveG.check()
903 if t := sc.shutdownTimer; t != nil {
904 t.Stop()
905 }
906}
907
908func (sc *serverConn) notePanic() {
909 // Note: this is for serverConn.serve panicking, not http.Handler code.
910 if testHookOnPanicMu != nil {
911 testHookOnPanicMu.Lock()
912 defer testHookOnPanicMu.Unlock()
913 }
914 if testHookOnPanic != nil {
915 if e := recover(); e != nil {
916 if testHookOnPanic(sc, e) {
917 panic(e)
918 }
919 }
920 }
921}
922
mgouda64be8822025-05-30 10:44:00 +0530923func (sc *serverConn) serve(conf http2Config) {
khenaidooac637102019-01-14 15:44:34 -0500924 sc.serveG.check()
925 defer sc.notePanic()
926 defer sc.conn.Close()
927 defer sc.closeAllStreamsOnConnClose()
928 defer sc.stopShutdownTimer()
929 defer close(sc.doneServing) // unblocks handlers trying to send
930
931 if VerboseLogs {
932 sc.vlogf("http2: server connection from %v on %p", sc.conn.RemoteAddr(), sc.hs)
933 }
934
mgouda64be8822025-05-30 10:44:00 +0530935 settings := writeSettings{
936 {SettingMaxFrameSize, conf.MaxReadFrameSize},
937 {SettingMaxConcurrentStreams, sc.advMaxStreams},
938 {SettingMaxHeaderListSize, sc.maxHeaderListSize()},
939 {SettingHeaderTableSize, conf.MaxDecoderHeaderTableSize},
940 {SettingInitialWindowSize, uint32(sc.initialStreamRecvWindowSize)},
941 }
942 if !disableExtendedConnectProtocol {
943 settings = append(settings, Setting{SettingEnableConnectProtocol, 1})
944 }
khenaidooac637102019-01-14 15:44:34 -0500945 sc.writeFrame(FrameWriteRequest{
mgouda64be8822025-05-30 10:44:00 +0530946 write: settings,
khenaidooac637102019-01-14 15:44:34 -0500947 })
948 sc.unackedSettings++
949
mgouda64be8822025-05-30 10:44:00 +0530950 // Each connection starts with initialWindowSize inflow tokens.
khenaidooac637102019-01-14 15:44:34 -0500951 // If a higher value is configured, we add more tokens.
mgouda64be8822025-05-30 10:44:00 +0530952 if diff := conf.MaxUploadBufferPerConnection - initialWindowSize; diff > 0 {
khenaidooac637102019-01-14 15:44:34 -0500953 sc.sendWindowUpdate(nil, int(diff))
954 }
955
956 if err := sc.readPreface(); err != nil {
957 sc.condlogf(err, "http2: server: error reading preface from client %v: %v", sc.conn.RemoteAddr(), err)
958 return
959 }
960 // Now that we've got the preface, get us out of the
961 // "StateNew" state. We can't go directly to idle, though.
962 // Active means we read some data and anticipate a request. We'll
963 // do another Active when we get a HEADERS frame.
964 sc.setConnState(http.StateActive)
965 sc.setConnState(http.StateIdle)
966
mgouda64be8822025-05-30 10:44:00 +0530967 if sc.srv.IdleTimeout > 0 {
968 sc.idleTimer = sc.srv.afterFunc(sc.srv.IdleTimeout, sc.onIdleTimer)
khenaidooac637102019-01-14 15:44:34 -0500969 defer sc.idleTimer.Stop()
970 }
971
mgouda64be8822025-05-30 10:44:00 +0530972 if conf.SendPingTimeout > 0 {
973 sc.readIdleTimeout = conf.SendPingTimeout
974 sc.readIdleTimer = sc.srv.afterFunc(conf.SendPingTimeout, sc.onReadIdleTimer)
975 defer sc.readIdleTimer.Stop()
976 }
977
khenaidooac637102019-01-14 15:44:34 -0500978 go sc.readFrames() // closed by defer sc.conn.Close above
979
mgouda64be8822025-05-30 10:44:00 +0530980 settingsTimer := sc.srv.afterFunc(firstSettingsTimeout, sc.onSettingsTimer)
khenaidooac637102019-01-14 15:44:34 -0500981 defer settingsTimer.Stop()
982
mgouda64be8822025-05-30 10:44:00 +0530983 lastFrameTime := sc.srv.now()
khenaidooac637102019-01-14 15:44:34 -0500984 loopNum := 0
985 for {
986 loopNum++
987 select {
988 case wr := <-sc.wantWriteFrameCh:
989 if se, ok := wr.write.(StreamError); ok {
990 sc.resetStream(se)
991 break
992 }
993 sc.writeFrame(wr)
994 case res := <-sc.wroteFrameCh:
995 sc.wroteFrame(res)
996 case res := <-sc.readFrameCh:
mgouda64be8822025-05-30 10:44:00 +0530997 lastFrameTime = sc.srv.now()
998 // Process any written frames before reading new frames from the client since a
999 // written frame could have triggered a new stream to be started.
1000 if sc.writingFrameAsync {
1001 select {
1002 case wroteRes := <-sc.wroteFrameCh:
1003 sc.wroteFrame(wroteRes)
1004 default:
1005 }
1006 }
khenaidooac637102019-01-14 15:44:34 -05001007 if !sc.processFrameFromReader(res) {
1008 return
1009 }
1010 res.readMore()
1011 if settingsTimer != nil {
1012 settingsTimer.Stop()
1013 settingsTimer = nil
1014 }
1015 case m := <-sc.bodyReadCh:
1016 sc.noteBodyRead(m.st, m.n)
1017 case msg := <-sc.serveMsgCh:
1018 switch v := msg.(type) {
1019 case func(int):
1020 v(loopNum) // for testing
1021 case *serverMessage:
1022 switch v {
1023 case settingsTimerMsg:
1024 sc.logf("timeout waiting for SETTINGS frames from %v", sc.conn.RemoteAddr())
1025 return
1026 case idleTimerMsg:
1027 sc.vlogf("connection is idle")
1028 sc.goAway(ErrCodeNo)
mgouda64be8822025-05-30 10:44:00 +05301029 case readIdleTimerMsg:
1030 sc.handlePingTimer(lastFrameTime)
khenaidooac637102019-01-14 15:44:34 -05001031 case shutdownTimerMsg:
1032 sc.vlogf("GOAWAY close timer fired; closing conn from %v", sc.conn.RemoteAddr())
1033 return
1034 case gracefulShutdownMsg:
1035 sc.startGracefulShutdownInternal()
mgouda64be8822025-05-30 10:44:00 +05301036 case handlerDoneMsg:
1037 sc.handlerDone()
khenaidooac637102019-01-14 15:44:34 -05001038 default:
1039 panic("unknown timer")
1040 }
1041 case *startPushRequest:
1042 sc.startPush(v)
mgouda64be8822025-05-30 10:44:00 +05301043 case func(*serverConn):
1044 v(sc)
khenaidooac637102019-01-14 15:44:34 -05001045 default:
1046 panic(fmt.Sprintf("unexpected type %T", v))
1047 }
1048 }
1049
Scott Baker8461e152019-10-01 14:44:30 -07001050 // If the peer is causing us to generate a lot of control frames,
1051 // but not reading them from us, assume they are trying to make us
1052 // run out of memory.
mgouda64be8822025-05-30 10:44:00 +05301053 if sc.queuedControlFrames > maxQueuedControlFrames {
Scott Baker8461e152019-10-01 14:44:30 -07001054 sc.vlogf("http2: too many control frames in send queue, closing connection")
1055 return
1056 }
1057
khenaidooac637102019-01-14 15:44:34 -05001058 // Start the shutdown timer after sending a GOAWAY. When sending GOAWAY
1059 // with no error code (graceful shutdown), don't start the timer until
1060 // all open streams have been completed.
1061 sentGoAway := sc.inGoAway && !sc.needToSendGoAway && !sc.writingFrame
1062 gracefulShutdownComplete := sc.goAwayCode == ErrCodeNo && sc.curOpenStreams() == 0
1063 if sentGoAway && sc.shutdownTimer == nil && (sc.goAwayCode != ErrCodeNo || gracefulShutdownComplete) {
1064 sc.shutDownIn(goAwayTimeout)
1065 }
1066 }
1067}
1068
mgouda64be8822025-05-30 10:44:00 +05301069func (sc *serverConn) handlePingTimer(lastFrameReadTime time.Time) {
1070 if sc.pingSent {
1071 sc.vlogf("timeout waiting for PING response")
1072 sc.conn.Close()
1073 return
khenaidooac637102019-01-14 15:44:34 -05001074 }
mgouda64be8822025-05-30 10:44:00 +05301075
1076 pingAt := lastFrameReadTime.Add(sc.readIdleTimeout)
1077 now := sc.srv.now()
1078 if pingAt.After(now) {
1079 // We received frames since arming the ping timer.
1080 // Reset it for the next possible timeout.
1081 sc.readIdleTimer.Reset(pingAt.Sub(now))
1082 return
1083 }
1084
1085 sc.pingSent = true
1086 // Ignore crypto/rand.Read errors: It generally can't fail, and worse case if it does
1087 // is we send a PING frame containing 0s.
1088 _, _ = rand.Read(sc.sentPingData[:])
1089 sc.writeFrame(FrameWriteRequest{
1090 write: &writePing{data: sc.sentPingData},
1091 })
1092 sc.readIdleTimer.Reset(sc.pingTimeout)
khenaidooac637102019-01-14 15:44:34 -05001093}
1094
1095type serverMessage int
1096
1097// Message values sent to serveMsgCh.
1098var (
1099 settingsTimerMsg = new(serverMessage)
1100 idleTimerMsg = new(serverMessage)
mgouda64be8822025-05-30 10:44:00 +05301101 readIdleTimerMsg = new(serverMessage)
khenaidooac637102019-01-14 15:44:34 -05001102 shutdownTimerMsg = new(serverMessage)
1103 gracefulShutdownMsg = new(serverMessage)
mgouda64be8822025-05-30 10:44:00 +05301104 handlerDoneMsg = new(serverMessage)
khenaidooac637102019-01-14 15:44:34 -05001105)
1106
1107func (sc *serverConn) onSettingsTimer() { sc.sendServeMsg(settingsTimerMsg) }
1108func (sc *serverConn) onIdleTimer() { sc.sendServeMsg(idleTimerMsg) }
mgouda64be8822025-05-30 10:44:00 +05301109func (sc *serverConn) onReadIdleTimer() { sc.sendServeMsg(readIdleTimerMsg) }
khenaidooac637102019-01-14 15:44:34 -05001110func (sc *serverConn) onShutdownTimer() { sc.sendServeMsg(shutdownTimerMsg) }
1111
1112func (sc *serverConn) sendServeMsg(msg interface{}) {
1113 sc.serveG.checkNotOn() // NOT
1114 select {
1115 case sc.serveMsgCh <- msg:
1116 case <-sc.doneServing:
1117 }
1118}
1119
1120var errPrefaceTimeout = errors.New("timeout waiting for client preface")
1121
1122// readPreface reads the ClientPreface greeting from the peer or
1123// returns errPrefaceTimeout on timeout, or an error if the greeting
1124// is invalid.
1125func (sc *serverConn) readPreface() error {
mgouda64be8822025-05-30 10:44:00 +05301126 if sc.sawClientPreface {
1127 return nil
1128 }
khenaidooac637102019-01-14 15:44:34 -05001129 errc := make(chan error, 1)
1130 go func() {
1131 // Read the client preface
1132 buf := make([]byte, len(ClientPreface))
1133 if _, err := io.ReadFull(sc.conn, buf); err != nil {
1134 errc <- err
1135 } else if !bytes.Equal(buf, clientPreface) {
1136 errc <- fmt.Errorf("bogus greeting %q", buf)
1137 } else {
1138 errc <- nil
1139 }
1140 }()
mgouda64be8822025-05-30 10:44:00 +05301141 timer := sc.srv.newTimer(prefaceTimeout) // TODO: configurable on *Server?
khenaidooac637102019-01-14 15:44:34 -05001142 defer timer.Stop()
1143 select {
mgouda64be8822025-05-30 10:44:00 +05301144 case <-timer.C():
khenaidooac637102019-01-14 15:44:34 -05001145 return errPrefaceTimeout
1146 case err := <-errc:
1147 if err == nil {
1148 if VerboseLogs {
1149 sc.vlogf("http2: server: client %v said hello", sc.conn.RemoteAddr())
1150 }
1151 }
1152 return err
1153 }
1154}
1155
1156var errChanPool = sync.Pool{
1157 New: func() interface{} { return make(chan error, 1) },
1158}
1159
1160var writeDataPool = sync.Pool{
1161 New: func() interface{} { return new(writeData) },
1162}
1163
1164// writeDataFromHandler writes DATA response frames from a handler on
1165// the given stream.
1166func (sc *serverConn) writeDataFromHandler(stream *stream, data []byte, endStream bool) error {
1167 ch := errChanPool.Get().(chan error)
1168 writeArg := writeDataPool.Get().(*writeData)
1169 *writeArg = writeData{stream.id, data, endStream}
1170 err := sc.writeFrameFromHandler(FrameWriteRequest{
1171 write: writeArg,
1172 stream: stream,
1173 done: ch,
1174 })
1175 if err != nil {
1176 return err
1177 }
1178 var frameWriteDone bool // the frame write is done (successfully or not)
1179 select {
1180 case err = <-ch:
1181 frameWriteDone = true
1182 case <-sc.doneServing:
1183 return errClientDisconnected
1184 case <-stream.cw:
1185 // If both ch and stream.cw were ready (as might
1186 // happen on the final Write after an http.Handler
1187 // ends), prefer the write result. Otherwise this
1188 // might just be us successfully closing the stream.
1189 // The writeFrameAsync and serve goroutines guarantee
1190 // that the ch send will happen before the stream.cw
1191 // close.
1192 select {
1193 case err = <-ch:
1194 frameWriteDone = true
1195 default:
1196 return errStreamClosed
1197 }
1198 }
1199 errChanPool.Put(ch)
1200 if frameWriteDone {
1201 writeDataPool.Put(writeArg)
1202 }
1203 return err
1204}
1205
1206// writeFrameFromHandler sends wr to sc.wantWriteFrameCh, but aborts
1207// if the connection has gone away.
1208//
1209// This must not be run from the serve goroutine itself, else it might
1210// deadlock writing to sc.wantWriteFrameCh (which is only mildly
1211// buffered and is read by serve itself). If you're on the serve
1212// goroutine, call writeFrame instead.
1213func (sc *serverConn) writeFrameFromHandler(wr FrameWriteRequest) error {
1214 sc.serveG.checkNotOn() // NOT
1215 select {
1216 case sc.wantWriteFrameCh <- wr:
1217 return nil
1218 case <-sc.doneServing:
1219 // Serve loop is gone.
1220 // Client has closed their connection to the server.
1221 return errClientDisconnected
1222 }
1223}
1224
1225// writeFrame schedules a frame to write and sends it if there's nothing
1226// already being written.
1227//
1228// There is no pushback here (the serve goroutine never blocks). It's
1229// the http.Handlers that block, waiting for their previous frames to
1230// make it onto the wire
1231//
1232// If you're not on the serve goroutine, use writeFrameFromHandler instead.
1233func (sc *serverConn) writeFrame(wr FrameWriteRequest) {
1234 sc.serveG.check()
1235
1236 // If true, wr will not be written and wr.done will not be signaled.
1237 var ignoreWrite bool
1238
1239 // We are not allowed to write frames on closed streams. RFC 7540 Section
1240 // 5.1.1 says: "An endpoint MUST NOT send frames other than PRIORITY on
1241 // a closed stream." Our server never sends PRIORITY, so that exception
1242 // does not apply.
1243 //
1244 // The serverConn might close an open stream while the stream's handler
1245 // is still running. For example, the server might close a stream when it
1246 // receives bad data from the client. If this happens, the handler might
1247 // attempt to write a frame after the stream has been closed (since the
1248 // handler hasn't yet been notified of the close). In this case, we simply
1249 // ignore the frame. The handler will notice that the stream is closed when
1250 // it waits for the frame to be written.
1251 //
1252 // As an exception to this rule, we allow sending RST_STREAM after close.
1253 // This allows us to immediately reject new streams without tracking any
1254 // state for those streams (except for the queued RST_STREAM frame). This
1255 // may result in duplicate RST_STREAMs in some cases, but the client should
1256 // ignore those.
1257 if wr.StreamID() != 0 {
1258 _, isReset := wr.write.(StreamError)
1259 if state, _ := sc.state(wr.StreamID()); state == stateClosed && !isReset {
1260 ignoreWrite = true
1261 }
1262 }
1263
1264 // Don't send a 100-continue response if we've already sent headers.
1265 // See golang.org/issue/14030.
1266 switch wr.write.(type) {
1267 case *writeResHeaders:
1268 wr.stream.wroteHeaders = true
1269 case write100ContinueHeadersFrame:
1270 if wr.stream.wroteHeaders {
1271 // We do not need to notify wr.done because this frame is
1272 // never written with wr.done != nil.
1273 if wr.done != nil {
1274 panic("wr.done != nil for write100ContinueHeadersFrame")
1275 }
1276 ignoreWrite = true
1277 }
1278 }
1279
1280 if !ignoreWrite {
Scott Baker8461e152019-10-01 14:44:30 -07001281 if wr.isControl() {
1282 sc.queuedControlFrames++
1283 // For extra safety, detect wraparounds, which should not happen,
1284 // and pull the plug.
1285 if sc.queuedControlFrames < 0 {
1286 sc.conn.Close()
1287 }
1288 }
khenaidooac637102019-01-14 15:44:34 -05001289 sc.writeSched.Push(wr)
1290 }
1291 sc.scheduleFrameWrite()
1292}
1293
1294// startFrameWrite starts a goroutine to write wr (in a separate
1295// goroutine since that might block on the network), and updates the
1296// serve goroutine's state about the world, updated from info in wr.
1297func (sc *serverConn) startFrameWrite(wr FrameWriteRequest) {
1298 sc.serveG.check()
1299 if sc.writingFrame {
1300 panic("internal error: can only be writing one frame at a time")
1301 }
1302
1303 st := wr.stream
1304 if st != nil {
1305 switch st.state {
1306 case stateHalfClosedLocal:
1307 switch wr.write.(type) {
1308 case StreamError, handlerPanicRST, writeWindowUpdate:
1309 // RFC 7540 Section 5.1 allows sending RST_STREAM, PRIORITY, and WINDOW_UPDATE
1310 // in this state. (We never send PRIORITY from the server, so that is not checked.)
1311 default:
1312 panic(fmt.Sprintf("internal error: attempt to send frame on a half-closed-local stream: %v", wr))
1313 }
1314 case stateClosed:
1315 panic(fmt.Sprintf("internal error: attempt to send frame on a closed stream: %v", wr))
1316 }
1317 }
1318 if wpp, ok := wr.write.(*writePushPromise); ok {
1319 var err error
1320 wpp.promisedID, err = wpp.allocatePromisedID()
1321 if err != nil {
1322 sc.writingFrameAsync = false
1323 wr.replyToWriter(err)
1324 return
1325 }
1326 }
1327
1328 sc.writingFrame = true
1329 sc.needsFrameFlush = true
1330 if wr.write.staysWithinBuffer(sc.bw.Available()) {
1331 sc.writingFrameAsync = false
1332 err := wr.write.writeFrame(sc)
Andrea Campanella3614a922021-02-25 12:40:42 +01001333 sc.wroteFrame(frameWriteResult{wr: wr, err: err})
mgouda64be8822025-05-30 10:44:00 +05301334 } else if wd, ok := wr.write.(*writeData); ok {
1335 // Encode the frame in the serve goroutine, to ensure we don't have
1336 // any lingering asynchronous references to data passed to Write.
1337 // See https://go.dev/issue/58446.
1338 sc.framer.startWriteDataPadded(wd.streamID, wd.endStream, wd.p, nil)
1339 sc.writingFrameAsync = true
1340 go sc.writeFrameAsync(wr, wd)
khenaidooac637102019-01-14 15:44:34 -05001341 } else {
1342 sc.writingFrameAsync = true
mgouda64be8822025-05-30 10:44:00 +05301343 go sc.writeFrameAsync(wr, nil)
khenaidooac637102019-01-14 15:44:34 -05001344 }
1345}
1346
1347// errHandlerPanicked is the error given to any callers blocked in a read from
1348// Request.Body when the main goroutine panics. Since most handlers read in the
1349// main ServeHTTP goroutine, this will show up rarely.
1350var errHandlerPanicked = errors.New("http2: handler panicked")
1351
1352// wroteFrame is called on the serve goroutine with the result of
1353// whatever happened on writeFrameAsync.
1354func (sc *serverConn) wroteFrame(res frameWriteResult) {
1355 sc.serveG.check()
1356 if !sc.writingFrame {
1357 panic("internal error: expected to be already writing a frame")
1358 }
1359 sc.writingFrame = false
1360 sc.writingFrameAsync = false
1361
mgouda64be8822025-05-30 10:44:00 +05301362 if res.err != nil {
1363 sc.conn.Close()
1364 }
1365
khenaidooac637102019-01-14 15:44:34 -05001366 wr := res.wr
1367
1368 if writeEndsStream(wr.write) {
1369 st := wr.stream
1370 if st == nil {
1371 panic("internal error: expecting non-nil stream")
1372 }
1373 switch st.state {
1374 case stateOpen:
1375 // Here we would go to stateHalfClosedLocal in
1376 // theory, but since our handler is done and
1377 // the net/http package provides no mechanism
1378 // for closing a ResponseWriter while still
1379 // reading data (see possible TODO at top of
1380 // this file), we go into closed state here
1381 // anyway, after telling the peer we're
1382 // hanging up on them. We'll transition to
1383 // stateClosed after the RST_STREAM frame is
1384 // written.
1385 st.state = stateHalfClosedLocal
1386 // Section 8.1: a server MAY request that the client abort
1387 // transmission of a request without error by sending a
1388 // RST_STREAM with an error code of NO_ERROR after sending
1389 // a complete response.
1390 sc.resetStream(streamError(st.id, ErrCodeNo))
1391 case stateHalfClosedRemote:
1392 sc.closeStream(st, errHandlerComplete)
1393 }
1394 } else {
1395 switch v := wr.write.(type) {
1396 case StreamError:
1397 // st may be unknown if the RST_STREAM was generated to reject bad input.
1398 if st, ok := sc.streams[v.StreamID]; ok {
1399 sc.closeStream(st, v)
1400 }
1401 case handlerPanicRST:
1402 sc.closeStream(wr.stream, errHandlerPanicked)
1403 }
1404 }
1405
1406 // Reply (if requested) to unblock the ServeHTTP goroutine.
1407 wr.replyToWriter(res.err)
1408
1409 sc.scheduleFrameWrite()
1410}
1411
1412// scheduleFrameWrite tickles the frame writing scheduler.
1413//
1414// If a frame is already being written, nothing happens. This will be called again
1415// when the frame is done being written.
1416//
Scott Baker8461e152019-10-01 14:44:30 -07001417// If a frame isn't being written and we need to send one, the best frame
1418// to send is selected by writeSched.
khenaidooac637102019-01-14 15:44:34 -05001419//
1420// If a frame isn't being written and there's nothing else to send, we
1421// flush the write buffer.
1422func (sc *serverConn) scheduleFrameWrite() {
1423 sc.serveG.check()
1424 if sc.writingFrame || sc.inFrameScheduleLoop {
1425 return
1426 }
1427 sc.inFrameScheduleLoop = true
1428 for !sc.writingFrameAsync {
1429 if sc.needToSendGoAway {
1430 sc.needToSendGoAway = false
1431 sc.startFrameWrite(FrameWriteRequest{
1432 write: &writeGoAway{
1433 maxStreamID: sc.maxClientStreamID,
1434 code: sc.goAwayCode,
1435 },
1436 })
1437 continue
1438 }
1439 if sc.needToSendSettingsAck {
1440 sc.needToSendSettingsAck = false
1441 sc.startFrameWrite(FrameWriteRequest{write: writeSettingsAck{}})
1442 continue
1443 }
1444 if !sc.inGoAway || sc.goAwayCode == ErrCodeNo {
1445 if wr, ok := sc.writeSched.Pop(); ok {
Scott Baker8461e152019-10-01 14:44:30 -07001446 if wr.isControl() {
1447 sc.queuedControlFrames--
1448 }
khenaidooac637102019-01-14 15:44:34 -05001449 sc.startFrameWrite(wr)
1450 continue
1451 }
1452 }
1453 if sc.needsFrameFlush {
1454 sc.startFrameWrite(FrameWriteRequest{write: flushFrameWriter{}})
1455 sc.needsFrameFlush = false // after startFrameWrite, since it sets this true
1456 continue
1457 }
1458 break
1459 }
1460 sc.inFrameScheduleLoop = false
1461}
1462
1463// startGracefulShutdown gracefully shuts down a connection. This
1464// sends GOAWAY with ErrCodeNo to tell the client we're gracefully
1465// shutting down. The connection isn't closed until all current
1466// streams are done.
1467//
1468// startGracefulShutdown returns immediately; it does not wait until
1469// the connection has shut down.
1470func (sc *serverConn) startGracefulShutdown() {
1471 sc.serveG.checkNotOn() // NOT
1472 sc.shutdownOnce.Do(func() { sc.sendServeMsg(gracefulShutdownMsg) })
1473}
1474
khenaidood948f772021-08-11 17:49:24 -04001475// After sending GOAWAY with an error code (non-graceful shutdown), the
1476// connection will close after goAwayTimeout.
1477//
khenaidooac637102019-01-14 15:44:34 -05001478// If we close the connection immediately after sending GOAWAY, there may
1479// be unsent data in our kernel receive buffer, which will cause the kernel
1480// to send a TCP RST on close() instead of a FIN. This RST will abort the
1481// connection immediately, whether or not the client had received the GOAWAY.
1482//
1483// Ideally we should delay for at least 1 RTT + epsilon so the client has
1484// a chance to read the GOAWAY and stop sending messages. Measuring RTT
1485// is hard, so we approximate with 1 second. See golang.org/issue/18701.
1486//
1487// This is a var so it can be shorter in tests, where all requests uses the
1488// loopback interface making the expected RTT very small.
1489//
1490// TODO: configurable?
1491var goAwayTimeout = 1 * time.Second
1492
1493func (sc *serverConn) startGracefulShutdownInternal() {
1494 sc.goAway(ErrCodeNo)
1495}
1496
1497func (sc *serverConn) goAway(code ErrCode) {
1498 sc.serveG.check()
1499 if sc.inGoAway {
mgouda64be8822025-05-30 10:44:00 +05301500 if sc.goAwayCode == ErrCodeNo {
1501 sc.goAwayCode = code
1502 }
khenaidooac637102019-01-14 15:44:34 -05001503 return
1504 }
1505 sc.inGoAway = true
1506 sc.needToSendGoAway = true
1507 sc.goAwayCode = code
1508 sc.scheduleFrameWrite()
1509}
1510
1511func (sc *serverConn) shutDownIn(d time.Duration) {
1512 sc.serveG.check()
mgouda64be8822025-05-30 10:44:00 +05301513 sc.shutdownTimer = sc.srv.afterFunc(d, sc.onShutdownTimer)
khenaidooac637102019-01-14 15:44:34 -05001514}
1515
1516func (sc *serverConn) resetStream(se StreamError) {
1517 sc.serveG.check()
1518 sc.writeFrame(FrameWriteRequest{write: se})
1519 if st, ok := sc.streams[se.StreamID]; ok {
1520 st.resetQueued = true
1521 }
1522}
1523
1524// processFrameFromReader processes the serve loop's read from readFrameCh from the
1525// frame-reading goroutine.
1526// processFrameFromReader returns whether the connection should be kept open.
1527func (sc *serverConn) processFrameFromReader(res readFrameResult) bool {
1528 sc.serveG.check()
1529 err := res.err
1530 if err != nil {
1531 if err == ErrFrameTooLarge {
1532 sc.goAway(ErrCodeFrameSize)
1533 return true // goAway will close the loop
1534 }
1535 clientGone := err == io.EOF || err == io.ErrUnexpectedEOF || isClosedConnError(err)
1536 if clientGone {
1537 // TODO: could we also get into this state if
1538 // the peer does a half close
1539 // (e.g. CloseWrite) because they're done
1540 // sending frames but they're still wanting
1541 // our open replies? Investigate.
1542 // TODO: add CloseWrite to crypto/tls.Conn first
1543 // so we have a way to test this? I suppose
1544 // just for testing we could have a non-TLS mode.
1545 return false
1546 }
1547 } else {
1548 f := res.f
1549 if VerboseLogs {
1550 sc.vlogf("http2: server read frame %v", summarizeFrame(f))
1551 }
1552 err = sc.processFrame(f)
1553 if err == nil {
1554 return true
1555 }
1556 }
1557
1558 switch ev := err.(type) {
1559 case StreamError:
1560 sc.resetStream(ev)
1561 return true
1562 case goAwayFlowError:
1563 sc.goAway(ErrCodeFlowControl)
1564 return true
1565 case ConnectionError:
mgouda64be8822025-05-30 10:44:00 +05301566 if res.f != nil {
1567 if id := res.f.Header().StreamID; id > sc.maxClientStreamID {
1568 sc.maxClientStreamID = id
1569 }
1570 }
khenaidooac637102019-01-14 15:44:34 -05001571 sc.logf("http2: server connection error from %v: %v", sc.conn.RemoteAddr(), ev)
1572 sc.goAway(ErrCode(ev))
1573 return true // goAway will handle shutdown
1574 default:
1575 if res.err != nil {
1576 sc.vlogf("http2: server closing client connection; error reading frame from client %s: %v", sc.conn.RemoteAddr(), err)
1577 } else {
1578 sc.logf("http2: server closing client connection: %v", err)
1579 }
1580 return false
1581 }
1582}
1583
1584func (sc *serverConn) processFrame(f Frame) error {
1585 sc.serveG.check()
1586
1587 // First frame received must be SETTINGS.
1588 if !sc.sawFirstSettings {
1589 if _, ok := f.(*SettingsFrame); !ok {
mgouda64be8822025-05-30 10:44:00 +05301590 return sc.countError("first_settings", ConnectionError(ErrCodeProtocol))
khenaidooac637102019-01-14 15:44:34 -05001591 }
1592 sc.sawFirstSettings = true
1593 }
1594
mgouda64be8822025-05-30 10:44:00 +05301595 // Discard frames for streams initiated after the identified last
1596 // stream sent in a GOAWAY, or all frames after sending an error.
1597 // We still need to return connection-level flow control for DATA frames.
1598 // RFC 9113 Section 6.8.
1599 if sc.inGoAway && (sc.goAwayCode != ErrCodeNo || f.Header().StreamID > sc.maxClientStreamID) {
1600
1601 if f, ok := f.(*DataFrame); ok {
1602 if !sc.inflow.take(f.Length) {
1603 return sc.countError("data_flow", streamError(f.Header().StreamID, ErrCodeFlowControl))
1604 }
1605 sc.sendWindowUpdate(nil, int(f.Length)) // conn-level
1606 }
1607 return nil
1608 }
1609
khenaidooac637102019-01-14 15:44:34 -05001610 switch f := f.(type) {
1611 case *SettingsFrame:
1612 return sc.processSettings(f)
1613 case *MetaHeadersFrame:
1614 return sc.processHeaders(f)
1615 case *WindowUpdateFrame:
1616 return sc.processWindowUpdate(f)
1617 case *PingFrame:
1618 return sc.processPing(f)
1619 case *DataFrame:
1620 return sc.processData(f)
1621 case *RSTStreamFrame:
1622 return sc.processResetStream(f)
1623 case *PriorityFrame:
1624 return sc.processPriority(f)
1625 case *GoAwayFrame:
1626 return sc.processGoAway(f)
1627 case *PushPromiseFrame:
1628 // A client cannot push. Thus, servers MUST treat the receipt of a PUSH_PROMISE
1629 // frame as a connection error (Section 5.4.1) of type PROTOCOL_ERROR.
mgouda64be8822025-05-30 10:44:00 +05301630 return sc.countError("push_promise", ConnectionError(ErrCodeProtocol))
khenaidooac637102019-01-14 15:44:34 -05001631 default:
1632 sc.vlogf("http2: server ignoring frame: %v", f.Header())
1633 return nil
1634 }
1635}
1636
1637func (sc *serverConn) processPing(f *PingFrame) error {
1638 sc.serveG.check()
1639 if f.IsAck() {
mgouda64be8822025-05-30 10:44:00 +05301640 if sc.pingSent && sc.sentPingData == f.Data {
1641 // This is a response to a PING we sent.
1642 sc.pingSent = false
1643 sc.readIdleTimer.Reset(sc.readIdleTimeout)
1644 }
khenaidooac637102019-01-14 15:44:34 -05001645 // 6.7 PING: " An endpoint MUST NOT respond to PING frames
1646 // containing this flag."
1647 return nil
1648 }
1649 if f.StreamID != 0 {
1650 // "PING frames are not associated with any individual
1651 // stream. If a PING frame is received with a stream
1652 // identifier field value other than 0x0, the recipient MUST
1653 // respond with a connection error (Section 5.4.1) of type
1654 // PROTOCOL_ERROR."
mgouda64be8822025-05-30 10:44:00 +05301655 return sc.countError("ping_on_stream", ConnectionError(ErrCodeProtocol))
khenaidooac637102019-01-14 15:44:34 -05001656 }
1657 sc.writeFrame(FrameWriteRequest{write: writePingAck{f}})
1658 return nil
1659}
1660
1661func (sc *serverConn) processWindowUpdate(f *WindowUpdateFrame) error {
1662 sc.serveG.check()
1663 switch {
1664 case f.StreamID != 0: // stream-level flow control
1665 state, st := sc.state(f.StreamID)
1666 if state == stateIdle {
1667 // Section 5.1: "Receiving any frame other than HEADERS
1668 // or PRIORITY on a stream in this state MUST be
1669 // treated as a connection error (Section 5.4.1) of
1670 // type PROTOCOL_ERROR."
mgouda64be8822025-05-30 10:44:00 +05301671 return sc.countError("stream_idle", ConnectionError(ErrCodeProtocol))
khenaidooac637102019-01-14 15:44:34 -05001672 }
1673 if st == nil {
1674 // "WINDOW_UPDATE can be sent by a peer that has sent a
1675 // frame bearing the END_STREAM flag. This means that a
1676 // receiver could receive a WINDOW_UPDATE frame on a "half
1677 // closed (remote)" or "closed" stream. A receiver MUST
1678 // NOT treat this as an error, see Section 5.1."
1679 return nil
1680 }
1681 if !st.flow.add(int32(f.Increment)) {
mgouda64be8822025-05-30 10:44:00 +05301682 return sc.countError("bad_flow", streamError(f.StreamID, ErrCodeFlowControl))
khenaidooac637102019-01-14 15:44:34 -05001683 }
1684 default: // connection-level flow control
1685 if !sc.flow.add(int32(f.Increment)) {
1686 return goAwayFlowError{}
1687 }
1688 }
1689 sc.scheduleFrameWrite()
1690 return nil
1691}
1692
1693func (sc *serverConn) processResetStream(f *RSTStreamFrame) error {
1694 sc.serveG.check()
1695
1696 state, st := sc.state(f.StreamID)
1697 if state == stateIdle {
1698 // 6.4 "RST_STREAM frames MUST NOT be sent for a
1699 // stream in the "idle" state. If a RST_STREAM frame
1700 // identifying an idle stream is received, the
1701 // recipient MUST treat this as a connection error
1702 // (Section 5.4.1) of type PROTOCOL_ERROR.
mgouda64be8822025-05-30 10:44:00 +05301703 return sc.countError("reset_idle_stream", ConnectionError(ErrCodeProtocol))
khenaidooac637102019-01-14 15:44:34 -05001704 }
1705 if st != nil {
1706 st.cancelCtx()
1707 sc.closeStream(st, streamError(f.StreamID, f.ErrCode))
1708 }
1709 return nil
1710}
1711
1712func (sc *serverConn) closeStream(st *stream, err error) {
1713 sc.serveG.check()
1714 if st.state == stateIdle || st.state == stateClosed {
1715 panic(fmt.Sprintf("invariant; can't close stream in state %v", st.state))
1716 }
1717 st.state = stateClosed
mgouda64be8822025-05-30 10:44:00 +05301718 if st.readDeadline != nil {
1719 st.readDeadline.Stop()
1720 }
khenaidooac637102019-01-14 15:44:34 -05001721 if st.writeDeadline != nil {
1722 st.writeDeadline.Stop()
1723 }
1724 if st.isPushed() {
1725 sc.curPushedStreams--
1726 } else {
1727 sc.curClientStreams--
1728 }
1729 delete(sc.streams, st.id)
1730 if len(sc.streams) == 0 {
1731 sc.setConnState(http.StateIdle)
mgouda64be8822025-05-30 10:44:00 +05301732 if sc.srv.IdleTimeout > 0 && sc.idleTimer != nil {
khenaidooac637102019-01-14 15:44:34 -05001733 sc.idleTimer.Reset(sc.srv.IdleTimeout)
1734 }
1735 if h1ServerKeepAlivesDisabled(sc.hs) {
1736 sc.startGracefulShutdownInternal()
1737 }
1738 }
1739 if p := st.body; p != nil {
1740 // Return any buffered unread bytes worth of conn-level flow control.
1741 // See golang.org/issue/16481
1742 sc.sendWindowUpdate(nil, p.Len())
1743
1744 p.CloseWithError(err)
1745 }
mgouda64be8822025-05-30 10:44:00 +05301746 if e, ok := err.(StreamError); ok {
1747 if e.Cause != nil {
1748 err = e.Cause
1749 } else {
1750 err = errStreamClosed
1751 }
1752 }
1753 st.closeErr = err
1754 st.cancelCtx()
khenaidooac637102019-01-14 15:44:34 -05001755 st.cw.Close() // signals Handler's CloseNotifier, unblocks writes, etc
1756 sc.writeSched.CloseStream(st.id)
1757}
1758
1759func (sc *serverConn) processSettings(f *SettingsFrame) error {
1760 sc.serveG.check()
1761 if f.IsAck() {
1762 sc.unackedSettings--
1763 if sc.unackedSettings < 0 {
1764 // Why is the peer ACKing settings we never sent?
1765 // The spec doesn't mention this case, but
1766 // hang up on them anyway.
mgouda64be8822025-05-30 10:44:00 +05301767 return sc.countError("ack_mystery", ConnectionError(ErrCodeProtocol))
khenaidooac637102019-01-14 15:44:34 -05001768 }
1769 return nil
1770 }
1771 if f.NumSettings() > 100 || f.HasDuplicates() {
1772 // This isn't actually in the spec, but hang up on
1773 // suspiciously large settings frames or those with
1774 // duplicate entries.
mgouda64be8822025-05-30 10:44:00 +05301775 return sc.countError("settings_big_or_dups", ConnectionError(ErrCodeProtocol))
khenaidooac637102019-01-14 15:44:34 -05001776 }
1777 if err := f.ForeachSetting(sc.processSetting); err != nil {
1778 return err
1779 }
Scott Baker8461e152019-10-01 14:44:30 -07001780 // TODO: judging by RFC 7540, Section 6.5.3 each SETTINGS frame should be
1781 // acknowledged individually, even if multiple are received before the ACK.
khenaidooac637102019-01-14 15:44:34 -05001782 sc.needToSendSettingsAck = true
1783 sc.scheduleFrameWrite()
1784 return nil
1785}
1786
1787func (sc *serverConn) processSetting(s Setting) error {
1788 sc.serveG.check()
1789 if err := s.Valid(); err != nil {
1790 return err
1791 }
1792 if VerboseLogs {
1793 sc.vlogf("http2: server processing setting %v", s)
1794 }
1795 switch s.ID {
1796 case SettingHeaderTableSize:
khenaidooac637102019-01-14 15:44:34 -05001797 sc.hpackEncoder.SetMaxDynamicTableSize(s.Val)
1798 case SettingEnablePush:
1799 sc.pushEnabled = s.Val != 0
1800 case SettingMaxConcurrentStreams:
1801 sc.clientMaxStreams = s.Val
1802 case SettingInitialWindowSize:
1803 return sc.processSettingInitialWindowSize(s.Val)
1804 case SettingMaxFrameSize:
1805 sc.maxFrameSize = int32(s.Val) // the maximum valid s.Val is < 2^31
1806 case SettingMaxHeaderListSize:
1807 sc.peerMaxHeaderListSize = s.Val
mgouda64be8822025-05-30 10:44:00 +05301808 case SettingEnableConnectProtocol:
1809 // Receipt of this parameter by a server does not
1810 // have any impact
khenaidooac637102019-01-14 15:44:34 -05001811 default:
1812 // Unknown setting: "An endpoint that receives a SETTINGS
1813 // frame with any unknown or unsupported identifier MUST
1814 // ignore that setting."
1815 if VerboseLogs {
1816 sc.vlogf("http2: server ignoring unknown setting %v", s)
1817 }
1818 }
1819 return nil
1820}
1821
1822func (sc *serverConn) processSettingInitialWindowSize(val uint32) error {
1823 sc.serveG.check()
1824 // Note: val already validated to be within range by
1825 // processSetting's Valid call.
1826
1827 // "A SETTINGS frame can alter the initial flow control window
1828 // size for all current streams. When the value of
1829 // SETTINGS_INITIAL_WINDOW_SIZE changes, a receiver MUST
1830 // adjust the size of all stream flow control windows that it
1831 // maintains by the difference between the new value and the
1832 // old value."
1833 old := sc.initialStreamSendWindowSize
1834 sc.initialStreamSendWindowSize = int32(val)
1835 growth := int32(val) - old // may be negative
1836 for _, st := range sc.streams {
1837 if !st.flow.add(growth) {
1838 // 6.9.2 Initial Flow Control Window Size
1839 // "An endpoint MUST treat a change to
1840 // SETTINGS_INITIAL_WINDOW_SIZE that causes any flow
1841 // control window to exceed the maximum size as a
1842 // connection error (Section 5.4.1) of type
1843 // FLOW_CONTROL_ERROR."
mgouda64be8822025-05-30 10:44:00 +05301844 return sc.countError("setting_win_size", ConnectionError(ErrCodeFlowControl))
khenaidooac637102019-01-14 15:44:34 -05001845 }
1846 }
1847 return nil
1848}
1849
1850func (sc *serverConn) processData(f *DataFrame) error {
1851 sc.serveG.check()
khenaidood948f772021-08-11 17:49:24 -04001852 id := f.Header().StreamID
khenaidooac637102019-01-14 15:44:34 -05001853
khenaidood948f772021-08-11 17:49:24 -04001854 data := f.Data()
khenaidooac637102019-01-14 15:44:34 -05001855 state, st := sc.state(id)
1856 if id == 0 || state == stateIdle {
khenaidood948f772021-08-11 17:49:24 -04001857 // Section 6.1: "DATA frames MUST be associated with a
1858 // stream. If a DATA frame is received whose stream
1859 // identifier field is 0x0, the recipient MUST respond
1860 // with a connection error (Section 5.4.1) of type
1861 // PROTOCOL_ERROR."
1862 //
khenaidooac637102019-01-14 15:44:34 -05001863 // Section 5.1: "Receiving any frame other than HEADERS
1864 // or PRIORITY on a stream in this state MUST be
1865 // treated as a connection error (Section 5.4.1) of
1866 // type PROTOCOL_ERROR."
mgouda64be8822025-05-30 10:44:00 +05301867 return sc.countError("data_on_idle", ConnectionError(ErrCodeProtocol))
khenaidooac637102019-01-14 15:44:34 -05001868 }
khenaidood948f772021-08-11 17:49:24 -04001869
1870 // "If a DATA frame is received whose stream is not in "open"
1871 // or "half closed (local)" state, the recipient MUST respond
1872 // with a stream error (Section 5.4.2) of type STREAM_CLOSED."
khenaidooac637102019-01-14 15:44:34 -05001873 if st == nil || state != stateOpen || st.gotTrailerHeader || st.resetQueued {
1874 // This includes sending a RST_STREAM if the stream is
1875 // in stateHalfClosedLocal (which currently means that
1876 // the http.Handler returned, so it's done reading &
1877 // done writing). Try to stop the client from sending
1878 // more DATA.
1879
1880 // But still enforce their connection-level flow control,
1881 // and return any flow control bytes since we're not going
1882 // to consume them.
mgouda64be8822025-05-30 10:44:00 +05301883 if !sc.inflow.take(f.Length) {
1884 return sc.countError("data_flow", streamError(id, ErrCodeFlowControl))
khenaidooac637102019-01-14 15:44:34 -05001885 }
khenaidooac637102019-01-14 15:44:34 -05001886 sc.sendWindowUpdate(nil, int(f.Length)) // conn-level
1887
1888 if st != nil && st.resetQueued {
1889 // Already have a stream error in flight. Don't send another.
1890 return nil
1891 }
mgouda64be8822025-05-30 10:44:00 +05301892 return sc.countError("closed", streamError(id, ErrCodeStreamClosed))
khenaidooac637102019-01-14 15:44:34 -05001893 }
1894 if st.body == nil {
1895 panic("internal error: should have a body in this state")
1896 }
1897
1898 // Sender sending more than they'd declared?
1899 if st.declBodyBytes != -1 && st.bodyBytes+int64(len(data)) > st.declBodyBytes {
mgouda64be8822025-05-30 10:44:00 +05301900 if !sc.inflow.take(f.Length) {
1901 return sc.countError("data_flow", streamError(id, ErrCodeFlowControl))
1902 }
1903 sc.sendWindowUpdate(nil, int(f.Length)) // conn-level
1904
khenaidooac637102019-01-14 15:44:34 -05001905 st.body.CloseWithError(fmt.Errorf("sender tried to send more than declared Content-Length of %d bytes", st.declBodyBytes))
1906 // RFC 7540, sec 8.1.2.6: A request or response is also malformed if the
1907 // value of a content-length header field does not equal the sum of the
1908 // DATA frame payload lengths that form the body.
mgouda64be8822025-05-30 10:44:00 +05301909 return sc.countError("send_too_much", streamError(id, ErrCodeProtocol))
khenaidooac637102019-01-14 15:44:34 -05001910 }
1911 if f.Length > 0 {
1912 // Check whether the client has flow control quota.
mgouda64be8822025-05-30 10:44:00 +05301913 if !takeInflows(&sc.inflow, &st.inflow, f.Length) {
1914 return sc.countError("flow_on_data_length", streamError(id, ErrCodeFlowControl))
khenaidooac637102019-01-14 15:44:34 -05001915 }
khenaidooac637102019-01-14 15:44:34 -05001916
1917 if len(data) > 0 {
mgouda64be8822025-05-30 10:44:00 +05301918 st.bodyBytes += int64(len(data))
khenaidooac637102019-01-14 15:44:34 -05001919 wrote, err := st.body.Write(data)
1920 if err != nil {
mgouda64be8822025-05-30 10:44:00 +05301921 // The handler has closed the request body.
1922 // Return the connection-level flow control for the discarded data,
1923 // but not the stream-level flow control.
Andrea Campanella3614a922021-02-25 12:40:42 +01001924 sc.sendWindowUpdate(nil, int(f.Length)-wrote)
mgouda64be8822025-05-30 10:44:00 +05301925 return nil
khenaidooac637102019-01-14 15:44:34 -05001926 }
1927 if wrote != len(data) {
1928 panic("internal error: bad Writer")
1929 }
khenaidooac637102019-01-14 15:44:34 -05001930 }
1931
1932 // Return any padded flow control now, since we won't
1933 // refund it later on body reads.
mgouda64be8822025-05-30 10:44:00 +05301934 // Call sendWindowUpdate even if there is no padding,
1935 // to return buffered flow control credit if the sent
1936 // window has shrunk.
1937 pad := int32(f.Length) - int32(len(data))
1938 sc.sendWindowUpdate32(nil, pad)
1939 sc.sendWindowUpdate32(st, pad)
khenaidooac637102019-01-14 15:44:34 -05001940 }
1941 if f.StreamEnded() {
1942 st.endStream()
1943 }
1944 return nil
1945}
1946
1947func (sc *serverConn) processGoAway(f *GoAwayFrame) error {
1948 sc.serveG.check()
1949 if f.ErrCode != ErrCodeNo {
1950 sc.logf("http2: received GOAWAY %+v, starting graceful shutdown", f)
1951 } else {
1952 sc.vlogf("http2: received GOAWAY %+v, starting graceful shutdown", f)
1953 }
1954 sc.startGracefulShutdownInternal()
1955 // http://tools.ietf.org/html/rfc7540#section-6.8
1956 // We should not create any new streams, which means we should disable push.
1957 sc.pushEnabled = false
1958 return nil
1959}
1960
1961// isPushed reports whether the stream is server-initiated.
1962func (st *stream) isPushed() bool {
1963 return st.id%2 == 0
1964}
1965
1966// endStream closes a Request.Body's pipe. It is called when a DATA
1967// frame says a request body is over (or after trailers).
1968func (st *stream) endStream() {
1969 sc := st.sc
1970 sc.serveG.check()
1971
1972 if st.declBodyBytes != -1 && st.declBodyBytes != st.bodyBytes {
1973 st.body.CloseWithError(fmt.Errorf("request declared a Content-Length of %d but only wrote %d bytes",
1974 st.declBodyBytes, st.bodyBytes))
1975 } else {
1976 st.body.closeWithErrorAndCode(io.EOF, st.copyTrailersToHandlerRequest)
1977 st.body.CloseWithError(io.EOF)
1978 }
1979 st.state = stateHalfClosedRemote
1980}
1981
1982// copyTrailersToHandlerRequest is run in the Handler's goroutine in
1983// its Request.Body.Read just before it gets io.EOF.
1984func (st *stream) copyTrailersToHandlerRequest() {
1985 for k, vv := range st.trailer {
1986 if _, ok := st.reqTrailer[k]; ok {
1987 // Only copy it over it was pre-declared.
1988 st.reqTrailer[k] = vv
1989 }
1990 }
1991}
1992
mgouda64be8822025-05-30 10:44:00 +05301993// onReadTimeout is run on its own goroutine (from time.AfterFunc)
1994// when the stream's ReadTimeout has fired.
1995func (st *stream) onReadTimeout() {
1996 if st.body != nil {
1997 // Wrap the ErrDeadlineExceeded to avoid callers depending on us
1998 // returning the bare error.
1999 st.body.CloseWithError(fmt.Errorf("%w", os.ErrDeadlineExceeded))
2000 }
2001}
2002
khenaidooac637102019-01-14 15:44:34 -05002003// onWriteTimeout is run on its own goroutine (from time.AfterFunc)
2004// when the stream's WriteTimeout has fired.
2005func (st *stream) onWriteTimeout() {
mgouda64be8822025-05-30 10:44:00 +05302006 st.sc.writeFrameFromHandler(FrameWriteRequest{write: StreamError{
2007 StreamID: st.id,
2008 Code: ErrCodeInternal,
2009 Cause: os.ErrDeadlineExceeded,
2010 }})
khenaidooac637102019-01-14 15:44:34 -05002011}
2012
2013func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error {
2014 sc.serveG.check()
2015 id := f.StreamID
khenaidooac637102019-01-14 15:44:34 -05002016 // http://tools.ietf.org/html/rfc7540#section-5.1.1
2017 // Streams initiated by a client MUST use odd-numbered stream
2018 // identifiers. [...] An endpoint that receives an unexpected
2019 // stream identifier MUST respond with a connection error
2020 // (Section 5.4.1) of type PROTOCOL_ERROR.
2021 if id%2 != 1 {
mgouda64be8822025-05-30 10:44:00 +05302022 return sc.countError("headers_even", ConnectionError(ErrCodeProtocol))
khenaidooac637102019-01-14 15:44:34 -05002023 }
2024 // A HEADERS frame can be used to create a new stream or
2025 // send a trailer for an open one. If we already have a stream
2026 // open, let it process its own HEADERS frame (trailers at this
2027 // point, if it's valid).
2028 if st := sc.streams[f.StreamID]; st != nil {
2029 if st.resetQueued {
2030 // We're sending RST_STREAM to close the stream, so don't bother
2031 // processing this frame.
2032 return nil
2033 }
2034 // RFC 7540, sec 5.1: If an endpoint receives additional frames, other than
2035 // WINDOW_UPDATE, PRIORITY, or RST_STREAM, for a stream that is in
2036 // this state, it MUST respond with a stream error (Section 5.4.2) of
2037 // type STREAM_CLOSED.
2038 if st.state == stateHalfClosedRemote {
mgouda64be8822025-05-30 10:44:00 +05302039 return sc.countError("headers_half_closed", streamError(id, ErrCodeStreamClosed))
khenaidooac637102019-01-14 15:44:34 -05002040 }
2041 return st.processTrailerHeaders(f)
2042 }
2043
2044 // [...] The identifier of a newly established stream MUST be
2045 // numerically greater than all streams that the initiating
2046 // endpoint has opened or reserved. [...] An endpoint that
2047 // receives an unexpected stream identifier MUST respond with
2048 // a connection error (Section 5.4.1) of type PROTOCOL_ERROR.
2049 if id <= sc.maxClientStreamID {
mgouda64be8822025-05-30 10:44:00 +05302050 return sc.countError("stream_went_down", ConnectionError(ErrCodeProtocol))
khenaidooac637102019-01-14 15:44:34 -05002051 }
2052 sc.maxClientStreamID = id
2053
2054 if sc.idleTimer != nil {
2055 sc.idleTimer.Stop()
2056 }
2057
2058 // http://tools.ietf.org/html/rfc7540#section-5.1.2
2059 // [...] Endpoints MUST NOT exceed the limit set by their peer. An
2060 // endpoint that receives a HEADERS frame that causes their
2061 // advertised concurrent stream limit to be exceeded MUST treat
2062 // this as a stream error (Section 5.4.2) of type PROTOCOL_ERROR
2063 // or REFUSED_STREAM.
2064 if sc.curClientStreams+1 > sc.advMaxStreams {
2065 if sc.unackedSettings == 0 {
2066 // They should know better.
mgouda64be8822025-05-30 10:44:00 +05302067 return sc.countError("over_max_streams", streamError(id, ErrCodeProtocol))
khenaidooac637102019-01-14 15:44:34 -05002068 }
2069 // Assume it's a network race, where they just haven't
2070 // received our last SETTINGS update. But actually
2071 // this can't happen yet, because we don't yet provide
2072 // a way for users to adjust server parameters at
2073 // runtime.
mgouda64be8822025-05-30 10:44:00 +05302074 return sc.countError("over_max_streams_race", streamError(id, ErrCodeRefusedStream))
khenaidooac637102019-01-14 15:44:34 -05002075 }
2076
2077 initialState := stateOpen
2078 if f.StreamEnded() {
2079 initialState = stateHalfClosedRemote
2080 }
2081 st := sc.newStream(id, 0, initialState)
2082
2083 if f.HasPriority() {
mgouda64be8822025-05-30 10:44:00 +05302084 if err := sc.checkPriority(f.StreamID, f.Priority); err != nil {
khenaidooac637102019-01-14 15:44:34 -05002085 return err
2086 }
2087 sc.writeSched.AdjustStream(st.id, f.Priority)
2088 }
2089
2090 rw, req, err := sc.newWriterAndRequest(st, f)
2091 if err != nil {
2092 return err
2093 }
2094 st.reqTrailer = req.Trailer
2095 if st.reqTrailer != nil {
2096 st.trailer = make(http.Header)
2097 }
2098 st.body = req.Body.(*requestBody).pipe // may be nil
2099 st.declBodyBytes = req.ContentLength
2100
2101 handler := sc.handler.ServeHTTP
2102 if f.Truncated {
2103 // Their header list was too long. Send a 431 error.
2104 handler = handleHeaderListTooLong
2105 } else if err := checkValidHTTP2RequestHeaders(req.Header); err != nil {
2106 handler = new400Handler(err)
2107 }
2108
2109 // The net/http package sets the read deadline from the
2110 // http.Server.ReadTimeout during the TLS handshake, but then
2111 // passes the connection off to us with the deadline already
2112 // set. Disarm it here after the request headers are read,
2113 // similar to how the http1 server works. Here it's
2114 // technically more like the http1 Server's ReadHeaderTimeout
2115 // (in Go 1.8), though. That's a more sane option anyway.
mgouda64be8822025-05-30 10:44:00 +05302116 if sc.hs.ReadTimeout > 0 {
2117 sc.conn.SetReadDeadline(time.Time{})
2118 st.readDeadline = sc.srv.afterFunc(sc.hs.ReadTimeout, st.onReadTimeout)
2119 }
2120
2121 return sc.scheduleHandler(id, rw, req, handler)
2122}
2123
2124func (sc *serverConn) upgradeRequest(req *http.Request) {
2125 sc.serveG.check()
2126 id := uint32(1)
2127 sc.maxClientStreamID = id
2128 st := sc.newStream(id, 0, stateHalfClosedRemote)
2129 st.reqTrailer = req.Trailer
2130 if st.reqTrailer != nil {
2131 st.trailer = make(http.Header)
2132 }
2133 rw := sc.newResponseWriter(st, req)
2134
2135 // Disable any read deadline set by the net/http package
2136 // prior to the upgrade.
2137 if sc.hs.ReadTimeout > 0 {
khenaidooac637102019-01-14 15:44:34 -05002138 sc.conn.SetReadDeadline(time.Time{})
2139 }
2140
mgouda64be8822025-05-30 10:44:00 +05302141 // This is the first request on the connection,
2142 // so start the handler directly rather than going
2143 // through scheduleHandler.
2144 sc.curHandlers++
2145 go sc.runHandler(rw, req, sc.handler.ServeHTTP)
khenaidooac637102019-01-14 15:44:34 -05002146}
2147
2148func (st *stream) processTrailerHeaders(f *MetaHeadersFrame) error {
2149 sc := st.sc
2150 sc.serveG.check()
2151 if st.gotTrailerHeader {
mgouda64be8822025-05-30 10:44:00 +05302152 return sc.countError("dup_trailers", ConnectionError(ErrCodeProtocol))
khenaidooac637102019-01-14 15:44:34 -05002153 }
2154 st.gotTrailerHeader = true
2155 if !f.StreamEnded() {
mgouda64be8822025-05-30 10:44:00 +05302156 return sc.countError("trailers_not_ended", streamError(st.id, ErrCodeProtocol))
khenaidooac637102019-01-14 15:44:34 -05002157 }
2158
2159 if len(f.PseudoFields()) > 0 {
mgouda64be8822025-05-30 10:44:00 +05302160 return sc.countError("trailers_pseudo", streamError(st.id, ErrCodeProtocol))
khenaidooac637102019-01-14 15:44:34 -05002161 }
2162 if st.trailer != nil {
2163 for _, hf := range f.RegularFields() {
2164 key := sc.canonicalHeader(hf.Name)
2165 if !httpguts.ValidTrailerHeader(key) {
2166 // TODO: send more details to the peer somehow. But http2 has
2167 // no way to send debug data at a stream level. Discuss with
2168 // HTTP folk.
mgouda64be8822025-05-30 10:44:00 +05302169 return sc.countError("trailers_bogus", streamError(st.id, ErrCodeProtocol))
khenaidooac637102019-01-14 15:44:34 -05002170 }
2171 st.trailer[key] = append(st.trailer[key], hf.Value)
2172 }
2173 }
2174 st.endStream()
2175 return nil
2176}
2177
mgouda64be8822025-05-30 10:44:00 +05302178func (sc *serverConn) checkPriority(streamID uint32, p PriorityParam) error {
khenaidooac637102019-01-14 15:44:34 -05002179 if streamID == p.StreamDep {
2180 // Section 5.3.1: "A stream cannot depend on itself. An endpoint MUST treat
2181 // this as a stream error (Section 5.4.2) of type PROTOCOL_ERROR."
2182 // Section 5.3.3 says that a stream can depend on one of its dependencies,
2183 // so it's only self-dependencies that are forbidden.
mgouda64be8822025-05-30 10:44:00 +05302184 return sc.countError("priority", streamError(streamID, ErrCodeProtocol))
khenaidooac637102019-01-14 15:44:34 -05002185 }
2186 return nil
2187}
2188
2189func (sc *serverConn) processPriority(f *PriorityFrame) error {
mgouda64be8822025-05-30 10:44:00 +05302190 if err := sc.checkPriority(f.StreamID, f.PriorityParam); err != nil {
khenaidooac637102019-01-14 15:44:34 -05002191 return err
2192 }
2193 sc.writeSched.AdjustStream(f.StreamID, f.PriorityParam)
2194 return nil
2195}
2196
2197func (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream {
2198 sc.serveG.check()
2199 if id == 0 {
2200 panic("internal error: cannot create stream with id 0")
2201 }
2202
2203 ctx, cancelCtx := context.WithCancel(sc.baseCtx)
2204 st := &stream{
2205 sc: sc,
2206 id: id,
2207 state: state,
2208 ctx: ctx,
2209 cancelCtx: cancelCtx,
2210 }
2211 st.cw.Init()
2212 st.flow.conn = &sc.flow // link to conn-level counter
2213 st.flow.add(sc.initialStreamSendWindowSize)
mgouda64be8822025-05-30 10:44:00 +05302214 st.inflow.init(sc.initialStreamRecvWindowSize)
2215 if sc.hs.WriteTimeout > 0 {
2216 st.writeDeadline = sc.srv.afterFunc(sc.hs.WriteTimeout, st.onWriteTimeout)
khenaidooac637102019-01-14 15:44:34 -05002217 }
2218
2219 sc.streams[id] = st
2220 sc.writeSched.OpenStream(st.id, OpenStreamOptions{PusherID: pusherID})
2221 if st.isPushed() {
2222 sc.curPushedStreams++
2223 } else {
2224 sc.curClientStreams++
2225 }
2226 if sc.curOpenStreams() == 1 {
2227 sc.setConnState(http.StateActive)
2228 }
2229
2230 return st
2231}
2232
2233func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*responseWriter, *http.Request, error) {
2234 sc.serveG.check()
2235
mgouda64be8822025-05-30 10:44:00 +05302236 rp := httpcommon.ServerRequestParam{
2237 Method: f.PseudoValue("method"),
2238 Scheme: f.PseudoValue("scheme"),
2239 Authority: f.PseudoValue("authority"),
2240 Path: f.PseudoValue("path"),
2241 Protocol: f.PseudoValue("protocol"),
khenaidooac637102019-01-14 15:44:34 -05002242 }
2243
mgouda64be8822025-05-30 10:44:00 +05302244 // extended connect is disabled, so we should not see :protocol
2245 if disableExtendedConnectProtocol && rp.Protocol != "" {
2246 return nil, nil, sc.countError("bad_connect", streamError(f.StreamID, ErrCodeProtocol))
2247 }
2248
2249 isConnect := rp.Method == "CONNECT"
khenaidooac637102019-01-14 15:44:34 -05002250 if isConnect {
mgouda64be8822025-05-30 10:44:00 +05302251 if rp.Protocol == "" && (rp.Path != "" || rp.Scheme != "" || rp.Authority == "") {
2252 return nil, nil, sc.countError("bad_connect", streamError(f.StreamID, ErrCodeProtocol))
khenaidooac637102019-01-14 15:44:34 -05002253 }
mgouda64be8822025-05-30 10:44:00 +05302254 } else if rp.Method == "" || rp.Path == "" || (rp.Scheme != "https" && rp.Scheme != "http") {
khenaidooac637102019-01-14 15:44:34 -05002255 // See 8.1.2.6 Malformed Requests and Responses:
2256 //
2257 // Malformed requests or responses that are detected
2258 // MUST be treated as a stream error (Section 5.4.2)
2259 // of type PROTOCOL_ERROR."
2260 //
2261 // 8.1.2.3 Request Pseudo-Header Fields
2262 // "All HTTP/2 requests MUST include exactly one valid
2263 // value for the :method, :scheme, and :path
2264 // pseudo-header fields"
mgouda64be8822025-05-30 10:44:00 +05302265 return nil, nil, sc.countError("bad_path_method", streamError(f.StreamID, ErrCodeProtocol))
khenaidooac637102019-01-14 15:44:34 -05002266 }
2267
mgouda64be8822025-05-30 10:44:00 +05302268 header := make(http.Header)
2269 rp.Header = header
khenaidooac637102019-01-14 15:44:34 -05002270 for _, hf := range f.RegularFields() {
mgouda64be8822025-05-30 10:44:00 +05302271 header.Add(sc.canonicalHeader(hf.Name), hf.Value)
khenaidooac637102019-01-14 15:44:34 -05002272 }
mgouda64be8822025-05-30 10:44:00 +05302273 if rp.Authority == "" {
2274 rp.Authority = header.Get("Host")
2275 }
2276 if rp.Protocol != "" {
2277 header.Set(":protocol", rp.Protocol)
khenaidooac637102019-01-14 15:44:34 -05002278 }
2279
2280 rw, req, err := sc.newWriterAndRequestNoBody(st, rp)
2281 if err != nil {
2282 return nil, nil, err
2283 }
mgouda64be8822025-05-30 10:44:00 +05302284 bodyOpen := !f.StreamEnded()
khenaidooac637102019-01-14 15:44:34 -05002285 if bodyOpen {
mgouda64be8822025-05-30 10:44:00 +05302286 if vv, ok := rp.Header["Content-Length"]; ok {
Andrea Campanella3614a922021-02-25 12:40:42 +01002287 if cl, err := strconv.ParseUint(vv[0], 10, 63); err == nil {
2288 req.ContentLength = int64(cl)
2289 } else {
2290 req.ContentLength = 0
2291 }
khenaidooac637102019-01-14 15:44:34 -05002292 } else {
2293 req.ContentLength = -1
2294 }
2295 req.Body.(*requestBody).pipe = &pipe{
2296 b: &dataBuffer{expected: req.ContentLength},
2297 }
2298 }
2299 return rw, req, nil
2300}
2301
mgouda64be8822025-05-30 10:44:00 +05302302func (sc *serverConn) newWriterAndRequestNoBody(st *stream, rp httpcommon.ServerRequestParam) (*responseWriter, *http.Request, error) {
khenaidooac637102019-01-14 15:44:34 -05002303 sc.serveG.check()
2304
2305 var tlsState *tls.ConnectionState // nil if not scheme https
mgouda64be8822025-05-30 10:44:00 +05302306 if rp.Scheme == "https" {
khenaidooac637102019-01-14 15:44:34 -05002307 tlsState = sc.tlsState
2308 }
2309
mgouda64be8822025-05-30 10:44:00 +05302310 res := httpcommon.NewServerRequest(rp)
2311 if res.InvalidReason != "" {
2312 return nil, nil, sc.countError(res.InvalidReason, streamError(st.id, ErrCodeProtocol))
khenaidooac637102019-01-14 15:44:34 -05002313 }
2314
2315 body := &requestBody{
2316 conn: sc,
2317 stream: st,
mgouda64be8822025-05-30 10:44:00 +05302318 needsContinue: res.NeedsContinue,
khenaidooac637102019-01-14 15:44:34 -05002319 }
mgouda64be8822025-05-30 10:44:00 +05302320 req := (&http.Request{
2321 Method: rp.Method,
2322 URL: res.URL,
khenaidooac637102019-01-14 15:44:34 -05002323 RemoteAddr: sc.remoteAddrStr,
mgouda64be8822025-05-30 10:44:00 +05302324 Header: rp.Header,
2325 RequestURI: res.RequestURI,
khenaidooac637102019-01-14 15:44:34 -05002326 Proto: "HTTP/2.0",
2327 ProtoMajor: 2,
2328 ProtoMinor: 0,
2329 TLS: tlsState,
mgouda64be8822025-05-30 10:44:00 +05302330 Host: rp.Authority,
khenaidooac637102019-01-14 15:44:34 -05002331 Body: body,
mgouda64be8822025-05-30 10:44:00 +05302332 Trailer: res.Trailer,
2333 }).WithContext(st.ctx)
2334 rw := sc.newResponseWriter(st, req)
2335 return rw, req, nil
2336}
khenaidooac637102019-01-14 15:44:34 -05002337
mgouda64be8822025-05-30 10:44:00 +05302338func (sc *serverConn) newResponseWriter(st *stream, req *http.Request) *responseWriter {
khenaidooac637102019-01-14 15:44:34 -05002339 rws := responseWriterStatePool.Get().(*responseWriterState)
2340 bwSave := rws.bw
2341 *rws = responseWriterState{} // zero all the fields
2342 rws.conn = sc
2343 rws.bw = bwSave
2344 rws.bw.Reset(chunkWriter{rws})
2345 rws.stream = st
2346 rws.req = req
mgouda64be8822025-05-30 10:44:00 +05302347 return &responseWriter{rws: rws}
2348}
khenaidooac637102019-01-14 15:44:34 -05002349
mgouda64be8822025-05-30 10:44:00 +05302350type unstartedHandler struct {
2351 streamID uint32
2352 rw *responseWriter
2353 req *http.Request
2354 handler func(http.ResponseWriter, *http.Request)
2355}
2356
2357// scheduleHandler starts a handler goroutine,
2358// or schedules one to start as soon as an existing handler finishes.
2359func (sc *serverConn) scheduleHandler(streamID uint32, rw *responseWriter, req *http.Request, handler func(http.ResponseWriter, *http.Request)) error {
2360 sc.serveG.check()
2361 maxHandlers := sc.advMaxStreams
2362 if sc.curHandlers < maxHandlers {
2363 sc.curHandlers++
2364 go sc.runHandler(rw, req, handler)
2365 return nil
2366 }
2367 if len(sc.unstartedHandlers) > int(4*sc.advMaxStreams) {
2368 return sc.countError("too_many_early_resets", ConnectionError(ErrCodeEnhanceYourCalm))
2369 }
2370 sc.unstartedHandlers = append(sc.unstartedHandlers, unstartedHandler{
2371 streamID: streamID,
2372 rw: rw,
2373 req: req,
2374 handler: handler,
2375 })
2376 return nil
2377}
2378
2379func (sc *serverConn) handlerDone() {
2380 sc.serveG.check()
2381 sc.curHandlers--
2382 i := 0
2383 maxHandlers := sc.advMaxStreams
2384 for ; i < len(sc.unstartedHandlers); i++ {
2385 u := sc.unstartedHandlers[i]
2386 if sc.streams[u.streamID] == nil {
2387 // This stream was reset before its goroutine had a chance to start.
2388 continue
2389 }
2390 if sc.curHandlers >= maxHandlers {
2391 break
2392 }
2393 sc.curHandlers++
2394 go sc.runHandler(u.rw, u.req, u.handler)
2395 sc.unstartedHandlers[i] = unstartedHandler{} // don't retain references
2396 }
2397 sc.unstartedHandlers = sc.unstartedHandlers[i:]
2398 if len(sc.unstartedHandlers) == 0 {
2399 sc.unstartedHandlers = nil
2400 }
khenaidooac637102019-01-14 15:44:34 -05002401}
2402
2403// Run on its own goroutine.
2404func (sc *serverConn) runHandler(rw *responseWriter, req *http.Request, handler func(http.ResponseWriter, *http.Request)) {
mgouda64be8822025-05-30 10:44:00 +05302405 sc.srv.markNewGoroutine()
2406 defer sc.sendServeMsg(handlerDoneMsg)
khenaidooac637102019-01-14 15:44:34 -05002407 didPanic := true
2408 defer func() {
2409 rw.rws.stream.cancelCtx()
mgouda64be8822025-05-30 10:44:00 +05302410 if req.MultipartForm != nil {
2411 req.MultipartForm.RemoveAll()
2412 }
khenaidooac637102019-01-14 15:44:34 -05002413 if didPanic {
2414 e := recover()
2415 sc.writeFrameFromHandler(FrameWriteRequest{
2416 write: handlerPanicRST{rw.rws.stream.id},
2417 stream: rw.rws.stream,
2418 })
2419 // Same as net/http:
2420 if e != nil && e != http.ErrAbortHandler {
2421 const size = 64 << 10
2422 buf := make([]byte, size)
2423 buf = buf[:runtime.Stack(buf, false)]
2424 sc.logf("http2: panic serving %v: %v\n%s", sc.conn.RemoteAddr(), e, buf)
2425 }
2426 return
2427 }
2428 rw.handlerDone()
2429 }()
2430 handler(rw, req)
2431 didPanic = false
2432}
2433
2434func handleHeaderListTooLong(w http.ResponseWriter, r *http.Request) {
2435 // 10.5.1 Limits on Header Block Size:
2436 // .. "A server that receives a larger header block than it is
2437 // willing to handle can send an HTTP 431 (Request Header Fields Too
2438 // Large) status code"
2439 const statusRequestHeaderFieldsTooLarge = 431 // only in Go 1.6+
2440 w.WriteHeader(statusRequestHeaderFieldsTooLarge)
2441 io.WriteString(w, "<h1>HTTP Error 431</h1><p>Request Header Field(s) Too Large</p>")
2442}
2443
2444// called from handler goroutines.
2445// h may be nil.
2446func (sc *serverConn) writeHeaders(st *stream, headerData *writeResHeaders) error {
2447 sc.serveG.checkNotOn() // NOT on
2448 var errc chan error
2449 if headerData.h != nil {
2450 // If there's a header map (which we don't own), so we have to block on
2451 // waiting for this frame to be written, so an http.Flush mid-handler
2452 // writes out the correct value of keys, before a handler later potentially
2453 // mutates it.
2454 errc = errChanPool.Get().(chan error)
2455 }
2456 if err := sc.writeFrameFromHandler(FrameWriteRequest{
2457 write: headerData,
2458 stream: st,
2459 done: errc,
2460 }); err != nil {
2461 return err
2462 }
2463 if errc != nil {
2464 select {
2465 case err := <-errc:
2466 errChanPool.Put(errc)
2467 return err
2468 case <-sc.doneServing:
2469 return errClientDisconnected
2470 case <-st.cw:
2471 return errStreamClosed
2472 }
2473 }
2474 return nil
2475}
2476
2477// called from handler goroutines.
2478func (sc *serverConn) write100ContinueHeaders(st *stream) {
2479 sc.writeFrameFromHandler(FrameWriteRequest{
2480 write: write100ContinueHeadersFrame{st.id},
2481 stream: st,
2482 })
2483}
2484
2485// A bodyReadMsg tells the server loop that the http.Handler read n
2486// bytes of the DATA from the client on the given stream.
2487type bodyReadMsg struct {
2488 st *stream
2489 n int
2490}
2491
2492// called from handler goroutines.
2493// Notes that the handler for the given stream ID read n bytes of its body
2494// and schedules flow control tokens to be sent.
2495func (sc *serverConn) noteBodyReadFromHandler(st *stream, n int, err error) {
2496 sc.serveG.checkNotOn() // NOT on
2497 if n > 0 {
2498 select {
2499 case sc.bodyReadCh <- bodyReadMsg{st, n}:
2500 case <-sc.doneServing:
2501 }
2502 }
2503}
2504
2505func (sc *serverConn) noteBodyRead(st *stream, n int) {
2506 sc.serveG.check()
2507 sc.sendWindowUpdate(nil, n) // conn-level
2508 if st.state != stateHalfClosedRemote && st.state != stateClosed {
2509 // Don't send this WINDOW_UPDATE if the stream is closed
2510 // remotely.
2511 sc.sendWindowUpdate(st, n)
2512 }
2513}
2514
2515// st may be nil for conn-level
mgouda64be8822025-05-30 10:44:00 +05302516func (sc *serverConn) sendWindowUpdate32(st *stream, n int32) {
2517 sc.sendWindowUpdate(st, int(n))
khenaidooac637102019-01-14 15:44:34 -05002518}
2519
2520// st may be nil for conn-level
mgouda64be8822025-05-30 10:44:00 +05302521func (sc *serverConn) sendWindowUpdate(st *stream, n int) {
khenaidooac637102019-01-14 15:44:34 -05002522 sc.serveG.check()
mgouda64be8822025-05-30 10:44:00 +05302523 var streamID uint32
2524 var send int32
2525 if st == nil {
2526 send = sc.inflow.add(n)
2527 } else {
2528 streamID = st.id
2529 send = st.inflow.add(n)
2530 }
2531 if send == 0 {
khenaidooac637102019-01-14 15:44:34 -05002532 return
2533 }
khenaidooac637102019-01-14 15:44:34 -05002534 sc.writeFrame(FrameWriteRequest{
mgouda64be8822025-05-30 10:44:00 +05302535 write: writeWindowUpdate{streamID: streamID, n: uint32(send)},
khenaidooac637102019-01-14 15:44:34 -05002536 stream: st,
2537 })
khenaidooac637102019-01-14 15:44:34 -05002538}
2539
2540// requestBody is the Handler's Request.Body type.
2541// Read and Close may be called concurrently.
2542type requestBody struct {
Andrea Campanella3614a922021-02-25 12:40:42 +01002543 _ incomparable
khenaidooac637102019-01-14 15:44:34 -05002544 stream *stream
2545 conn *serverConn
mgouda64be8822025-05-30 10:44:00 +05302546 closeOnce sync.Once // for use by Close only
2547 sawEOF bool // for use by Read only
2548 pipe *pipe // non-nil if we have an HTTP entity message body
2549 needsContinue bool // need to send a 100-continue
khenaidooac637102019-01-14 15:44:34 -05002550}
2551
2552func (b *requestBody) Close() error {
mgouda64be8822025-05-30 10:44:00 +05302553 b.closeOnce.Do(func() {
2554 if b.pipe != nil {
2555 b.pipe.BreakWithError(errClosedBody)
2556 }
2557 })
khenaidooac637102019-01-14 15:44:34 -05002558 return nil
2559}
2560
2561func (b *requestBody) Read(p []byte) (n int, err error) {
2562 if b.needsContinue {
2563 b.needsContinue = false
2564 b.conn.write100ContinueHeaders(b.stream)
2565 }
2566 if b.pipe == nil || b.sawEOF {
2567 return 0, io.EOF
2568 }
2569 n, err = b.pipe.Read(p)
2570 if err == io.EOF {
2571 b.sawEOF = true
2572 }
2573 if b.conn == nil && inTests {
2574 return
2575 }
2576 b.conn.noteBodyReadFromHandler(b.stream, n, err)
2577 return
2578}
2579
2580// responseWriter is the http.ResponseWriter implementation. It's
2581// intentionally small (1 pointer wide) to minimize garbage. The
2582// responseWriterState pointer inside is zeroed at the end of a
2583// request (in handlerDone) and calls on the responseWriter thereafter
2584// simply crash (caller's mistake), but the much larger responseWriterState
2585// and buffers are reused between multiple requests.
2586type responseWriter struct {
2587 rws *responseWriterState
2588}
2589
2590// Optional http.ResponseWriter interfaces implemented.
2591var (
2592 _ http.CloseNotifier = (*responseWriter)(nil)
2593 _ http.Flusher = (*responseWriter)(nil)
2594 _ stringWriter = (*responseWriter)(nil)
2595)
2596
2597type responseWriterState struct {
2598 // immutable within a request:
2599 stream *stream
2600 req *http.Request
khenaidooac637102019-01-14 15:44:34 -05002601 conn *serverConn
2602
2603 // TODO: adjust buffer writing sizes based on server config, frame size updates from peer, etc
2604 bw *bufio.Writer // writing to a chunkWriter{this *responseWriterState}
2605
2606 // mutated by http.Handler goroutine:
2607 handlerHeader http.Header // nil until called
2608 snapHeader http.Header // snapshot of handlerHeader at WriteHeader time
2609 trailers []string // set in writeChunk
2610 status int // status code passed to WriteHeader
2611 wroteHeader bool // WriteHeader called (explicitly or implicitly). Not necessarily sent to user yet.
2612 sentHeader bool // have we sent the header frame?
2613 handlerDone bool // handler has finished
khenaidooac637102019-01-14 15:44:34 -05002614
2615 sentContentLen int64 // non-zero if handler set a Content-Length header
2616 wroteBytes int64
2617
2618 closeNotifierMu sync.Mutex // guards closeNotifierCh
2619 closeNotifierCh chan bool // nil until first used
2620}
2621
2622type chunkWriter struct{ rws *responseWriterState }
2623
mgouda64be8822025-05-30 10:44:00 +05302624func (cw chunkWriter) Write(p []byte) (n int, err error) {
2625 n, err = cw.rws.writeChunk(p)
2626 if err == errStreamClosed {
2627 // If writing failed because the stream has been closed,
2628 // return the reason it was closed.
2629 err = cw.rws.stream.closeErr
2630 }
2631 return n, err
2632}
khenaidooac637102019-01-14 15:44:34 -05002633
Scott Baker8461e152019-10-01 14:44:30 -07002634func (rws *responseWriterState) hasTrailers() bool { return len(rws.trailers) > 0 }
2635
2636func (rws *responseWriterState) hasNonemptyTrailers() bool {
2637 for _, trailer := range rws.trailers {
2638 if _, ok := rws.handlerHeader[trailer]; ok {
2639 return true
2640 }
2641 }
2642 return false
2643}
khenaidooac637102019-01-14 15:44:34 -05002644
2645// declareTrailer is called for each Trailer header when the
2646// response header is written. It notes that a header will need to be
2647// written in the trailers at the end of the response.
2648func (rws *responseWriterState) declareTrailer(k string) {
2649 k = http.CanonicalHeaderKey(k)
2650 if !httpguts.ValidTrailerHeader(k) {
2651 // Forbidden by RFC 7230, section 4.1.2.
2652 rws.conn.logf("ignoring invalid trailer %q", k)
2653 return
2654 }
2655 if !strSliceContains(rws.trailers, k) {
2656 rws.trailers = append(rws.trailers, k)
2657 }
2658}
2659
2660// writeChunk writes chunks from the bufio.Writer. But because
2661// bufio.Writer may bypass its chunking, sometimes p may be
2662// arbitrarily large.
2663//
2664// writeChunk is also responsible (on the first chunk) for sending the
2665// HEADER response.
2666func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
2667 if !rws.wroteHeader {
2668 rws.writeHeader(200)
2669 }
2670
mgouda64be8822025-05-30 10:44:00 +05302671 if rws.handlerDone {
2672 rws.promoteUndeclaredTrailers()
2673 }
2674
khenaidooac637102019-01-14 15:44:34 -05002675 isHeadResp := rws.req.Method == "HEAD"
2676 if !rws.sentHeader {
2677 rws.sentHeader = true
2678 var ctype, clen string
2679 if clen = rws.snapHeader.Get("Content-Length"); clen != "" {
2680 rws.snapHeader.Del("Content-Length")
Andrea Campanella3614a922021-02-25 12:40:42 +01002681 if cl, err := strconv.ParseUint(clen, 10, 63); err == nil {
2682 rws.sentContentLen = int64(cl)
khenaidooac637102019-01-14 15:44:34 -05002683 } else {
2684 clen = ""
2685 }
2686 }
mgouda64be8822025-05-30 10:44:00 +05302687 _, hasContentLength := rws.snapHeader["Content-Length"]
2688 if !hasContentLength && clen == "" && rws.handlerDone && bodyAllowedForStatus(rws.status) && (len(p) > 0 || !isHeadResp) {
khenaidooac637102019-01-14 15:44:34 -05002689 clen = strconv.Itoa(len(p))
2690 }
2691 _, hasContentType := rws.snapHeader["Content-Type"]
Andrea Campanella3614a922021-02-25 12:40:42 +01002692 // If the Content-Encoding is non-blank, we shouldn't
2693 // sniff the body. See Issue golang.org/issue/31753.
2694 ce := rws.snapHeader.Get("Content-Encoding")
2695 hasCE := len(ce) > 0
2696 if !hasCE && !hasContentType && bodyAllowedForStatus(rws.status) && len(p) > 0 {
khenaidooac637102019-01-14 15:44:34 -05002697 ctype = http.DetectContentType(p)
2698 }
2699 var date string
2700 if _, ok := rws.snapHeader["Date"]; !ok {
2701 // TODO(bradfitz): be faster here, like net/http? measure.
mgouda64be8822025-05-30 10:44:00 +05302702 date = rws.conn.srv.now().UTC().Format(http.TimeFormat)
khenaidooac637102019-01-14 15:44:34 -05002703 }
2704
2705 for _, v := range rws.snapHeader["Trailer"] {
2706 foreachHeaderElement(v, rws.declareTrailer)
2707 }
2708
2709 // "Connection" headers aren't allowed in HTTP/2 (RFC 7540, 8.1.2.2),
2710 // but respect "Connection" == "close" to mean sending a GOAWAY and tearing
2711 // down the TCP connection when idle, like we do for HTTP/1.
2712 // TODO: remove more Connection-specific header fields here, in addition
2713 // to "Connection".
2714 if _, ok := rws.snapHeader["Connection"]; ok {
2715 v := rws.snapHeader.Get("Connection")
2716 delete(rws.snapHeader, "Connection")
2717 if v == "close" {
2718 rws.conn.startGracefulShutdown()
2719 }
2720 }
2721
2722 endStream := (rws.handlerDone && !rws.hasTrailers() && len(p) == 0) || isHeadResp
2723 err = rws.conn.writeHeaders(rws.stream, &writeResHeaders{
2724 streamID: rws.stream.id,
2725 httpResCode: rws.status,
2726 h: rws.snapHeader,
2727 endStream: endStream,
2728 contentType: ctype,
2729 contentLength: clen,
2730 date: date,
2731 })
2732 if err != nil {
khenaidooac637102019-01-14 15:44:34 -05002733 return 0, err
2734 }
2735 if endStream {
2736 return 0, nil
2737 }
2738 }
2739 if isHeadResp {
2740 return len(p), nil
2741 }
2742 if len(p) == 0 && !rws.handlerDone {
2743 return 0, nil
2744 }
2745
Scott Baker8461e152019-10-01 14:44:30 -07002746 // only send trailers if they have actually been defined by the
2747 // server handler.
2748 hasNonemptyTrailers := rws.hasNonemptyTrailers()
2749 endStream := rws.handlerDone && !hasNonemptyTrailers
khenaidooac637102019-01-14 15:44:34 -05002750 if len(p) > 0 || endStream {
2751 // only send a 0 byte DATA frame if we're ending the stream.
2752 if err := rws.conn.writeDataFromHandler(rws.stream, p, endStream); err != nil {
khenaidooac637102019-01-14 15:44:34 -05002753 return 0, err
2754 }
2755 }
2756
Scott Baker8461e152019-10-01 14:44:30 -07002757 if rws.handlerDone && hasNonemptyTrailers {
khenaidooac637102019-01-14 15:44:34 -05002758 err = rws.conn.writeHeaders(rws.stream, &writeResHeaders{
2759 streamID: rws.stream.id,
2760 h: rws.handlerHeader,
2761 trailers: rws.trailers,
2762 endStream: true,
2763 })
khenaidooac637102019-01-14 15:44:34 -05002764 return len(p), err
2765 }
2766 return len(p), nil
2767}
2768
2769// TrailerPrefix is a magic prefix for ResponseWriter.Header map keys
2770// that, if present, signals that the map entry is actually for
2771// the response trailers, and not the response headers. The prefix
2772// is stripped after the ServeHTTP call finishes and the values are
2773// sent in the trailers.
2774//
2775// This mechanism is intended only for trailers that are not known
2776// prior to the headers being written. If the set of trailers is fixed
2777// or known before the header is written, the normal Go trailers mechanism
2778// is preferred:
mgouda64be8822025-05-30 10:44:00 +05302779//
2780// https://golang.org/pkg/net/http/#ResponseWriter
2781// https://golang.org/pkg/net/http/#example_ResponseWriter_trailers
khenaidooac637102019-01-14 15:44:34 -05002782const TrailerPrefix = "Trailer:"
2783
2784// promoteUndeclaredTrailers permits http.Handlers to set trailers
2785// after the header has already been flushed. Because the Go
2786// ResponseWriter interface has no way to set Trailers (only the
2787// Header), and because we didn't want to expand the ResponseWriter
2788// interface, and because nobody used trailers, and because RFC 7230
2789// says you SHOULD (but not must) predeclare any trailers in the
2790// header, the official ResponseWriter rules said trailers in Go must
2791// be predeclared, and then we reuse the same ResponseWriter.Header()
2792// map to mean both Headers and Trailers. When it's time to write the
2793// Trailers, we pick out the fields of Headers that were declared as
2794// trailers. That worked for a while, until we found the first major
2795// user of Trailers in the wild: gRPC (using them only over http2),
2796// and gRPC libraries permit setting trailers mid-stream without
Scott Baker8461e152019-10-01 14:44:30 -07002797// predeclaring them. So: change of plans. We still permit the old
khenaidooac637102019-01-14 15:44:34 -05002798// way, but we also permit this hack: if a Header() key begins with
2799// "Trailer:", the suffix of that key is a Trailer. Because ':' is an
2800// invalid token byte anyway, there is no ambiguity. (And it's already
2801// filtered out) It's mildly hacky, but not terrible.
2802//
2803// This method runs after the Handler is done and promotes any Header
2804// fields to be trailers.
2805func (rws *responseWriterState) promoteUndeclaredTrailers() {
2806 for k, vv := range rws.handlerHeader {
2807 if !strings.HasPrefix(k, TrailerPrefix) {
2808 continue
2809 }
2810 trailerKey := strings.TrimPrefix(k, TrailerPrefix)
2811 rws.declareTrailer(trailerKey)
2812 rws.handlerHeader[http.CanonicalHeaderKey(trailerKey)] = vv
2813 }
2814
2815 if len(rws.trailers) > 1 {
2816 sorter := sorterPool.Get().(*sorter)
2817 sorter.SortStrings(rws.trailers)
2818 sorterPool.Put(sorter)
2819 }
2820}
2821
mgouda64be8822025-05-30 10:44:00 +05302822func (w *responseWriter) SetReadDeadline(deadline time.Time) error {
2823 st := w.rws.stream
2824 if !deadline.IsZero() && deadline.Before(w.rws.conn.srv.now()) {
2825 // If we're setting a deadline in the past, reset the stream immediately
2826 // so writes after SetWriteDeadline returns will fail.
2827 st.onReadTimeout()
2828 return nil
2829 }
2830 w.rws.conn.sendServeMsg(func(sc *serverConn) {
2831 if st.readDeadline != nil {
2832 if !st.readDeadline.Stop() {
2833 // Deadline already exceeded, or stream has been closed.
2834 return
2835 }
2836 }
2837 if deadline.IsZero() {
2838 st.readDeadline = nil
2839 } else if st.readDeadline == nil {
2840 st.readDeadline = sc.srv.afterFunc(deadline.Sub(sc.srv.now()), st.onReadTimeout)
2841 } else {
2842 st.readDeadline.Reset(deadline.Sub(sc.srv.now()))
2843 }
2844 })
2845 return nil
2846}
2847
2848func (w *responseWriter) SetWriteDeadline(deadline time.Time) error {
2849 st := w.rws.stream
2850 if !deadline.IsZero() && deadline.Before(w.rws.conn.srv.now()) {
2851 // If we're setting a deadline in the past, reset the stream immediately
2852 // so writes after SetWriteDeadline returns will fail.
2853 st.onWriteTimeout()
2854 return nil
2855 }
2856 w.rws.conn.sendServeMsg(func(sc *serverConn) {
2857 if st.writeDeadline != nil {
2858 if !st.writeDeadline.Stop() {
2859 // Deadline already exceeded, or stream has been closed.
2860 return
2861 }
2862 }
2863 if deadline.IsZero() {
2864 st.writeDeadline = nil
2865 } else if st.writeDeadline == nil {
2866 st.writeDeadline = sc.srv.afterFunc(deadline.Sub(sc.srv.now()), st.onWriteTimeout)
2867 } else {
2868 st.writeDeadline.Reset(deadline.Sub(sc.srv.now()))
2869 }
2870 })
2871 return nil
2872}
2873
2874func (w *responseWriter) EnableFullDuplex() error {
2875 // We always support full duplex responses, so this is a no-op.
2876 return nil
2877}
2878
khenaidooac637102019-01-14 15:44:34 -05002879func (w *responseWriter) Flush() {
mgouda64be8822025-05-30 10:44:00 +05302880 w.FlushError()
2881}
2882
2883func (w *responseWriter) FlushError() error {
khenaidooac637102019-01-14 15:44:34 -05002884 rws := w.rws
2885 if rws == nil {
2886 panic("Header called after Handler finished")
2887 }
mgouda64be8822025-05-30 10:44:00 +05302888 var err error
khenaidooac637102019-01-14 15:44:34 -05002889 if rws.bw.Buffered() > 0 {
mgouda64be8822025-05-30 10:44:00 +05302890 err = rws.bw.Flush()
khenaidooac637102019-01-14 15:44:34 -05002891 } else {
2892 // The bufio.Writer won't call chunkWriter.Write
mgouda64be8822025-05-30 10:44:00 +05302893 // (writeChunk with zero bytes), so we have to do it
khenaidooac637102019-01-14 15:44:34 -05002894 // ourselves to force the HTTP response header and/or
2895 // final DATA frame (with END_STREAM) to be sent.
mgouda64be8822025-05-30 10:44:00 +05302896 _, err = chunkWriter{rws}.Write(nil)
2897 if err == nil {
2898 select {
2899 case <-rws.stream.cw:
2900 err = rws.stream.closeErr
2901 default:
2902 }
2903 }
khenaidooac637102019-01-14 15:44:34 -05002904 }
mgouda64be8822025-05-30 10:44:00 +05302905 return err
khenaidooac637102019-01-14 15:44:34 -05002906}
2907
2908func (w *responseWriter) CloseNotify() <-chan bool {
2909 rws := w.rws
2910 if rws == nil {
2911 panic("CloseNotify called after Handler finished")
2912 }
2913 rws.closeNotifierMu.Lock()
2914 ch := rws.closeNotifierCh
2915 if ch == nil {
2916 ch = make(chan bool, 1)
2917 rws.closeNotifierCh = ch
2918 cw := rws.stream.cw
2919 go func() {
2920 cw.Wait() // wait for close
2921 ch <- true
2922 }()
2923 }
2924 rws.closeNotifierMu.Unlock()
2925 return ch
2926}
2927
2928func (w *responseWriter) Header() http.Header {
2929 rws := w.rws
2930 if rws == nil {
2931 panic("Header called after Handler finished")
2932 }
2933 if rws.handlerHeader == nil {
2934 rws.handlerHeader = make(http.Header)
2935 }
2936 return rws.handlerHeader
2937}
2938
2939// checkWriteHeaderCode is a copy of net/http's checkWriteHeaderCode.
2940func checkWriteHeaderCode(code int) {
2941 // Issue 22880: require valid WriteHeader status codes.
2942 // For now we only enforce that it's three digits.
2943 // In the future we might block things over 599 (600 and above aren't defined
mgouda64be8822025-05-30 10:44:00 +05302944 // at http://httpwg.org/specs/rfc7231.html#status.codes).
khenaidooac637102019-01-14 15:44:34 -05002945 // But for now any three digits.
2946 //
2947 // We used to send "HTTP/1.1 000 0" on the wire in responses but there's
2948 // no equivalent bogus thing we can realistically send in HTTP/2,
2949 // so we'll consistently panic instead and help people find their bugs
2950 // early. (We can't return an error from WriteHeader even if we wanted to.)
2951 if code < 100 || code > 999 {
2952 panic(fmt.Sprintf("invalid WriteHeader code %v", code))
2953 }
2954}
2955
2956func (w *responseWriter) WriteHeader(code int) {
2957 rws := w.rws
2958 if rws == nil {
2959 panic("WriteHeader called after Handler finished")
2960 }
2961 rws.writeHeader(code)
2962}
2963
2964func (rws *responseWriterState) writeHeader(code int) {
mgouda64be8822025-05-30 10:44:00 +05302965 if rws.wroteHeader {
2966 return
2967 }
2968
2969 checkWriteHeaderCode(code)
2970
2971 // Handle informational headers
2972 if code >= 100 && code <= 199 {
2973 // Per RFC 8297 we must not clear the current header map
2974 h := rws.handlerHeader
2975
2976 _, cl := h["Content-Length"]
2977 _, te := h["Transfer-Encoding"]
2978 if cl || te {
2979 h = h.Clone()
2980 h.Del("Content-Length")
2981 h.Del("Transfer-Encoding")
khenaidooac637102019-01-14 15:44:34 -05002982 }
mgouda64be8822025-05-30 10:44:00 +05302983
2984 rws.conn.writeHeaders(rws.stream, &writeResHeaders{
2985 streamID: rws.stream.id,
2986 httpResCode: code,
2987 h: h,
2988 endStream: rws.handlerDone && !rws.hasTrailers(),
2989 })
2990
2991 return
2992 }
2993
2994 rws.wroteHeader = true
2995 rws.status = code
2996 if len(rws.handlerHeader) > 0 {
2997 rws.snapHeader = cloneHeader(rws.handlerHeader)
khenaidooac637102019-01-14 15:44:34 -05002998 }
2999}
3000
3001func cloneHeader(h http.Header) http.Header {
3002 h2 := make(http.Header, len(h))
3003 for k, vv := range h {
3004 vv2 := make([]string, len(vv))
3005 copy(vv2, vv)
3006 h2[k] = vv2
3007 }
3008 return h2
3009}
3010
3011// The Life Of A Write is like this:
3012//
3013// * Handler calls w.Write or w.WriteString ->
3014// * -> rws.bw (*bufio.Writer) ->
3015// * (Handler might call Flush)
3016// * -> chunkWriter{rws}
3017// * -> responseWriterState.writeChunk(p []byte)
3018// * -> responseWriterState.writeChunk (most of the magic; see comment there)
3019func (w *responseWriter) Write(p []byte) (n int, err error) {
3020 return w.write(len(p), p, "")
3021}
3022
3023func (w *responseWriter) WriteString(s string) (n int, err error) {
3024 return w.write(len(s), nil, s)
3025}
3026
3027// either dataB or dataS is non-zero.
3028func (w *responseWriter) write(lenData int, dataB []byte, dataS string) (n int, err error) {
3029 rws := w.rws
3030 if rws == nil {
3031 panic("Write called after Handler finished")
3032 }
3033 if !rws.wroteHeader {
3034 w.WriteHeader(200)
3035 }
3036 if !bodyAllowedForStatus(rws.status) {
3037 return 0, http.ErrBodyNotAllowed
3038 }
3039 rws.wroteBytes += int64(len(dataB)) + int64(len(dataS)) // only one can be set
3040 if rws.sentContentLen != 0 && rws.wroteBytes > rws.sentContentLen {
3041 // TODO: send a RST_STREAM
3042 return 0, errors.New("http2: handler wrote more than declared Content-Length")
3043 }
3044
3045 if dataB != nil {
3046 return rws.bw.Write(dataB)
3047 } else {
3048 return rws.bw.WriteString(dataS)
3049 }
3050}
3051
3052func (w *responseWriter) handlerDone() {
3053 rws := w.rws
khenaidooac637102019-01-14 15:44:34 -05003054 rws.handlerDone = true
3055 w.Flush()
3056 w.rws = nil
mgouda64be8822025-05-30 10:44:00 +05303057 responseWriterStatePool.Put(rws)
khenaidooac637102019-01-14 15:44:34 -05003058}
3059
3060// Push errors.
3061var (
3062 ErrRecursivePush = errors.New("http2: recursive push not allowed")
3063 ErrPushLimitReached = errors.New("http2: push would exceed peer's SETTINGS_MAX_CONCURRENT_STREAMS")
3064)
3065
3066var _ http.Pusher = (*responseWriter)(nil)
3067
3068func (w *responseWriter) Push(target string, opts *http.PushOptions) error {
3069 st := w.rws.stream
3070 sc := st.sc
3071 sc.serveG.checkNotOn()
3072
3073 // No recursive pushes: "PUSH_PROMISE frames MUST only be sent on a peer-initiated stream."
3074 // http://tools.ietf.org/html/rfc7540#section-6.6
3075 if st.isPushed() {
3076 return ErrRecursivePush
3077 }
3078
3079 if opts == nil {
3080 opts = new(http.PushOptions)
3081 }
3082
3083 // Default options.
3084 if opts.Method == "" {
3085 opts.Method = "GET"
3086 }
3087 if opts.Header == nil {
3088 opts.Header = http.Header{}
3089 }
3090 wantScheme := "http"
3091 if w.rws.req.TLS != nil {
3092 wantScheme = "https"
3093 }
3094
3095 // Validate the request.
3096 u, err := url.Parse(target)
3097 if err != nil {
3098 return err
3099 }
3100 if u.Scheme == "" {
3101 if !strings.HasPrefix(target, "/") {
3102 return fmt.Errorf("target must be an absolute URL or an absolute path: %q", target)
3103 }
3104 u.Scheme = wantScheme
3105 u.Host = w.rws.req.Host
3106 } else {
3107 if u.Scheme != wantScheme {
3108 return fmt.Errorf("cannot push URL with scheme %q from request with scheme %q", u.Scheme, wantScheme)
3109 }
3110 if u.Host == "" {
3111 return errors.New("URL must have a host")
3112 }
3113 }
3114 for k := range opts.Header {
3115 if strings.HasPrefix(k, ":") {
3116 return fmt.Errorf("promised request headers cannot include pseudo header %q", k)
3117 }
3118 // These headers are meaningful only if the request has a body,
3119 // but PUSH_PROMISE requests cannot have a body.
3120 // http://tools.ietf.org/html/rfc7540#section-8.2
3121 // Also disallow Host, since the promised URL must be absolute.
khenaidood948f772021-08-11 17:49:24 -04003122 if asciiEqualFold(k, "content-length") ||
3123 asciiEqualFold(k, "content-encoding") ||
3124 asciiEqualFold(k, "trailer") ||
3125 asciiEqualFold(k, "te") ||
3126 asciiEqualFold(k, "expect") ||
3127 asciiEqualFold(k, "host") {
khenaidooac637102019-01-14 15:44:34 -05003128 return fmt.Errorf("promised request headers cannot include %q", k)
3129 }
3130 }
3131 if err := checkValidHTTP2RequestHeaders(opts.Header); err != nil {
3132 return err
3133 }
3134
3135 // The RFC effectively limits promised requests to GET and HEAD:
3136 // "Promised requests MUST be cacheable [GET, HEAD, or POST], and MUST be safe [GET or HEAD]"
3137 // http://tools.ietf.org/html/rfc7540#section-8.2
3138 if opts.Method != "GET" && opts.Method != "HEAD" {
3139 return fmt.Errorf("method %q must be GET or HEAD", opts.Method)
3140 }
3141
3142 msg := &startPushRequest{
3143 parent: st,
3144 method: opts.Method,
3145 url: u,
3146 header: cloneHeader(opts.Header),
3147 done: errChanPool.Get().(chan error),
3148 }
3149
3150 select {
3151 case <-sc.doneServing:
3152 return errClientDisconnected
3153 case <-st.cw:
3154 return errStreamClosed
3155 case sc.serveMsgCh <- msg:
3156 }
3157
3158 select {
3159 case <-sc.doneServing:
3160 return errClientDisconnected
3161 case <-st.cw:
3162 return errStreamClosed
3163 case err := <-msg.done:
3164 errChanPool.Put(msg.done)
3165 return err
3166 }
3167}
3168
3169type startPushRequest struct {
3170 parent *stream
3171 method string
3172 url *url.URL
3173 header http.Header
3174 done chan error
3175}
3176
3177func (sc *serverConn) startPush(msg *startPushRequest) {
3178 sc.serveG.check()
3179
3180 // http://tools.ietf.org/html/rfc7540#section-6.6.
3181 // PUSH_PROMISE frames MUST only be sent on a peer-initiated stream that
3182 // is in either the "open" or "half-closed (remote)" state.
3183 if msg.parent.state != stateOpen && msg.parent.state != stateHalfClosedRemote {
Scott Baker8461e152019-10-01 14:44:30 -07003184 // responseWriter.Push checks that the stream is peer-initiated.
khenaidooac637102019-01-14 15:44:34 -05003185 msg.done <- errStreamClosed
3186 return
3187 }
3188
3189 // http://tools.ietf.org/html/rfc7540#section-6.6.
3190 if !sc.pushEnabled {
3191 msg.done <- http.ErrNotSupported
3192 return
3193 }
3194
3195 // PUSH_PROMISE frames must be sent in increasing order by stream ID, so
3196 // we allocate an ID for the promised stream lazily, when the PUSH_PROMISE
3197 // is written. Once the ID is allocated, we start the request handler.
3198 allocatePromisedID := func() (uint32, error) {
3199 sc.serveG.check()
3200
3201 // Check this again, just in case. Technically, we might have received
3202 // an updated SETTINGS by the time we got around to writing this frame.
3203 if !sc.pushEnabled {
3204 return 0, http.ErrNotSupported
3205 }
3206 // http://tools.ietf.org/html/rfc7540#section-6.5.2.
3207 if sc.curPushedStreams+1 > sc.clientMaxStreams {
3208 return 0, ErrPushLimitReached
3209 }
3210
3211 // http://tools.ietf.org/html/rfc7540#section-5.1.1.
3212 // Streams initiated by the server MUST use even-numbered identifiers.
3213 // A server that is unable to establish a new stream identifier can send a GOAWAY
3214 // frame so that the client is forced to open a new connection for new streams.
3215 if sc.maxPushPromiseID+2 >= 1<<31 {
3216 sc.startGracefulShutdownInternal()
3217 return 0, ErrPushLimitReached
3218 }
3219 sc.maxPushPromiseID += 2
3220 promisedID := sc.maxPushPromiseID
3221
3222 // http://tools.ietf.org/html/rfc7540#section-8.2.
3223 // Strictly speaking, the new stream should start in "reserved (local)", then
3224 // transition to "half closed (remote)" after sending the initial HEADERS, but
3225 // we start in "half closed (remote)" for simplicity.
3226 // See further comments at the definition of stateHalfClosedRemote.
3227 promised := sc.newStream(promisedID, msg.parent.id, stateHalfClosedRemote)
mgouda64be8822025-05-30 10:44:00 +05303228 rw, req, err := sc.newWriterAndRequestNoBody(promised, httpcommon.ServerRequestParam{
3229 Method: msg.method,
3230 Scheme: msg.url.Scheme,
3231 Authority: msg.url.Host,
3232 Path: msg.url.RequestURI(),
3233 Header: cloneHeader(msg.header), // clone since handler runs concurrently with writing the PUSH_PROMISE
khenaidooac637102019-01-14 15:44:34 -05003234 })
3235 if err != nil {
3236 // Should not happen, since we've already validated msg.url.
3237 panic(fmt.Sprintf("newWriterAndRequestNoBody(%+v): %v", msg.url, err))
3238 }
3239
mgouda64be8822025-05-30 10:44:00 +05303240 sc.curHandlers++
khenaidooac637102019-01-14 15:44:34 -05003241 go sc.runHandler(rw, req, sc.handler.ServeHTTP)
3242 return promisedID, nil
3243 }
3244
3245 sc.writeFrame(FrameWriteRequest{
3246 write: &writePushPromise{
3247 streamID: msg.parent.id,
3248 method: msg.method,
3249 url: msg.url,
3250 h: msg.header,
3251 allocatePromisedID: allocatePromisedID,
3252 },
3253 stream: msg.parent,
3254 done: msg.done,
3255 })
3256}
3257
3258// foreachHeaderElement splits v according to the "#rule" construction
3259// in RFC 7230 section 7 and calls fn for each non-empty element.
3260func foreachHeaderElement(v string, fn func(string)) {
3261 v = textproto.TrimString(v)
3262 if v == "" {
3263 return
3264 }
3265 if !strings.Contains(v, ",") {
3266 fn(v)
3267 return
3268 }
3269 for _, f := range strings.Split(v, ",") {
3270 if f = textproto.TrimString(f); f != "" {
3271 fn(f)
3272 }
3273 }
3274}
3275
3276// From http://httpwg.org/specs/rfc7540.html#rfc.section.8.1.2.2
3277var connHeaders = []string{
3278 "Connection",
3279 "Keep-Alive",
3280 "Proxy-Connection",
3281 "Transfer-Encoding",
3282 "Upgrade",
3283}
3284
3285// checkValidHTTP2RequestHeaders checks whether h is a valid HTTP/2 request,
3286// per RFC 7540 Section 8.1.2.2.
3287// The returned error is reported to users.
3288func checkValidHTTP2RequestHeaders(h http.Header) error {
3289 for _, k := range connHeaders {
3290 if _, ok := h[k]; ok {
3291 return fmt.Errorf("request header %q is not valid in HTTP/2", k)
3292 }
3293 }
3294 te := h["Te"]
3295 if len(te) > 0 && (len(te) > 1 || (te[0] != "trailers" && te[0] != "")) {
3296 return errors.New(`request header "TE" may only be "trailers" in HTTP/2`)
3297 }
3298 return nil
3299}
3300
3301func new400Handler(err error) http.HandlerFunc {
3302 return func(w http.ResponseWriter, r *http.Request) {
3303 http.Error(w, err.Error(), http.StatusBadRequest)
3304 }
3305}
3306
3307// h1ServerKeepAlivesDisabled reports whether hs has its keep-alives
3308// disabled. See comments on h1ServerShutdownChan above for why
3309// the code is written this way.
3310func h1ServerKeepAlivesDisabled(hs *http.Server) bool {
3311 var x interface{} = hs
3312 type I interface {
3313 doKeepAlives() bool
3314 }
3315 if hs, ok := x.(I); ok {
3316 return !hs.doKeepAlives()
3317 }
3318 return false
3319}
mgouda64be8822025-05-30 10:44:00 +05303320
3321func (sc *serverConn) countError(name string, err error) error {
3322 if sc == nil || sc.srv == nil {
3323 return err
3324 }
3325 f := sc.countErrorFunc
3326 if f == nil {
3327 return err
3328 }
3329 var typ string
3330 var code ErrCode
3331 switch e := err.(type) {
3332 case ConnectionError:
3333 typ = "conn"
3334 code = ErrCode(e)
3335 case StreamError:
3336 typ = "stream"
3337 code = ErrCode(e.Code)
3338 default:
3339 return err
3340 }
3341 codeStr := errCodeName[code]
3342 if codeStr == "" {
3343 codeStr = strconv.Itoa(int(code))
3344 }
3345 f(fmt.Sprintf("%s_%s_%s", typ, codeStr, name))
3346 return err
3347}