blob: e644d9b2f34dc310e8cac27bfc6adabb6017700f [file] [log] [blame]
kesavand2cde6582020-06-22 04:56:23 -04001// 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"
32 "crypto/tls"
33 "errors"
34 "fmt"
35 "io"
36 "log"
37 "math"
38 "net"
39 "net/http"
40 "net/textproto"
41 "net/url"
42 "os"
43 "reflect"
44 "runtime"
45 "strconv"
46 "strings"
47 "sync"
48 "time"
49
50 "golang.org/x/net/http/httpguts"
51 "golang.org/x/net/http2/hpack"
52)
53
54const (
Andrea Campanella764f1ed2022-03-24 11:46:38 +010055 prefaceTimeout = 10 * time.Second
56 firstSettingsTimeout = 2 * time.Second // should be in-flight with preface anyway
57 handlerChunkWriteSize = 4 << 10
58 defaultMaxStreams = 250 // TODO: make this 100 as the GFE seems to?
59 maxQueuedControlFrames = 10000
kesavand2cde6582020-06-22 04:56:23 -040060)
61
62var (
63 errClientDisconnected = errors.New("client disconnected")
64 errClosedBody = errors.New("body closed by handler")
65 errHandlerComplete = errors.New("http2: request body closed due to handler exiting")
66 errStreamClosed = errors.New("http2: stream closed")
67)
68
69var responseWriterStatePool = sync.Pool{
70 New: func() interface{} {
71 rws := &responseWriterState{}
72 rws.bw = bufio.NewWriterSize(chunkWriter{rws}, handlerChunkWriteSize)
73 return rws
74 },
75}
76
77// Test hooks.
78var (
79 testHookOnConn func()
80 testHookGetServerConn func(*serverConn)
81 testHookOnPanicMu *sync.Mutex // nil except in tests
82 testHookOnPanic func(sc *serverConn, panicVal interface{}) (rePanic bool)
83)
84
85// Server is an HTTP/2 server.
86type Server struct {
87 // MaxHandlers limits the number of http.Handler ServeHTTP goroutines
88 // which may run at a time over all connections.
89 // Negative or zero no limit.
90 // TODO: implement
91 MaxHandlers int
92
93 // MaxConcurrentStreams optionally specifies the number of
94 // concurrent streams that each client may have open at a
95 // time. This is unrelated to the number of http.Handler goroutines
96 // which may be active globally, which is MaxHandlers.
97 // If zero, MaxConcurrentStreams defaults to at least 100, per
98 // the HTTP/2 spec's recommendations.
99 MaxConcurrentStreams uint32
100
101 // MaxReadFrameSize optionally specifies the largest frame
102 // this server is willing to read. A valid value is between
103 // 16k and 16M, inclusive. If zero or otherwise invalid, a
104 // default value is used.
105 MaxReadFrameSize uint32
106
107 // PermitProhibitedCipherSuites, if true, permits the use of
108 // cipher suites prohibited by the HTTP/2 spec.
109 PermitProhibitedCipherSuites bool
110
111 // IdleTimeout specifies how long until idle clients should be
112 // closed with a GOAWAY frame. PING frames are not considered
113 // activity for the purposes of IdleTimeout.
114 IdleTimeout time.Duration
115
116 // MaxUploadBufferPerConnection is the size of the initial flow
117 // control window for each connections. The HTTP/2 spec does not
118 // allow this to be smaller than 65535 or larger than 2^32-1.
119 // If the value is outside this range, a default value will be
120 // used instead.
121 MaxUploadBufferPerConnection int32
122
123 // MaxUploadBufferPerStream is the size of the initial flow control
124 // window for each stream. The HTTP/2 spec does not allow this to
125 // be larger than 2^32-1. If the value is zero or larger than the
126 // maximum, a default value will be used instead.
127 MaxUploadBufferPerStream int32
128
129 // NewWriteScheduler constructs a write scheduler for a connection.
130 // If nil, a default scheduler is chosen.
131 NewWriteScheduler func() WriteScheduler
132
kesavandc71914f2022-03-25 11:19:03 +0530133 // CountError, if non-nil, is called on HTTP/2 server errors.
134 // It's intended to increment a metric for monitoring, such
135 // as an expvar or Prometheus metric.
136 // The errType consists of only ASCII word characters.
137 CountError func(errType string)
138
kesavand2cde6582020-06-22 04:56:23 -0400139 // Internal state. This is a pointer (rather than embedded directly)
140 // so that we don't embed a Mutex in this struct, which will make the
141 // struct non-copyable, which might break some callers.
142 state *serverInternalState
143}
144
145func (s *Server) initialConnRecvWindowSize() int32 {
146 if s.MaxUploadBufferPerConnection > initialWindowSize {
147 return s.MaxUploadBufferPerConnection
148 }
149 return 1 << 20
150}
151
152func (s *Server) initialStreamRecvWindowSize() int32 {
153 if s.MaxUploadBufferPerStream > 0 {
154 return s.MaxUploadBufferPerStream
155 }
156 return 1 << 20
157}
158
159func (s *Server) maxReadFrameSize() uint32 {
160 if v := s.MaxReadFrameSize; v >= minMaxFrameSize && v <= maxFrameSize {
161 return v
162 }
163 return defaultMaxReadFrameSize
164}
165
166func (s *Server) maxConcurrentStreams() uint32 {
167 if v := s.MaxConcurrentStreams; v > 0 {
168 return v
169 }
170 return defaultMaxStreams
171}
172
Andrea Campanella764f1ed2022-03-24 11:46:38 +0100173// maxQueuedControlFrames is the maximum number of control frames like
174// SETTINGS, PING and RST_STREAM that will be queued for writing before
175// the connection is closed to prevent memory exhaustion attacks.
176func (s *Server) maxQueuedControlFrames() int {
177 // TODO: if anybody asks, add a Server field, and remember to define the
178 // behavior of negative values.
179 return maxQueuedControlFrames
180}
181
kesavand2cde6582020-06-22 04:56:23 -0400182type serverInternalState struct {
183 mu sync.Mutex
184 activeConns map[*serverConn]struct{}
185}
186
187func (s *serverInternalState) registerConn(sc *serverConn) {
188 if s == nil {
189 return // if the Server was used without calling ConfigureServer
190 }
191 s.mu.Lock()
192 s.activeConns[sc] = struct{}{}
193 s.mu.Unlock()
194}
195
196func (s *serverInternalState) unregisterConn(sc *serverConn) {
197 if s == nil {
198 return // if the Server was used without calling ConfigureServer
199 }
200 s.mu.Lock()
201 delete(s.activeConns, sc)
202 s.mu.Unlock()
203}
204
205func (s *serverInternalState) startGracefulShutdown() {
206 if s == nil {
207 return // if the Server was used without calling ConfigureServer
208 }
209 s.mu.Lock()
210 for sc := range s.activeConns {
211 sc.startGracefulShutdown()
212 }
213 s.mu.Unlock()
214}
215
216// ConfigureServer adds HTTP/2 support to a net/http Server.
217//
218// The configuration conf may be nil.
219//
220// ConfigureServer must be called before s begins serving.
221func ConfigureServer(s *http.Server, conf *Server) error {
222 if s == nil {
223 panic("nil *http.Server")
224 }
225 if conf == nil {
226 conf = new(Server)
227 }
228 conf.state = &serverInternalState{activeConns: make(map[*serverConn]struct{})}
229 if h1, h2 := s, conf; h2.IdleTimeout == 0 {
230 if h1.IdleTimeout != 0 {
231 h2.IdleTimeout = h1.IdleTimeout
232 } else {
233 h2.IdleTimeout = h1.ReadTimeout
234 }
235 }
236 s.RegisterOnShutdown(conf.state.startGracefulShutdown)
237
238 if s.TLSConfig == nil {
239 s.TLSConfig = new(tls.Config)
kesavandc71914f2022-03-25 11:19:03 +0530240 } else if s.TLSConfig.CipherSuites != nil && s.TLSConfig.MinVersion < tls.VersionTLS13 {
241 // If they already provided a TLS 1.0–1.2 CipherSuite list, return an
242 // error if it is missing ECDHE_RSA_WITH_AES_128_GCM_SHA256 or
243 // ECDHE_ECDSA_WITH_AES_128_GCM_SHA256.
kesavand2cde6582020-06-22 04:56:23 -0400244 haveRequired := false
kesavandc71914f2022-03-25 11:19:03 +0530245 for _, cs := range s.TLSConfig.CipherSuites {
kesavand2cde6582020-06-22 04:56:23 -0400246 switch cs {
247 case tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
248 // Alternative MTI cipher to not discourage ECDSA-only servers.
249 // See http://golang.org/cl/30721 for further information.
250 tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
251 haveRequired = true
252 }
kesavand2cde6582020-06-22 04:56:23 -0400253 }
254 if !haveRequired {
kesavandc71914f2022-03-25 11:19:03 +0530255 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)")
kesavand2cde6582020-06-22 04:56:23 -0400256 }
257 }
258
259 // Note: not setting MinVersion to tls.VersionTLS12,
260 // as we don't want to interfere with HTTP/1.1 traffic
261 // on the user's server. We enforce TLS 1.2 later once
262 // we accept a connection. Ideally this should be done
263 // during next-proto selection, but using TLS <1.2 with
264 // HTTP/2 is still the client's bug.
265
266 s.TLSConfig.PreferServerCipherSuites = true
267
kesavandc71914f2022-03-25 11:19:03 +0530268 if !strSliceContains(s.TLSConfig.NextProtos, NextProtoTLS) {
kesavand2cde6582020-06-22 04:56:23 -0400269 s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, NextProtoTLS)
270 }
kesavandc71914f2022-03-25 11:19:03 +0530271 if !strSliceContains(s.TLSConfig.NextProtos, "http/1.1") {
272 s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, "http/1.1")
273 }
kesavand2cde6582020-06-22 04:56:23 -0400274
275 if s.TLSNextProto == nil {
276 s.TLSNextProto = map[string]func(*http.Server, *tls.Conn, http.Handler){}
277 }
278 protoHandler := func(hs *http.Server, c *tls.Conn, h http.Handler) {
279 if testHookOnConn != nil {
280 testHookOnConn()
281 }
282 // The TLSNextProto interface predates contexts, so
283 // the net/http package passes down its per-connection
284 // base context via an exported but unadvertised
285 // method on the Handler. This is for internal
286 // net/http<=>http2 use only.
287 var ctx context.Context
288 type baseContexter interface {
289 BaseContext() context.Context
290 }
291 if bc, ok := h.(baseContexter); ok {
292 ctx = bc.BaseContext()
293 }
294 conf.ServeConn(c, &ServeConnOpts{
295 Context: ctx,
296 Handler: h,
297 BaseConfig: hs,
298 })
299 }
300 s.TLSNextProto[NextProtoTLS] = protoHandler
301 return nil
302}
303
304// ServeConnOpts are options for the Server.ServeConn method.
305type ServeConnOpts struct {
306 // Context is the base context to use.
307 // If nil, context.Background is used.
308 Context context.Context
309
310 // BaseConfig optionally sets the base configuration
311 // for values. If nil, defaults are used.
312 BaseConfig *http.Server
313
314 // Handler specifies which handler to use for processing
315 // requests. If nil, BaseConfig.Handler is used. If BaseConfig
316 // or BaseConfig.Handler is nil, http.DefaultServeMux is used.
317 Handler http.Handler
318}
319
320func (o *ServeConnOpts) context() context.Context {
Andrea Campanella764f1ed2022-03-24 11:46:38 +0100321 if o != nil && o.Context != nil {
kesavand2cde6582020-06-22 04:56:23 -0400322 return o.Context
323 }
324 return context.Background()
325}
326
327func (o *ServeConnOpts) baseConfig() *http.Server {
328 if o != nil && o.BaseConfig != nil {
329 return o.BaseConfig
330 }
331 return new(http.Server)
332}
333
334func (o *ServeConnOpts) handler() http.Handler {
335 if o != nil {
336 if o.Handler != nil {
337 return o.Handler
338 }
339 if o.BaseConfig != nil && o.BaseConfig.Handler != nil {
340 return o.BaseConfig.Handler
341 }
342 }
343 return http.DefaultServeMux
344}
345
346// ServeConn serves HTTP/2 requests on the provided connection and
347// blocks until the connection is no longer readable.
348//
349// ServeConn starts speaking HTTP/2 assuming that c has not had any
350// reads or writes. It writes its initial settings frame and expects
351// to be able to read the preface and settings frame from the
352// client. If c has a ConnectionState method like a *tls.Conn, the
353// ConnectionState is used to verify the TLS ciphersuite and to set
354// the Request.TLS field in Handlers.
355//
356// ServeConn does not support h2c by itself. Any h2c support must be
357// implemented in terms of providing a suitably-behaving net.Conn.
358//
359// The opts parameter is optional. If nil, default values are used.
360func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) {
361 baseCtx, cancel := serverConnBaseContext(c, opts)
362 defer cancel()
363
364 sc := &serverConn{
365 srv: s,
366 hs: opts.baseConfig(),
367 conn: c,
368 baseCtx: baseCtx,
369 remoteAddrStr: c.RemoteAddr().String(),
370 bw: newBufferedWriter(c),
371 handler: opts.handler(),
372 streams: make(map[uint32]*stream),
373 readFrameCh: make(chan readFrameResult),
374 wantWriteFrameCh: make(chan FrameWriteRequest, 8),
375 serveMsgCh: make(chan interface{}, 8),
376 wroteFrameCh: make(chan frameWriteResult, 1), // buffered; one send in writeFrameAsync
377 bodyReadCh: make(chan bodyReadMsg), // buffering doesn't matter either way
378 doneServing: make(chan struct{}),
379 clientMaxStreams: math.MaxUint32, // Section 6.5.2: "Initially, there is no limit to this value"
380 advMaxStreams: s.maxConcurrentStreams(),
381 initialStreamSendWindowSize: initialWindowSize,
382 maxFrameSize: initialMaxFrameSize,
383 headerTableSize: initialHeaderTableSize,
384 serveG: newGoroutineLock(),
385 pushEnabled: true,
386 }
387
388 s.state.registerConn(sc)
389 defer s.state.unregisterConn(sc)
390
391 // The net/http package sets the write deadline from the
392 // http.Server.WriteTimeout during the TLS handshake, but then
393 // passes the connection off to us with the deadline already set.
394 // Write deadlines are set per stream in serverConn.newStream.
395 // Disarm the net.Conn write deadline here.
396 if sc.hs.WriteTimeout != 0 {
397 sc.conn.SetWriteDeadline(time.Time{})
398 }
399
400 if s.NewWriteScheduler != nil {
401 sc.writeSched = s.NewWriteScheduler()
402 } else {
403 sc.writeSched = NewRandomWriteScheduler()
404 }
405
406 // These start at the RFC-specified defaults. If there is a higher
407 // configured value for inflow, that will be updated when we send a
408 // WINDOW_UPDATE shortly after sending SETTINGS.
409 sc.flow.add(initialWindowSize)
410 sc.inflow.add(initialWindowSize)
411 sc.hpackEncoder = hpack.NewEncoder(&sc.headerWriteBuf)
412
413 fr := NewFramer(sc.bw, c)
kesavandc71914f2022-03-25 11:19:03 +0530414 if s.CountError != nil {
415 fr.countError = s.CountError
416 }
kesavand2cde6582020-06-22 04:56:23 -0400417 fr.ReadMetaHeaders = hpack.NewDecoder(initialHeaderTableSize, nil)
418 fr.MaxHeaderListSize = sc.maxHeaderListSize()
419 fr.SetMaxReadFrameSize(s.maxReadFrameSize())
420 sc.framer = fr
421
422 if tc, ok := c.(connectionStater); ok {
423 sc.tlsState = new(tls.ConnectionState)
424 *sc.tlsState = tc.ConnectionState()
425 // 9.2 Use of TLS Features
426 // An implementation of HTTP/2 over TLS MUST use TLS
427 // 1.2 or higher with the restrictions on feature set
428 // and cipher suite described in this section. Due to
429 // implementation limitations, it might not be
430 // possible to fail TLS negotiation. An endpoint MUST
431 // immediately terminate an HTTP/2 connection that
432 // does not meet the TLS requirements described in
433 // this section with a connection error (Section
434 // 5.4.1) of type INADEQUATE_SECURITY.
435 if sc.tlsState.Version < tls.VersionTLS12 {
436 sc.rejectConn(ErrCodeInadequateSecurity, "TLS version too low")
437 return
438 }
439
440 if sc.tlsState.ServerName == "" {
441 // Client must use SNI, but we don't enforce that anymore,
442 // since it was causing problems when connecting to bare IP
443 // addresses during development.
444 //
445 // TODO: optionally enforce? Or enforce at the time we receive
446 // a new request, and verify the ServerName matches the :authority?
447 // But that precludes proxy situations, perhaps.
448 //
449 // So for now, do nothing here again.
450 }
451
452 if !s.PermitProhibitedCipherSuites && isBadCipher(sc.tlsState.CipherSuite) {
453 // "Endpoints MAY choose to generate a connection error
454 // (Section 5.4.1) of type INADEQUATE_SECURITY if one of
455 // the prohibited cipher suites are negotiated."
456 //
457 // We choose that. In my opinion, the spec is weak
458 // here. It also says both parties must support at least
459 // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 so there's no
460 // excuses here. If we really must, we could allow an
461 // "AllowInsecureWeakCiphers" option on the server later.
462 // Let's see how it plays out first.
463 sc.rejectConn(ErrCodeInadequateSecurity, fmt.Sprintf("Prohibited TLS 1.2 Cipher Suite: %x", sc.tlsState.CipherSuite))
464 return
465 }
466 }
467
468 if hook := testHookGetServerConn; hook != nil {
469 hook(sc)
470 }
471 sc.serve()
472}
473
474func serverConnBaseContext(c net.Conn, opts *ServeConnOpts) (ctx context.Context, cancel func()) {
475 ctx, cancel = context.WithCancel(opts.context())
476 ctx = context.WithValue(ctx, http.LocalAddrContextKey, c.LocalAddr())
477 if hs := opts.baseConfig(); hs != nil {
478 ctx = context.WithValue(ctx, http.ServerContextKey, hs)
479 }
480 return
481}
482
483func (sc *serverConn) rejectConn(err ErrCode, debug string) {
484 sc.vlogf("http2: server rejecting conn: %v, %s", err, debug)
485 // ignoring errors. hanging up anyway.
486 sc.framer.WriteGoAway(0, err, []byte(debug))
487 sc.bw.Flush()
488 sc.conn.Close()
489}
490
491type serverConn struct {
492 // Immutable:
493 srv *Server
494 hs *http.Server
495 conn net.Conn
496 bw *bufferedWriter // writing to conn
497 handler http.Handler
498 baseCtx context.Context
499 framer *Framer
500 doneServing chan struct{} // closed when serverConn.serve ends
501 readFrameCh chan readFrameResult // written by serverConn.readFrames
502 wantWriteFrameCh chan FrameWriteRequest // from handlers -> serve
503 wroteFrameCh chan frameWriteResult // from writeFrameAsync -> serve, tickles more frame writes
504 bodyReadCh chan bodyReadMsg // from handlers -> serve
505 serveMsgCh chan interface{} // misc messages & code to send to / run on the serve loop
506 flow flow // conn-wide (not stream-specific) outbound flow control
507 inflow flow // conn-wide inbound flow control
508 tlsState *tls.ConnectionState // shared by all handlers, like net/http
509 remoteAddrStr string
510 writeSched WriteScheduler
511
512 // Everything following is owned by the serve loop; use serveG.check():
513 serveG goroutineLock // used to verify funcs are on serve()
514 pushEnabled bool
515 sawFirstSettings bool // got the initial SETTINGS frame after the preface
516 needToSendSettingsAck bool
517 unackedSettings int // how many SETTINGS have we sent without ACKs?
Andrea Campanella764f1ed2022-03-24 11:46:38 +0100518 queuedControlFrames int // control frames in the writeSched queue
kesavand2cde6582020-06-22 04:56:23 -0400519 clientMaxStreams uint32 // SETTINGS_MAX_CONCURRENT_STREAMS from client (our PUSH_PROMISE limit)
520 advMaxStreams uint32 // our SETTINGS_MAX_CONCURRENT_STREAMS advertised the client
521 curClientStreams uint32 // number of open streams initiated by the client
522 curPushedStreams uint32 // number of open streams initiated by server push
523 maxClientStreamID uint32 // max ever seen from client (odd), or 0 if there have been no client requests
524 maxPushPromiseID uint32 // ID of the last push promise (even), or 0 if there have been no pushes
525 streams map[uint32]*stream
526 initialStreamSendWindowSize int32
527 maxFrameSize int32
528 headerTableSize uint32
529 peerMaxHeaderListSize uint32 // zero means unknown (default)
530 canonHeader map[string]string // http2-lower-case -> Go-Canonical-Case
531 writingFrame bool // started writing a frame (on serve goroutine or separate)
532 writingFrameAsync bool // started a frame on its own goroutine but haven't heard back on wroteFrameCh
533 needsFrameFlush bool // last frame write wasn't a flush
534 inGoAway bool // we've started to or sent GOAWAY
535 inFrameScheduleLoop bool // whether we're in the scheduleFrameWrite loop
536 needToSendGoAway bool // we need to schedule a GOAWAY frame write
537 goAwayCode ErrCode
538 shutdownTimer *time.Timer // nil until used
539 idleTimer *time.Timer // nil if unused
540
541 // Owned by the writeFrameAsync goroutine:
542 headerWriteBuf bytes.Buffer
543 hpackEncoder *hpack.Encoder
544
545 // Used by startGracefulShutdown.
546 shutdownOnce sync.Once
547}
548
549func (sc *serverConn) maxHeaderListSize() uint32 {
550 n := sc.hs.MaxHeaderBytes
551 if n <= 0 {
552 n = http.DefaultMaxHeaderBytes
553 }
554 // http2's count is in a slightly different unit and includes 32 bytes per pair.
555 // So, take the net/http.Server value and pad it up a bit, assuming 10 headers.
556 const perFieldOverhead = 32 // per http2 spec
557 const typicalHeaders = 10 // conservative
558 return uint32(n + typicalHeaders*perFieldOverhead)
559}
560
561func (sc *serverConn) curOpenStreams() uint32 {
562 sc.serveG.check()
563 return sc.curClientStreams + sc.curPushedStreams
564}
565
566// stream represents a stream. This is the minimal metadata needed by
567// the serve goroutine. Most of the actual stream state is owned by
568// the http.Handler's goroutine in the responseWriter. Because the
569// responseWriter's responseWriterState is recycled at the end of a
570// handler, this struct intentionally has no pointer to the
571// *responseWriter{,State} itself, as the Handler ending nils out the
572// responseWriter's state field.
573type stream struct {
574 // immutable:
575 sc *serverConn
576 id uint32
577 body *pipe // non-nil if expecting DATA frames
578 cw closeWaiter // closed wait stream transitions to closed state
579 ctx context.Context
580 cancelCtx func()
581
582 // owned by serverConn's serve loop:
Andrea Campanella764f1ed2022-03-24 11:46:38 +0100583 bodyBytes int64 // body bytes seen so far
584 declBodyBytes int64 // or -1 if undeclared
585 flow flow // limits writing from Handler to client
586 inflow flow // what the client is allowed to POST/etc to us
kesavand2cde6582020-06-22 04:56:23 -0400587 state streamState
588 resetQueued bool // RST_STREAM queued for write; set by sc.resetStream
589 gotTrailerHeader bool // HEADER frame for trailers was seen
590 wroteHeaders bool // whether we wrote headers (not status 100)
591 writeDeadline *time.Timer // nil if unused
592
593 trailer http.Header // accumulated trailers
594 reqTrailer http.Header // handler's Request.Trailer
595}
596
597func (sc *serverConn) Framer() *Framer { return sc.framer }
598func (sc *serverConn) CloseConn() error { return sc.conn.Close() }
599func (sc *serverConn) Flush() error { return sc.bw.Flush() }
600func (sc *serverConn) HeaderEncoder() (*hpack.Encoder, *bytes.Buffer) {
601 return sc.hpackEncoder, &sc.headerWriteBuf
602}
603
604func (sc *serverConn) state(streamID uint32) (streamState, *stream) {
605 sc.serveG.check()
606 // http://tools.ietf.org/html/rfc7540#section-5.1
607 if st, ok := sc.streams[streamID]; ok {
608 return st.state, st
609 }
610 // "The first use of a new stream identifier implicitly closes all
611 // streams in the "idle" state that might have been initiated by
612 // that peer with a lower-valued stream identifier. For example, if
613 // a client sends a HEADERS frame on stream 7 without ever sending a
614 // frame on stream 5, then stream 5 transitions to the "closed"
615 // state when the first frame for stream 7 is sent or received."
616 if streamID%2 == 1 {
617 if streamID <= sc.maxClientStreamID {
618 return stateClosed, nil
619 }
620 } else {
621 if streamID <= sc.maxPushPromiseID {
622 return stateClosed, nil
623 }
624 }
625 return stateIdle, nil
626}
627
628// setConnState calls the net/http ConnState hook for this connection, if configured.
629// Note that the net/http package does StateNew and StateClosed for us.
630// There is currently no plan for StateHijacked or hijacking HTTP/2 connections.
631func (sc *serverConn) setConnState(state http.ConnState) {
632 if sc.hs.ConnState != nil {
633 sc.hs.ConnState(sc.conn, state)
634 }
635}
636
637func (sc *serverConn) vlogf(format string, args ...interface{}) {
638 if VerboseLogs {
639 sc.logf(format, args...)
640 }
641}
642
643func (sc *serverConn) logf(format string, args ...interface{}) {
644 if lg := sc.hs.ErrorLog; lg != nil {
645 lg.Printf(format, args...)
646 } else {
647 log.Printf(format, args...)
648 }
649}
650
651// errno returns v's underlying uintptr, else 0.
652//
653// TODO: remove this helper function once http2 can use build
654// tags. See comment in isClosedConnError.
655func errno(v error) uintptr {
656 if rv := reflect.ValueOf(v); rv.Kind() == reflect.Uintptr {
657 return uintptr(rv.Uint())
658 }
659 return 0
660}
661
662// isClosedConnError reports whether err is an error from use of a closed
663// network connection.
664func isClosedConnError(err error) bool {
665 if err == nil {
666 return false
667 }
668
669 // TODO: remove this string search and be more like the Windows
670 // case below. That might involve modifying the standard library
671 // to return better error types.
672 str := err.Error()
673 if strings.Contains(str, "use of closed network connection") {
674 return true
675 }
676
677 // TODO(bradfitz): x/tools/cmd/bundle doesn't really support
678 // build tags, so I can't make an http2_windows.go file with
679 // Windows-specific stuff. Fix that and move this, once we
680 // have a way to bundle this into std's net/http somehow.
681 if runtime.GOOS == "windows" {
682 if oe, ok := err.(*net.OpError); ok && oe.Op == "read" {
683 if se, ok := oe.Err.(*os.SyscallError); ok && se.Syscall == "wsarecv" {
684 const WSAECONNABORTED = 10053
685 const WSAECONNRESET = 10054
686 if n := errno(se.Err); n == WSAECONNRESET || n == WSAECONNABORTED {
687 return true
688 }
689 }
690 }
691 }
692 return false
693}
694
695func (sc *serverConn) condlogf(err error, format string, args ...interface{}) {
696 if err == nil {
697 return
698 }
699 if err == io.EOF || err == io.ErrUnexpectedEOF || isClosedConnError(err) || err == errPrefaceTimeout {
700 // Boring, expected errors.
701 sc.vlogf(format, args...)
702 } else {
703 sc.logf(format, args...)
704 }
705}
706
707func (sc *serverConn) canonicalHeader(v string) string {
708 sc.serveG.check()
709 buildCommonHeaderMapsOnce()
710 cv, ok := commonCanonHeader[v]
711 if ok {
712 return cv
713 }
714 cv, ok = sc.canonHeader[v]
715 if ok {
716 return cv
717 }
718 if sc.canonHeader == nil {
719 sc.canonHeader = make(map[string]string)
720 }
721 cv = http.CanonicalHeaderKey(v)
kesavandc71914f2022-03-25 11:19:03 +0530722 // maxCachedCanonicalHeaders is an arbitrarily-chosen limit on the number of
723 // entries in the canonHeader cache. This should be larger than the number
724 // of unique, uncommon header keys likely to be sent by the peer, while not
725 // so high as to permit unreasonable memory usage if the peer sends an unbounded
726 // number of unique header keys.
727 const maxCachedCanonicalHeaders = 32
728 if len(sc.canonHeader) < maxCachedCanonicalHeaders {
729 sc.canonHeader[v] = cv
730 }
kesavand2cde6582020-06-22 04:56:23 -0400731 return cv
732}
733
734type readFrameResult struct {
735 f Frame // valid until readMore is called
736 err error
737
738 // readMore should be called once the consumer no longer needs or
739 // retains f. After readMore, f is invalid and more frames can be
740 // read.
741 readMore func()
742}
743
744// readFrames is the loop that reads incoming frames.
745// It takes care to only read one frame at a time, blocking until the
746// consumer is done with the frame.
747// It's run on its own goroutine.
748func (sc *serverConn) readFrames() {
749 gate := make(gate)
750 gateDone := gate.Done
751 for {
752 f, err := sc.framer.ReadFrame()
753 select {
754 case sc.readFrameCh <- readFrameResult{f, err, gateDone}:
755 case <-sc.doneServing:
756 return
757 }
758 select {
759 case <-gate:
760 case <-sc.doneServing:
761 return
762 }
763 if terminalReadFrameError(err) {
764 return
765 }
766 }
767}
768
769// frameWriteResult is the message passed from writeFrameAsync to the serve goroutine.
770type frameWriteResult struct {
Andrea Campanella764f1ed2022-03-24 11:46:38 +0100771 _ incomparable
kesavand2cde6582020-06-22 04:56:23 -0400772 wr FrameWriteRequest // what was written (or attempted)
773 err error // result of the writeFrame call
774}
775
776// writeFrameAsync runs in its own goroutine and writes a single frame
777// and then reports when it's done.
778// At most one goroutine can be running writeFrameAsync at a time per
779// serverConn.
780func (sc *serverConn) writeFrameAsync(wr FrameWriteRequest) {
781 err := wr.write.writeFrame(sc)
Andrea Campanella764f1ed2022-03-24 11:46:38 +0100782 sc.wroteFrameCh <- frameWriteResult{wr: wr, err: err}
kesavand2cde6582020-06-22 04:56:23 -0400783}
784
785func (sc *serverConn) closeAllStreamsOnConnClose() {
786 sc.serveG.check()
787 for _, st := range sc.streams {
788 sc.closeStream(st, errClientDisconnected)
789 }
790}
791
792func (sc *serverConn) stopShutdownTimer() {
793 sc.serveG.check()
794 if t := sc.shutdownTimer; t != nil {
795 t.Stop()
796 }
797}
798
799func (sc *serverConn) notePanic() {
800 // Note: this is for serverConn.serve panicking, not http.Handler code.
801 if testHookOnPanicMu != nil {
802 testHookOnPanicMu.Lock()
803 defer testHookOnPanicMu.Unlock()
804 }
805 if testHookOnPanic != nil {
806 if e := recover(); e != nil {
807 if testHookOnPanic(sc, e) {
808 panic(e)
809 }
810 }
811 }
812}
813
814func (sc *serverConn) serve() {
815 sc.serveG.check()
816 defer sc.notePanic()
817 defer sc.conn.Close()
818 defer sc.closeAllStreamsOnConnClose()
819 defer sc.stopShutdownTimer()
820 defer close(sc.doneServing) // unblocks handlers trying to send
821
822 if VerboseLogs {
823 sc.vlogf("http2: server connection from %v on %p", sc.conn.RemoteAddr(), sc.hs)
824 }
825
826 sc.writeFrame(FrameWriteRequest{
827 write: writeSettings{
828 {SettingMaxFrameSize, sc.srv.maxReadFrameSize()},
829 {SettingMaxConcurrentStreams, sc.advMaxStreams},
830 {SettingMaxHeaderListSize, sc.maxHeaderListSize()},
831 {SettingInitialWindowSize, uint32(sc.srv.initialStreamRecvWindowSize())},
832 },
833 })
834 sc.unackedSettings++
835
kesavandc71914f2022-03-25 11:19:03 +0530836 // Each connection starts with initialWindowSize inflow tokens.
kesavand2cde6582020-06-22 04:56:23 -0400837 // If a higher value is configured, we add more tokens.
838 if diff := sc.srv.initialConnRecvWindowSize() - initialWindowSize; diff > 0 {
839 sc.sendWindowUpdate(nil, int(diff))
840 }
841
842 if err := sc.readPreface(); err != nil {
843 sc.condlogf(err, "http2: server: error reading preface from client %v: %v", sc.conn.RemoteAddr(), err)
844 return
845 }
846 // Now that we've got the preface, get us out of the
847 // "StateNew" state. We can't go directly to idle, though.
848 // Active means we read some data and anticipate a request. We'll
849 // do another Active when we get a HEADERS frame.
850 sc.setConnState(http.StateActive)
851 sc.setConnState(http.StateIdle)
852
853 if sc.srv.IdleTimeout != 0 {
854 sc.idleTimer = time.AfterFunc(sc.srv.IdleTimeout, sc.onIdleTimer)
855 defer sc.idleTimer.Stop()
856 }
857
858 go sc.readFrames() // closed by defer sc.conn.Close above
859
860 settingsTimer := time.AfterFunc(firstSettingsTimeout, sc.onSettingsTimer)
861 defer settingsTimer.Stop()
862
863 loopNum := 0
864 for {
865 loopNum++
866 select {
867 case wr := <-sc.wantWriteFrameCh:
868 if se, ok := wr.write.(StreamError); ok {
869 sc.resetStream(se)
870 break
871 }
872 sc.writeFrame(wr)
873 case res := <-sc.wroteFrameCh:
874 sc.wroteFrame(res)
875 case res := <-sc.readFrameCh:
kesavandc71914f2022-03-25 11:19:03 +0530876 // Process any written frames before reading new frames from the client since a
877 // written frame could have triggered a new stream to be started.
878 if sc.writingFrameAsync {
879 select {
880 case wroteRes := <-sc.wroteFrameCh:
881 sc.wroteFrame(wroteRes)
882 default:
883 }
884 }
kesavand2cde6582020-06-22 04:56:23 -0400885 if !sc.processFrameFromReader(res) {
886 return
887 }
888 res.readMore()
889 if settingsTimer != nil {
890 settingsTimer.Stop()
891 settingsTimer = nil
892 }
893 case m := <-sc.bodyReadCh:
894 sc.noteBodyRead(m.st, m.n)
895 case msg := <-sc.serveMsgCh:
896 switch v := msg.(type) {
897 case func(int):
898 v(loopNum) // for testing
899 case *serverMessage:
900 switch v {
901 case settingsTimerMsg:
902 sc.logf("timeout waiting for SETTINGS frames from %v", sc.conn.RemoteAddr())
903 return
904 case idleTimerMsg:
905 sc.vlogf("connection is idle")
906 sc.goAway(ErrCodeNo)
907 case shutdownTimerMsg:
908 sc.vlogf("GOAWAY close timer fired; closing conn from %v", sc.conn.RemoteAddr())
909 return
910 case gracefulShutdownMsg:
911 sc.startGracefulShutdownInternal()
912 default:
913 panic("unknown timer")
914 }
915 case *startPushRequest:
916 sc.startPush(v)
917 default:
918 panic(fmt.Sprintf("unexpected type %T", v))
919 }
920 }
921
Andrea Campanella764f1ed2022-03-24 11:46:38 +0100922 // If the peer is causing us to generate a lot of control frames,
923 // but not reading them from us, assume they are trying to make us
924 // run out of memory.
925 if sc.queuedControlFrames > sc.srv.maxQueuedControlFrames() {
926 sc.vlogf("http2: too many control frames in send queue, closing connection")
927 return
928 }
929
kesavand2cde6582020-06-22 04:56:23 -0400930 // Start the shutdown timer after sending a GOAWAY. When sending GOAWAY
931 // with no error code (graceful shutdown), don't start the timer until
932 // all open streams have been completed.
933 sentGoAway := sc.inGoAway && !sc.needToSendGoAway && !sc.writingFrame
934 gracefulShutdownComplete := sc.goAwayCode == ErrCodeNo && sc.curOpenStreams() == 0
935 if sentGoAway && sc.shutdownTimer == nil && (sc.goAwayCode != ErrCodeNo || gracefulShutdownComplete) {
936 sc.shutDownIn(goAwayTimeout)
937 }
938 }
939}
940
941func (sc *serverConn) awaitGracefulShutdown(sharedCh <-chan struct{}, privateCh chan struct{}) {
942 select {
943 case <-sc.doneServing:
944 case <-sharedCh:
945 close(privateCh)
946 }
947}
948
949type serverMessage int
950
951// Message values sent to serveMsgCh.
952var (
953 settingsTimerMsg = new(serverMessage)
954 idleTimerMsg = new(serverMessage)
955 shutdownTimerMsg = new(serverMessage)
956 gracefulShutdownMsg = new(serverMessage)
957)
958
959func (sc *serverConn) onSettingsTimer() { sc.sendServeMsg(settingsTimerMsg) }
960func (sc *serverConn) onIdleTimer() { sc.sendServeMsg(idleTimerMsg) }
961func (sc *serverConn) onShutdownTimer() { sc.sendServeMsg(shutdownTimerMsg) }
962
963func (sc *serverConn) sendServeMsg(msg interface{}) {
964 sc.serveG.checkNotOn() // NOT
965 select {
966 case sc.serveMsgCh <- msg:
967 case <-sc.doneServing:
968 }
969}
970
971var errPrefaceTimeout = errors.New("timeout waiting for client preface")
972
973// readPreface reads the ClientPreface greeting from the peer or
974// returns errPrefaceTimeout on timeout, or an error if the greeting
975// is invalid.
976func (sc *serverConn) readPreface() error {
977 errc := make(chan error, 1)
978 go func() {
979 // Read the client preface
980 buf := make([]byte, len(ClientPreface))
981 if _, err := io.ReadFull(sc.conn, buf); err != nil {
982 errc <- err
983 } else if !bytes.Equal(buf, clientPreface) {
984 errc <- fmt.Errorf("bogus greeting %q", buf)
985 } else {
986 errc <- nil
987 }
988 }()
989 timer := time.NewTimer(prefaceTimeout) // TODO: configurable on *Server?
990 defer timer.Stop()
991 select {
992 case <-timer.C:
993 return errPrefaceTimeout
994 case err := <-errc:
995 if err == nil {
996 if VerboseLogs {
997 sc.vlogf("http2: server: client %v said hello", sc.conn.RemoteAddr())
998 }
999 }
1000 return err
1001 }
1002}
1003
1004var errChanPool = sync.Pool{
1005 New: func() interface{} { return make(chan error, 1) },
1006}
1007
1008var writeDataPool = sync.Pool{
1009 New: func() interface{} { return new(writeData) },
1010}
1011
1012// writeDataFromHandler writes DATA response frames from a handler on
1013// the given stream.
1014func (sc *serverConn) writeDataFromHandler(stream *stream, data []byte, endStream bool) error {
1015 ch := errChanPool.Get().(chan error)
1016 writeArg := writeDataPool.Get().(*writeData)
1017 *writeArg = writeData{stream.id, data, endStream}
1018 err := sc.writeFrameFromHandler(FrameWriteRequest{
1019 write: writeArg,
1020 stream: stream,
1021 done: ch,
1022 })
1023 if err != nil {
1024 return err
1025 }
1026 var frameWriteDone bool // the frame write is done (successfully or not)
1027 select {
1028 case err = <-ch:
1029 frameWriteDone = true
1030 case <-sc.doneServing:
1031 return errClientDisconnected
1032 case <-stream.cw:
1033 // If both ch and stream.cw were ready (as might
1034 // happen on the final Write after an http.Handler
1035 // ends), prefer the write result. Otherwise this
1036 // might just be us successfully closing the stream.
1037 // The writeFrameAsync and serve goroutines guarantee
1038 // that the ch send will happen before the stream.cw
1039 // close.
1040 select {
1041 case err = <-ch:
1042 frameWriteDone = true
1043 default:
1044 return errStreamClosed
1045 }
1046 }
1047 errChanPool.Put(ch)
1048 if frameWriteDone {
1049 writeDataPool.Put(writeArg)
1050 }
1051 return err
1052}
1053
1054// writeFrameFromHandler sends wr to sc.wantWriteFrameCh, but aborts
1055// if the connection has gone away.
1056//
1057// This must not be run from the serve goroutine itself, else it might
1058// deadlock writing to sc.wantWriteFrameCh (which is only mildly
1059// buffered and is read by serve itself). If you're on the serve
1060// goroutine, call writeFrame instead.
1061func (sc *serverConn) writeFrameFromHandler(wr FrameWriteRequest) error {
1062 sc.serveG.checkNotOn() // NOT
1063 select {
1064 case sc.wantWriteFrameCh <- wr:
1065 return nil
1066 case <-sc.doneServing:
1067 // Serve loop is gone.
1068 // Client has closed their connection to the server.
1069 return errClientDisconnected
1070 }
1071}
1072
1073// writeFrame schedules a frame to write and sends it if there's nothing
1074// already being written.
1075//
1076// There is no pushback here (the serve goroutine never blocks). It's
1077// the http.Handlers that block, waiting for their previous frames to
1078// make it onto the wire
1079//
1080// If you're not on the serve goroutine, use writeFrameFromHandler instead.
1081func (sc *serverConn) writeFrame(wr FrameWriteRequest) {
1082 sc.serveG.check()
1083
1084 // If true, wr will not be written and wr.done will not be signaled.
1085 var ignoreWrite bool
1086
1087 // We are not allowed to write frames on closed streams. RFC 7540 Section
1088 // 5.1.1 says: "An endpoint MUST NOT send frames other than PRIORITY on
1089 // a closed stream." Our server never sends PRIORITY, so that exception
1090 // does not apply.
1091 //
1092 // The serverConn might close an open stream while the stream's handler
1093 // is still running. For example, the server might close a stream when it
1094 // receives bad data from the client. If this happens, the handler might
1095 // attempt to write a frame after the stream has been closed (since the
1096 // handler hasn't yet been notified of the close). In this case, we simply
1097 // ignore the frame. The handler will notice that the stream is closed when
1098 // it waits for the frame to be written.
1099 //
1100 // As an exception to this rule, we allow sending RST_STREAM after close.
1101 // This allows us to immediately reject new streams without tracking any
1102 // state for those streams (except for the queued RST_STREAM frame). This
1103 // may result in duplicate RST_STREAMs in some cases, but the client should
1104 // ignore those.
1105 if wr.StreamID() != 0 {
1106 _, isReset := wr.write.(StreamError)
1107 if state, _ := sc.state(wr.StreamID()); state == stateClosed && !isReset {
1108 ignoreWrite = true
1109 }
1110 }
1111
1112 // Don't send a 100-continue response if we've already sent headers.
1113 // See golang.org/issue/14030.
1114 switch wr.write.(type) {
1115 case *writeResHeaders:
1116 wr.stream.wroteHeaders = true
1117 case write100ContinueHeadersFrame:
1118 if wr.stream.wroteHeaders {
1119 // We do not need to notify wr.done because this frame is
1120 // never written with wr.done != nil.
1121 if wr.done != nil {
1122 panic("wr.done != nil for write100ContinueHeadersFrame")
1123 }
1124 ignoreWrite = true
1125 }
1126 }
1127
1128 if !ignoreWrite {
Andrea Campanella764f1ed2022-03-24 11:46:38 +01001129 if wr.isControl() {
1130 sc.queuedControlFrames++
1131 // For extra safety, detect wraparounds, which should not happen,
1132 // and pull the plug.
1133 if sc.queuedControlFrames < 0 {
1134 sc.conn.Close()
1135 }
1136 }
kesavand2cde6582020-06-22 04:56:23 -04001137 sc.writeSched.Push(wr)
1138 }
1139 sc.scheduleFrameWrite()
1140}
1141
1142// startFrameWrite starts a goroutine to write wr (in a separate
1143// goroutine since that might block on the network), and updates the
1144// serve goroutine's state about the world, updated from info in wr.
1145func (sc *serverConn) startFrameWrite(wr FrameWriteRequest) {
1146 sc.serveG.check()
1147 if sc.writingFrame {
1148 panic("internal error: can only be writing one frame at a time")
1149 }
1150
1151 st := wr.stream
1152 if st != nil {
1153 switch st.state {
1154 case stateHalfClosedLocal:
1155 switch wr.write.(type) {
1156 case StreamError, handlerPanicRST, writeWindowUpdate:
1157 // RFC 7540 Section 5.1 allows sending RST_STREAM, PRIORITY, and WINDOW_UPDATE
1158 // in this state. (We never send PRIORITY from the server, so that is not checked.)
1159 default:
1160 panic(fmt.Sprintf("internal error: attempt to send frame on a half-closed-local stream: %v", wr))
1161 }
1162 case stateClosed:
1163 panic(fmt.Sprintf("internal error: attempt to send frame on a closed stream: %v", wr))
1164 }
1165 }
1166 if wpp, ok := wr.write.(*writePushPromise); ok {
1167 var err error
1168 wpp.promisedID, err = wpp.allocatePromisedID()
1169 if err != nil {
1170 sc.writingFrameAsync = false
1171 wr.replyToWriter(err)
1172 return
1173 }
1174 }
1175
1176 sc.writingFrame = true
1177 sc.needsFrameFlush = true
1178 if wr.write.staysWithinBuffer(sc.bw.Available()) {
1179 sc.writingFrameAsync = false
1180 err := wr.write.writeFrame(sc)
Andrea Campanella764f1ed2022-03-24 11:46:38 +01001181 sc.wroteFrame(frameWriteResult{wr: wr, err: err})
kesavand2cde6582020-06-22 04:56:23 -04001182 } else {
1183 sc.writingFrameAsync = true
1184 go sc.writeFrameAsync(wr)
1185 }
1186}
1187
1188// errHandlerPanicked is the error given to any callers blocked in a read from
1189// Request.Body when the main goroutine panics. Since most handlers read in the
1190// main ServeHTTP goroutine, this will show up rarely.
1191var errHandlerPanicked = errors.New("http2: handler panicked")
1192
1193// wroteFrame is called on the serve goroutine with the result of
1194// whatever happened on writeFrameAsync.
1195func (sc *serverConn) wroteFrame(res frameWriteResult) {
1196 sc.serveG.check()
1197 if !sc.writingFrame {
1198 panic("internal error: expected to be already writing a frame")
1199 }
1200 sc.writingFrame = false
1201 sc.writingFrameAsync = false
1202
1203 wr := res.wr
1204
1205 if writeEndsStream(wr.write) {
1206 st := wr.stream
1207 if st == nil {
1208 panic("internal error: expecting non-nil stream")
1209 }
1210 switch st.state {
1211 case stateOpen:
1212 // Here we would go to stateHalfClosedLocal in
1213 // theory, but since our handler is done and
1214 // the net/http package provides no mechanism
1215 // for closing a ResponseWriter while still
1216 // reading data (see possible TODO at top of
1217 // this file), we go into closed state here
1218 // anyway, after telling the peer we're
1219 // hanging up on them. We'll transition to
1220 // stateClosed after the RST_STREAM frame is
1221 // written.
1222 st.state = stateHalfClosedLocal
1223 // Section 8.1: a server MAY request that the client abort
1224 // transmission of a request without error by sending a
1225 // RST_STREAM with an error code of NO_ERROR after sending
1226 // a complete response.
1227 sc.resetStream(streamError(st.id, ErrCodeNo))
1228 case stateHalfClosedRemote:
1229 sc.closeStream(st, errHandlerComplete)
1230 }
1231 } else {
1232 switch v := wr.write.(type) {
1233 case StreamError:
1234 // st may be unknown if the RST_STREAM was generated to reject bad input.
1235 if st, ok := sc.streams[v.StreamID]; ok {
1236 sc.closeStream(st, v)
1237 }
1238 case handlerPanicRST:
1239 sc.closeStream(wr.stream, errHandlerPanicked)
1240 }
1241 }
1242
1243 // Reply (if requested) to unblock the ServeHTTP goroutine.
1244 wr.replyToWriter(res.err)
1245
1246 sc.scheduleFrameWrite()
1247}
1248
1249// scheduleFrameWrite tickles the frame writing scheduler.
1250//
1251// If a frame is already being written, nothing happens. This will be called again
1252// when the frame is done being written.
1253//
Andrea Campanella764f1ed2022-03-24 11:46:38 +01001254// If a frame isn't being written and we need to send one, the best frame
1255// to send is selected by writeSched.
kesavand2cde6582020-06-22 04:56:23 -04001256//
1257// If a frame isn't being written and there's nothing else to send, we
1258// flush the write buffer.
1259func (sc *serverConn) scheduleFrameWrite() {
1260 sc.serveG.check()
1261 if sc.writingFrame || sc.inFrameScheduleLoop {
1262 return
1263 }
1264 sc.inFrameScheduleLoop = true
1265 for !sc.writingFrameAsync {
1266 if sc.needToSendGoAway {
1267 sc.needToSendGoAway = false
1268 sc.startFrameWrite(FrameWriteRequest{
1269 write: &writeGoAway{
1270 maxStreamID: sc.maxClientStreamID,
1271 code: sc.goAwayCode,
1272 },
1273 })
1274 continue
1275 }
1276 if sc.needToSendSettingsAck {
1277 sc.needToSendSettingsAck = false
1278 sc.startFrameWrite(FrameWriteRequest{write: writeSettingsAck{}})
1279 continue
1280 }
1281 if !sc.inGoAway || sc.goAwayCode == ErrCodeNo {
1282 if wr, ok := sc.writeSched.Pop(); ok {
Andrea Campanella764f1ed2022-03-24 11:46:38 +01001283 if wr.isControl() {
1284 sc.queuedControlFrames--
1285 }
kesavand2cde6582020-06-22 04:56:23 -04001286 sc.startFrameWrite(wr)
1287 continue
1288 }
1289 }
1290 if sc.needsFrameFlush {
1291 sc.startFrameWrite(FrameWriteRequest{write: flushFrameWriter{}})
1292 sc.needsFrameFlush = false // after startFrameWrite, since it sets this true
1293 continue
1294 }
1295 break
1296 }
1297 sc.inFrameScheduleLoop = false
1298}
1299
1300// startGracefulShutdown gracefully shuts down a connection. This
1301// sends GOAWAY with ErrCodeNo to tell the client we're gracefully
1302// shutting down. The connection isn't closed until all current
1303// streams are done.
1304//
1305// startGracefulShutdown returns immediately; it does not wait until
1306// the connection has shut down.
1307func (sc *serverConn) startGracefulShutdown() {
1308 sc.serveG.checkNotOn() // NOT
1309 sc.shutdownOnce.Do(func() { sc.sendServeMsg(gracefulShutdownMsg) })
1310}
1311
Andrea Campanella764f1ed2022-03-24 11:46:38 +01001312// After sending GOAWAY with an error code (non-graceful shutdown), the
1313// connection will close after goAwayTimeout.
1314//
kesavand2cde6582020-06-22 04:56:23 -04001315// If we close the connection immediately after sending GOAWAY, there may
1316// be unsent data in our kernel receive buffer, which will cause the kernel
1317// to send a TCP RST on close() instead of a FIN. This RST will abort the
1318// connection immediately, whether or not the client had received the GOAWAY.
1319//
1320// Ideally we should delay for at least 1 RTT + epsilon so the client has
1321// a chance to read the GOAWAY and stop sending messages. Measuring RTT
1322// is hard, so we approximate with 1 second. See golang.org/issue/18701.
1323//
1324// This is a var so it can be shorter in tests, where all requests uses the
1325// loopback interface making the expected RTT very small.
1326//
1327// TODO: configurable?
1328var goAwayTimeout = 1 * time.Second
1329
1330func (sc *serverConn) startGracefulShutdownInternal() {
1331 sc.goAway(ErrCodeNo)
1332}
1333
1334func (sc *serverConn) goAway(code ErrCode) {
1335 sc.serveG.check()
1336 if sc.inGoAway {
1337 return
1338 }
1339 sc.inGoAway = true
1340 sc.needToSendGoAway = true
1341 sc.goAwayCode = code
1342 sc.scheduleFrameWrite()
1343}
1344
1345func (sc *serverConn) shutDownIn(d time.Duration) {
1346 sc.serveG.check()
1347 sc.shutdownTimer = time.AfterFunc(d, sc.onShutdownTimer)
1348}
1349
1350func (sc *serverConn) resetStream(se StreamError) {
1351 sc.serveG.check()
1352 sc.writeFrame(FrameWriteRequest{write: se})
1353 if st, ok := sc.streams[se.StreamID]; ok {
1354 st.resetQueued = true
1355 }
1356}
1357
1358// processFrameFromReader processes the serve loop's read from readFrameCh from the
1359// frame-reading goroutine.
1360// processFrameFromReader returns whether the connection should be kept open.
1361func (sc *serverConn) processFrameFromReader(res readFrameResult) bool {
1362 sc.serveG.check()
1363 err := res.err
1364 if err != nil {
1365 if err == ErrFrameTooLarge {
1366 sc.goAway(ErrCodeFrameSize)
1367 return true // goAway will close the loop
1368 }
1369 clientGone := err == io.EOF || err == io.ErrUnexpectedEOF || isClosedConnError(err)
1370 if clientGone {
1371 // TODO: could we also get into this state if
1372 // the peer does a half close
1373 // (e.g. CloseWrite) because they're done
1374 // sending frames but they're still wanting
1375 // our open replies? Investigate.
1376 // TODO: add CloseWrite to crypto/tls.Conn first
1377 // so we have a way to test this? I suppose
1378 // just for testing we could have a non-TLS mode.
1379 return false
1380 }
1381 } else {
1382 f := res.f
1383 if VerboseLogs {
1384 sc.vlogf("http2: server read frame %v", summarizeFrame(f))
1385 }
1386 err = sc.processFrame(f)
1387 if err == nil {
1388 return true
1389 }
1390 }
1391
1392 switch ev := err.(type) {
1393 case StreamError:
1394 sc.resetStream(ev)
1395 return true
1396 case goAwayFlowError:
1397 sc.goAway(ErrCodeFlowControl)
1398 return true
1399 case ConnectionError:
1400 sc.logf("http2: server connection error from %v: %v", sc.conn.RemoteAddr(), ev)
1401 sc.goAway(ErrCode(ev))
1402 return true // goAway will handle shutdown
1403 default:
1404 if res.err != nil {
1405 sc.vlogf("http2: server closing client connection; error reading frame from client %s: %v", sc.conn.RemoteAddr(), err)
1406 } else {
1407 sc.logf("http2: server closing client connection: %v", err)
1408 }
1409 return false
1410 }
1411}
1412
1413func (sc *serverConn) processFrame(f Frame) error {
1414 sc.serveG.check()
1415
1416 // First frame received must be SETTINGS.
1417 if !sc.sawFirstSettings {
1418 if _, ok := f.(*SettingsFrame); !ok {
kesavandc71914f2022-03-25 11:19:03 +05301419 return sc.countError("first_settings", ConnectionError(ErrCodeProtocol))
kesavand2cde6582020-06-22 04:56:23 -04001420 }
1421 sc.sawFirstSettings = true
1422 }
1423
1424 switch f := f.(type) {
1425 case *SettingsFrame:
1426 return sc.processSettings(f)
1427 case *MetaHeadersFrame:
1428 return sc.processHeaders(f)
1429 case *WindowUpdateFrame:
1430 return sc.processWindowUpdate(f)
1431 case *PingFrame:
1432 return sc.processPing(f)
1433 case *DataFrame:
1434 return sc.processData(f)
1435 case *RSTStreamFrame:
1436 return sc.processResetStream(f)
1437 case *PriorityFrame:
1438 return sc.processPriority(f)
1439 case *GoAwayFrame:
1440 return sc.processGoAway(f)
1441 case *PushPromiseFrame:
1442 // A client cannot push. Thus, servers MUST treat the receipt of a PUSH_PROMISE
1443 // frame as a connection error (Section 5.4.1) of type PROTOCOL_ERROR.
kesavandc71914f2022-03-25 11:19:03 +05301444 return sc.countError("push_promise", ConnectionError(ErrCodeProtocol))
kesavand2cde6582020-06-22 04:56:23 -04001445 default:
1446 sc.vlogf("http2: server ignoring frame: %v", f.Header())
1447 return nil
1448 }
1449}
1450
1451func (sc *serverConn) processPing(f *PingFrame) error {
1452 sc.serveG.check()
1453 if f.IsAck() {
1454 // 6.7 PING: " An endpoint MUST NOT respond to PING frames
1455 // containing this flag."
1456 return nil
1457 }
1458 if f.StreamID != 0 {
1459 // "PING frames are not associated with any individual
1460 // stream. If a PING frame is received with a stream
1461 // identifier field value other than 0x0, the recipient MUST
1462 // respond with a connection error (Section 5.4.1) of type
1463 // PROTOCOL_ERROR."
kesavandc71914f2022-03-25 11:19:03 +05301464 return sc.countError("ping_on_stream", ConnectionError(ErrCodeProtocol))
kesavand2cde6582020-06-22 04:56:23 -04001465 }
1466 if sc.inGoAway && sc.goAwayCode != ErrCodeNo {
1467 return nil
1468 }
1469 sc.writeFrame(FrameWriteRequest{write: writePingAck{f}})
1470 return nil
1471}
1472
1473func (sc *serverConn) processWindowUpdate(f *WindowUpdateFrame) error {
1474 sc.serveG.check()
1475 switch {
1476 case f.StreamID != 0: // stream-level flow control
1477 state, st := sc.state(f.StreamID)
1478 if state == stateIdle {
1479 // Section 5.1: "Receiving any frame other than HEADERS
1480 // or PRIORITY on a stream in this state MUST be
1481 // treated as a connection error (Section 5.4.1) of
1482 // type PROTOCOL_ERROR."
kesavandc71914f2022-03-25 11:19:03 +05301483 return sc.countError("stream_idle", ConnectionError(ErrCodeProtocol))
kesavand2cde6582020-06-22 04:56:23 -04001484 }
1485 if st == nil {
1486 // "WINDOW_UPDATE can be sent by a peer that has sent a
1487 // frame bearing the END_STREAM flag. This means that a
1488 // receiver could receive a WINDOW_UPDATE frame on a "half
1489 // closed (remote)" or "closed" stream. A receiver MUST
1490 // NOT treat this as an error, see Section 5.1."
1491 return nil
1492 }
1493 if !st.flow.add(int32(f.Increment)) {
kesavandc71914f2022-03-25 11:19:03 +05301494 return sc.countError("bad_flow", streamError(f.StreamID, ErrCodeFlowControl))
kesavand2cde6582020-06-22 04:56:23 -04001495 }
1496 default: // connection-level flow control
1497 if !sc.flow.add(int32(f.Increment)) {
1498 return goAwayFlowError{}
1499 }
1500 }
1501 sc.scheduleFrameWrite()
1502 return nil
1503}
1504
1505func (sc *serverConn) processResetStream(f *RSTStreamFrame) error {
1506 sc.serveG.check()
1507
1508 state, st := sc.state(f.StreamID)
1509 if state == stateIdle {
1510 // 6.4 "RST_STREAM frames MUST NOT be sent for a
1511 // stream in the "idle" state. If a RST_STREAM frame
1512 // identifying an idle stream is received, the
1513 // recipient MUST treat this as a connection error
1514 // (Section 5.4.1) of type PROTOCOL_ERROR.
kesavandc71914f2022-03-25 11:19:03 +05301515 return sc.countError("reset_idle_stream", ConnectionError(ErrCodeProtocol))
kesavand2cde6582020-06-22 04:56:23 -04001516 }
1517 if st != nil {
1518 st.cancelCtx()
1519 sc.closeStream(st, streamError(f.StreamID, f.ErrCode))
1520 }
1521 return nil
1522}
1523
1524func (sc *serverConn) closeStream(st *stream, err error) {
1525 sc.serveG.check()
1526 if st.state == stateIdle || st.state == stateClosed {
1527 panic(fmt.Sprintf("invariant; can't close stream in state %v", st.state))
1528 }
1529 st.state = stateClosed
1530 if st.writeDeadline != nil {
1531 st.writeDeadline.Stop()
1532 }
1533 if st.isPushed() {
1534 sc.curPushedStreams--
1535 } else {
1536 sc.curClientStreams--
1537 }
1538 delete(sc.streams, st.id)
1539 if len(sc.streams) == 0 {
1540 sc.setConnState(http.StateIdle)
1541 if sc.srv.IdleTimeout != 0 {
1542 sc.idleTimer.Reset(sc.srv.IdleTimeout)
1543 }
1544 if h1ServerKeepAlivesDisabled(sc.hs) {
1545 sc.startGracefulShutdownInternal()
1546 }
1547 }
1548 if p := st.body; p != nil {
1549 // Return any buffered unread bytes worth of conn-level flow control.
1550 // See golang.org/issue/16481
1551 sc.sendWindowUpdate(nil, p.Len())
1552
1553 p.CloseWithError(err)
1554 }
1555 st.cw.Close() // signals Handler's CloseNotifier, unblocks writes, etc
1556 sc.writeSched.CloseStream(st.id)
1557}
1558
1559func (sc *serverConn) processSettings(f *SettingsFrame) error {
1560 sc.serveG.check()
1561 if f.IsAck() {
1562 sc.unackedSettings--
1563 if sc.unackedSettings < 0 {
1564 // Why is the peer ACKing settings we never sent?
1565 // The spec doesn't mention this case, but
1566 // hang up on them anyway.
kesavandc71914f2022-03-25 11:19:03 +05301567 return sc.countError("ack_mystery", ConnectionError(ErrCodeProtocol))
kesavand2cde6582020-06-22 04:56:23 -04001568 }
1569 return nil
1570 }
1571 if f.NumSettings() > 100 || f.HasDuplicates() {
1572 // This isn't actually in the spec, but hang up on
1573 // suspiciously large settings frames or those with
1574 // duplicate entries.
kesavandc71914f2022-03-25 11:19:03 +05301575 return sc.countError("settings_big_or_dups", ConnectionError(ErrCodeProtocol))
kesavand2cde6582020-06-22 04:56:23 -04001576 }
1577 if err := f.ForeachSetting(sc.processSetting); err != nil {
1578 return err
1579 }
Andrea Campanella764f1ed2022-03-24 11:46:38 +01001580 // TODO: judging by RFC 7540, Section 6.5.3 each SETTINGS frame should be
1581 // acknowledged individually, even if multiple are received before the ACK.
kesavand2cde6582020-06-22 04:56:23 -04001582 sc.needToSendSettingsAck = true
1583 sc.scheduleFrameWrite()
1584 return nil
1585}
1586
1587func (sc *serverConn) processSetting(s Setting) error {
1588 sc.serveG.check()
1589 if err := s.Valid(); err != nil {
1590 return err
1591 }
1592 if VerboseLogs {
1593 sc.vlogf("http2: server processing setting %v", s)
1594 }
1595 switch s.ID {
1596 case SettingHeaderTableSize:
1597 sc.headerTableSize = s.Val
1598 sc.hpackEncoder.SetMaxDynamicTableSize(s.Val)
1599 case SettingEnablePush:
1600 sc.pushEnabled = s.Val != 0
1601 case SettingMaxConcurrentStreams:
1602 sc.clientMaxStreams = s.Val
1603 case SettingInitialWindowSize:
1604 return sc.processSettingInitialWindowSize(s.Val)
1605 case SettingMaxFrameSize:
1606 sc.maxFrameSize = int32(s.Val) // the maximum valid s.Val is < 2^31
1607 case SettingMaxHeaderListSize:
1608 sc.peerMaxHeaderListSize = s.Val
1609 default:
1610 // Unknown setting: "An endpoint that receives a SETTINGS
1611 // frame with any unknown or unsupported identifier MUST
1612 // ignore that setting."
1613 if VerboseLogs {
1614 sc.vlogf("http2: server ignoring unknown setting %v", s)
1615 }
1616 }
1617 return nil
1618}
1619
1620func (sc *serverConn) processSettingInitialWindowSize(val uint32) error {
1621 sc.serveG.check()
1622 // Note: val already validated to be within range by
1623 // processSetting's Valid call.
1624
1625 // "A SETTINGS frame can alter the initial flow control window
1626 // size for all current streams. When the value of
1627 // SETTINGS_INITIAL_WINDOW_SIZE changes, a receiver MUST
1628 // adjust the size of all stream flow control windows that it
1629 // maintains by the difference between the new value and the
1630 // old value."
1631 old := sc.initialStreamSendWindowSize
1632 sc.initialStreamSendWindowSize = int32(val)
1633 growth := int32(val) - old // may be negative
1634 for _, st := range sc.streams {
1635 if !st.flow.add(growth) {
1636 // 6.9.2 Initial Flow Control Window Size
1637 // "An endpoint MUST treat a change to
1638 // SETTINGS_INITIAL_WINDOW_SIZE that causes any flow
1639 // control window to exceed the maximum size as a
1640 // connection error (Section 5.4.1) of type
1641 // FLOW_CONTROL_ERROR."
kesavandc71914f2022-03-25 11:19:03 +05301642 return sc.countError("setting_win_size", ConnectionError(ErrCodeFlowControl))
kesavand2cde6582020-06-22 04:56:23 -04001643 }
1644 }
1645 return nil
1646}
1647
1648func (sc *serverConn) processData(f *DataFrame) error {
1649 sc.serveG.check()
Andrea Campanella764f1ed2022-03-24 11:46:38 +01001650 id := f.Header().StreamID
1651 if sc.inGoAway && (sc.goAwayCode != ErrCodeNo || id > sc.maxClientStreamID) {
1652 // Discard all DATA frames if the GOAWAY is due to an
1653 // error, or:
1654 //
1655 // Section 6.8: After sending a GOAWAY frame, the sender
1656 // can discard frames for streams initiated by the
1657 // receiver with identifiers higher than the identified
1658 // last stream.
kesavand2cde6582020-06-22 04:56:23 -04001659 return nil
1660 }
kesavand2cde6582020-06-22 04:56:23 -04001661
Andrea Campanella764f1ed2022-03-24 11:46:38 +01001662 data := f.Data()
kesavand2cde6582020-06-22 04:56:23 -04001663 state, st := sc.state(id)
1664 if id == 0 || state == stateIdle {
Andrea Campanella764f1ed2022-03-24 11:46:38 +01001665 // Section 6.1: "DATA frames MUST be associated with a
1666 // stream. If a DATA frame is received whose stream
1667 // identifier field is 0x0, the recipient MUST respond
1668 // with a connection error (Section 5.4.1) of type
1669 // PROTOCOL_ERROR."
1670 //
kesavand2cde6582020-06-22 04:56:23 -04001671 // Section 5.1: "Receiving any frame other than HEADERS
1672 // or PRIORITY on a stream in this state MUST be
1673 // treated as a connection error (Section 5.4.1) of
1674 // type PROTOCOL_ERROR."
kesavandc71914f2022-03-25 11:19:03 +05301675 return sc.countError("data_on_idle", ConnectionError(ErrCodeProtocol))
kesavand2cde6582020-06-22 04:56:23 -04001676 }
Andrea Campanella764f1ed2022-03-24 11:46:38 +01001677
1678 // "If a DATA frame is received whose stream is not in "open"
1679 // or "half closed (local)" state, the recipient MUST respond
1680 // with a stream error (Section 5.4.2) of type STREAM_CLOSED."
kesavand2cde6582020-06-22 04:56:23 -04001681 if st == nil || state != stateOpen || st.gotTrailerHeader || st.resetQueued {
1682 // This includes sending a RST_STREAM if the stream is
1683 // in stateHalfClosedLocal (which currently means that
1684 // the http.Handler returned, so it's done reading &
1685 // done writing). Try to stop the client from sending
1686 // more DATA.
1687
1688 // But still enforce their connection-level flow control,
1689 // and return any flow control bytes since we're not going
1690 // to consume them.
1691 if sc.inflow.available() < int32(f.Length) {
kesavandc71914f2022-03-25 11:19:03 +05301692 return sc.countError("data_flow", streamError(id, ErrCodeFlowControl))
kesavand2cde6582020-06-22 04:56:23 -04001693 }
1694 // Deduct the flow control from inflow, since we're
1695 // going to immediately add it back in
1696 // sendWindowUpdate, which also schedules sending the
1697 // frames.
1698 sc.inflow.take(int32(f.Length))
1699 sc.sendWindowUpdate(nil, int(f.Length)) // conn-level
1700
1701 if st != nil && st.resetQueued {
1702 // Already have a stream error in flight. Don't send another.
1703 return nil
1704 }
kesavandc71914f2022-03-25 11:19:03 +05301705 return sc.countError("closed", streamError(id, ErrCodeStreamClosed))
kesavand2cde6582020-06-22 04:56:23 -04001706 }
1707 if st.body == nil {
1708 panic("internal error: should have a body in this state")
1709 }
1710
1711 // Sender sending more than they'd declared?
1712 if st.declBodyBytes != -1 && st.bodyBytes+int64(len(data)) > st.declBodyBytes {
1713 st.body.CloseWithError(fmt.Errorf("sender tried to send more than declared Content-Length of %d bytes", st.declBodyBytes))
1714 // RFC 7540, sec 8.1.2.6: A request or response is also malformed if the
1715 // value of a content-length header field does not equal the sum of the
1716 // DATA frame payload lengths that form the body.
kesavandc71914f2022-03-25 11:19:03 +05301717 return sc.countError("send_too_much", streamError(id, ErrCodeProtocol))
kesavand2cde6582020-06-22 04:56:23 -04001718 }
1719 if f.Length > 0 {
1720 // Check whether the client has flow control quota.
1721 if st.inflow.available() < int32(f.Length) {
kesavandc71914f2022-03-25 11:19:03 +05301722 return sc.countError("flow_on_data_length", streamError(id, ErrCodeFlowControl))
kesavand2cde6582020-06-22 04:56:23 -04001723 }
1724 st.inflow.take(int32(f.Length))
1725
1726 if len(data) > 0 {
1727 wrote, err := st.body.Write(data)
1728 if err != nil {
Andrea Campanella764f1ed2022-03-24 11:46:38 +01001729 sc.sendWindowUpdate(nil, int(f.Length)-wrote)
kesavandc71914f2022-03-25 11:19:03 +05301730 return sc.countError("body_write_err", streamError(id, ErrCodeStreamClosed))
kesavand2cde6582020-06-22 04:56:23 -04001731 }
1732 if wrote != len(data) {
1733 panic("internal error: bad Writer")
1734 }
1735 st.bodyBytes += int64(len(data))
1736 }
1737
1738 // Return any padded flow control now, since we won't
1739 // refund it later on body reads.
1740 if pad := int32(f.Length) - int32(len(data)); pad > 0 {
1741 sc.sendWindowUpdate32(nil, pad)
1742 sc.sendWindowUpdate32(st, pad)
1743 }
1744 }
1745 if f.StreamEnded() {
1746 st.endStream()
1747 }
1748 return nil
1749}
1750
1751func (sc *serverConn) processGoAway(f *GoAwayFrame) error {
1752 sc.serveG.check()
1753 if f.ErrCode != ErrCodeNo {
1754 sc.logf("http2: received GOAWAY %+v, starting graceful shutdown", f)
1755 } else {
1756 sc.vlogf("http2: received GOAWAY %+v, starting graceful shutdown", f)
1757 }
1758 sc.startGracefulShutdownInternal()
1759 // http://tools.ietf.org/html/rfc7540#section-6.8
1760 // We should not create any new streams, which means we should disable push.
1761 sc.pushEnabled = false
1762 return nil
1763}
1764
1765// isPushed reports whether the stream is server-initiated.
1766func (st *stream) isPushed() bool {
1767 return st.id%2 == 0
1768}
1769
1770// endStream closes a Request.Body's pipe. It is called when a DATA
1771// frame says a request body is over (or after trailers).
1772func (st *stream) endStream() {
1773 sc := st.sc
1774 sc.serveG.check()
1775
1776 if st.declBodyBytes != -1 && st.declBodyBytes != st.bodyBytes {
1777 st.body.CloseWithError(fmt.Errorf("request declared a Content-Length of %d but only wrote %d bytes",
1778 st.declBodyBytes, st.bodyBytes))
1779 } else {
1780 st.body.closeWithErrorAndCode(io.EOF, st.copyTrailersToHandlerRequest)
1781 st.body.CloseWithError(io.EOF)
1782 }
1783 st.state = stateHalfClosedRemote
1784}
1785
1786// copyTrailersToHandlerRequest is run in the Handler's goroutine in
1787// its Request.Body.Read just before it gets io.EOF.
1788func (st *stream) copyTrailersToHandlerRequest() {
1789 for k, vv := range st.trailer {
1790 if _, ok := st.reqTrailer[k]; ok {
1791 // Only copy it over it was pre-declared.
1792 st.reqTrailer[k] = vv
1793 }
1794 }
1795}
1796
1797// onWriteTimeout is run on its own goroutine (from time.AfterFunc)
1798// when the stream's WriteTimeout has fired.
1799func (st *stream) onWriteTimeout() {
1800 st.sc.writeFrameFromHandler(FrameWriteRequest{write: streamError(st.id, ErrCodeInternal)})
1801}
1802
1803func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error {
1804 sc.serveG.check()
1805 id := f.StreamID
1806 if sc.inGoAway {
1807 // Ignore.
1808 return nil
1809 }
1810 // http://tools.ietf.org/html/rfc7540#section-5.1.1
1811 // Streams initiated by a client MUST use odd-numbered stream
1812 // identifiers. [...] An endpoint that receives an unexpected
1813 // stream identifier MUST respond with a connection error
1814 // (Section 5.4.1) of type PROTOCOL_ERROR.
1815 if id%2 != 1 {
kesavandc71914f2022-03-25 11:19:03 +05301816 return sc.countError("headers_even", ConnectionError(ErrCodeProtocol))
kesavand2cde6582020-06-22 04:56:23 -04001817 }
1818 // A HEADERS frame can be used to create a new stream or
1819 // send a trailer for an open one. If we already have a stream
1820 // open, let it process its own HEADERS frame (trailers at this
1821 // point, if it's valid).
1822 if st := sc.streams[f.StreamID]; st != nil {
1823 if st.resetQueued {
1824 // We're sending RST_STREAM to close the stream, so don't bother
1825 // processing this frame.
1826 return nil
1827 }
1828 // RFC 7540, sec 5.1: If an endpoint receives additional frames, other than
1829 // WINDOW_UPDATE, PRIORITY, or RST_STREAM, for a stream that is in
1830 // this state, it MUST respond with a stream error (Section 5.4.2) of
1831 // type STREAM_CLOSED.
1832 if st.state == stateHalfClosedRemote {
kesavandc71914f2022-03-25 11:19:03 +05301833 return sc.countError("headers_half_closed", streamError(id, ErrCodeStreamClosed))
kesavand2cde6582020-06-22 04:56:23 -04001834 }
1835 return st.processTrailerHeaders(f)
1836 }
1837
1838 // [...] The identifier of a newly established stream MUST be
1839 // numerically greater than all streams that the initiating
1840 // endpoint has opened or reserved. [...] An endpoint that
1841 // receives an unexpected stream identifier MUST respond with
1842 // a connection error (Section 5.4.1) of type PROTOCOL_ERROR.
1843 if id <= sc.maxClientStreamID {
kesavandc71914f2022-03-25 11:19:03 +05301844 return sc.countError("stream_went_down", ConnectionError(ErrCodeProtocol))
kesavand2cde6582020-06-22 04:56:23 -04001845 }
1846 sc.maxClientStreamID = id
1847
1848 if sc.idleTimer != nil {
1849 sc.idleTimer.Stop()
1850 }
1851
1852 // http://tools.ietf.org/html/rfc7540#section-5.1.2
1853 // [...] Endpoints MUST NOT exceed the limit set by their peer. An
1854 // endpoint that receives a HEADERS frame that causes their
1855 // advertised concurrent stream limit to be exceeded MUST treat
1856 // this as a stream error (Section 5.4.2) of type PROTOCOL_ERROR
1857 // or REFUSED_STREAM.
1858 if sc.curClientStreams+1 > sc.advMaxStreams {
1859 if sc.unackedSettings == 0 {
1860 // They should know better.
kesavandc71914f2022-03-25 11:19:03 +05301861 return sc.countError("over_max_streams", streamError(id, ErrCodeProtocol))
kesavand2cde6582020-06-22 04:56:23 -04001862 }
1863 // Assume it's a network race, where they just haven't
1864 // received our last SETTINGS update. But actually
1865 // this can't happen yet, because we don't yet provide
1866 // a way for users to adjust server parameters at
1867 // runtime.
kesavandc71914f2022-03-25 11:19:03 +05301868 return sc.countError("over_max_streams_race", streamError(id, ErrCodeRefusedStream))
kesavand2cde6582020-06-22 04:56:23 -04001869 }
1870
1871 initialState := stateOpen
1872 if f.StreamEnded() {
1873 initialState = stateHalfClosedRemote
1874 }
1875 st := sc.newStream(id, 0, initialState)
1876
1877 if f.HasPriority() {
kesavandc71914f2022-03-25 11:19:03 +05301878 if err := sc.checkPriority(f.StreamID, f.Priority); err != nil {
kesavand2cde6582020-06-22 04:56:23 -04001879 return err
1880 }
1881 sc.writeSched.AdjustStream(st.id, f.Priority)
1882 }
1883
1884 rw, req, err := sc.newWriterAndRequest(st, f)
1885 if err != nil {
1886 return err
1887 }
1888 st.reqTrailer = req.Trailer
1889 if st.reqTrailer != nil {
1890 st.trailer = make(http.Header)
1891 }
1892 st.body = req.Body.(*requestBody).pipe // may be nil
1893 st.declBodyBytes = req.ContentLength
1894
1895 handler := sc.handler.ServeHTTP
1896 if f.Truncated {
1897 // Their header list was too long. Send a 431 error.
1898 handler = handleHeaderListTooLong
1899 } else if err := checkValidHTTP2RequestHeaders(req.Header); err != nil {
1900 handler = new400Handler(err)
1901 }
1902
1903 // The net/http package sets the read deadline from the
1904 // http.Server.ReadTimeout during the TLS handshake, but then
1905 // passes the connection off to us with the deadline already
1906 // set. Disarm it here after the request headers are read,
1907 // similar to how the http1 server works. Here it's
1908 // technically more like the http1 Server's ReadHeaderTimeout
1909 // (in Go 1.8), though. That's a more sane option anyway.
1910 if sc.hs.ReadTimeout != 0 {
1911 sc.conn.SetReadDeadline(time.Time{})
1912 }
1913
1914 go sc.runHandler(rw, req, handler)
1915 return nil
1916}
1917
1918func (st *stream) processTrailerHeaders(f *MetaHeadersFrame) error {
1919 sc := st.sc
1920 sc.serveG.check()
1921 if st.gotTrailerHeader {
kesavandc71914f2022-03-25 11:19:03 +05301922 return sc.countError("dup_trailers", ConnectionError(ErrCodeProtocol))
kesavand2cde6582020-06-22 04:56:23 -04001923 }
1924 st.gotTrailerHeader = true
1925 if !f.StreamEnded() {
kesavandc71914f2022-03-25 11:19:03 +05301926 return sc.countError("trailers_not_ended", streamError(st.id, ErrCodeProtocol))
kesavand2cde6582020-06-22 04:56:23 -04001927 }
1928
1929 if len(f.PseudoFields()) > 0 {
kesavandc71914f2022-03-25 11:19:03 +05301930 return sc.countError("trailers_pseudo", streamError(st.id, ErrCodeProtocol))
kesavand2cde6582020-06-22 04:56:23 -04001931 }
1932 if st.trailer != nil {
1933 for _, hf := range f.RegularFields() {
1934 key := sc.canonicalHeader(hf.Name)
1935 if !httpguts.ValidTrailerHeader(key) {
1936 // TODO: send more details to the peer somehow. But http2 has
1937 // no way to send debug data at a stream level. Discuss with
1938 // HTTP folk.
kesavandc71914f2022-03-25 11:19:03 +05301939 return sc.countError("trailers_bogus", streamError(st.id, ErrCodeProtocol))
kesavand2cde6582020-06-22 04:56:23 -04001940 }
1941 st.trailer[key] = append(st.trailer[key], hf.Value)
1942 }
1943 }
1944 st.endStream()
1945 return nil
1946}
1947
kesavandc71914f2022-03-25 11:19:03 +05301948func (sc *serverConn) checkPriority(streamID uint32, p PriorityParam) error {
kesavand2cde6582020-06-22 04:56:23 -04001949 if streamID == p.StreamDep {
1950 // Section 5.3.1: "A stream cannot depend on itself. An endpoint MUST treat
1951 // this as a stream error (Section 5.4.2) of type PROTOCOL_ERROR."
1952 // Section 5.3.3 says that a stream can depend on one of its dependencies,
1953 // so it's only self-dependencies that are forbidden.
kesavandc71914f2022-03-25 11:19:03 +05301954 return sc.countError("priority", streamError(streamID, ErrCodeProtocol))
kesavand2cde6582020-06-22 04:56:23 -04001955 }
1956 return nil
1957}
1958
1959func (sc *serverConn) processPriority(f *PriorityFrame) error {
1960 if sc.inGoAway {
1961 return nil
1962 }
kesavandc71914f2022-03-25 11:19:03 +05301963 if err := sc.checkPriority(f.StreamID, f.PriorityParam); err != nil {
kesavand2cde6582020-06-22 04:56:23 -04001964 return err
1965 }
1966 sc.writeSched.AdjustStream(f.StreamID, f.PriorityParam)
1967 return nil
1968}
1969
1970func (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream {
1971 sc.serveG.check()
1972 if id == 0 {
1973 panic("internal error: cannot create stream with id 0")
1974 }
1975
1976 ctx, cancelCtx := context.WithCancel(sc.baseCtx)
1977 st := &stream{
1978 sc: sc,
1979 id: id,
1980 state: state,
1981 ctx: ctx,
1982 cancelCtx: cancelCtx,
1983 }
1984 st.cw.Init()
1985 st.flow.conn = &sc.flow // link to conn-level counter
1986 st.flow.add(sc.initialStreamSendWindowSize)
1987 st.inflow.conn = &sc.inflow // link to conn-level counter
1988 st.inflow.add(sc.srv.initialStreamRecvWindowSize())
1989 if sc.hs.WriteTimeout != 0 {
1990 st.writeDeadline = time.AfterFunc(sc.hs.WriteTimeout, st.onWriteTimeout)
1991 }
1992
1993 sc.streams[id] = st
1994 sc.writeSched.OpenStream(st.id, OpenStreamOptions{PusherID: pusherID})
1995 if st.isPushed() {
1996 sc.curPushedStreams++
1997 } else {
1998 sc.curClientStreams++
1999 }
2000 if sc.curOpenStreams() == 1 {
2001 sc.setConnState(http.StateActive)
2002 }
2003
2004 return st
2005}
2006
2007func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*responseWriter, *http.Request, error) {
2008 sc.serveG.check()
2009
2010 rp := requestParam{
2011 method: f.PseudoValue("method"),
2012 scheme: f.PseudoValue("scheme"),
2013 authority: f.PseudoValue("authority"),
2014 path: f.PseudoValue("path"),
2015 }
2016
2017 isConnect := rp.method == "CONNECT"
2018 if isConnect {
2019 if rp.path != "" || rp.scheme != "" || rp.authority == "" {
kesavandc71914f2022-03-25 11:19:03 +05302020 return nil, nil, sc.countError("bad_connect", streamError(f.StreamID, ErrCodeProtocol))
kesavand2cde6582020-06-22 04:56:23 -04002021 }
2022 } else if rp.method == "" || rp.path == "" || (rp.scheme != "https" && rp.scheme != "http") {
2023 // See 8.1.2.6 Malformed Requests and Responses:
2024 //
2025 // Malformed requests or responses that are detected
2026 // MUST be treated as a stream error (Section 5.4.2)
2027 // of type PROTOCOL_ERROR."
2028 //
2029 // 8.1.2.3 Request Pseudo-Header Fields
2030 // "All HTTP/2 requests MUST include exactly one valid
2031 // value for the :method, :scheme, and :path
2032 // pseudo-header fields"
kesavandc71914f2022-03-25 11:19:03 +05302033 return nil, nil, sc.countError("bad_path_method", streamError(f.StreamID, ErrCodeProtocol))
kesavand2cde6582020-06-22 04:56:23 -04002034 }
2035
2036 bodyOpen := !f.StreamEnded()
2037 if rp.method == "HEAD" && bodyOpen {
2038 // HEAD requests can't have bodies
kesavandc71914f2022-03-25 11:19:03 +05302039 return nil, nil, sc.countError("head_body", streamError(f.StreamID, ErrCodeProtocol))
kesavand2cde6582020-06-22 04:56:23 -04002040 }
2041
2042 rp.header = make(http.Header)
2043 for _, hf := range f.RegularFields() {
2044 rp.header.Add(sc.canonicalHeader(hf.Name), hf.Value)
2045 }
2046 if rp.authority == "" {
2047 rp.authority = rp.header.Get("Host")
2048 }
2049
2050 rw, req, err := sc.newWriterAndRequestNoBody(st, rp)
2051 if err != nil {
2052 return nil, nil, err
2053 }
2054 if bodyOpen {
2055 if vv, ok := rp.header["Content-Length"]; ok {
Andrea Campanella764f1ed2022-03-24 11:46:38 +01002056 if cl, err := strconv.ParseUint(vv[0], 10, 63); err == nil {
2057 req.ContentLength = int64(cl)
2058 } else {
2059 req.ContentLength = 0
2060 }
kesavand2cde6582020-06-22 04:56:23 -04002061 } else {
2062 req.ContentLength = -1
2063 }
2064 req.Body.(*requestBody).pipe = &pipe{
2065 b: &dataBuffer{expected: req.ContentLength},
2066 }
2067 }
2068 return rw, req, nil
2069}
2070
2071type requestParam struct {
2072 method string
2073 scheme, authority, path string
2074 header http.Header
2075}
2076
2077func (sc *serverConn) newWriterAndRequestNoBody(st *stream, rp requestParam) (*responseWriter, *http.Request, error) {
2078 sc.serveG.check()
2079
2080 var tlsState *tls.ConnectionState // nil if not scheme https
2081 if rp.scheme == "https" {
2082 tlsState = sc.tlsState
2083 }
2084
2085 needsContinue := rp.header.Get("Expect") == "100-continue"
2086 if needsContinue {
2087 rp.header.Del("Expect")
2088 }
2089 // Merge Cookie headers into one "; "-delimited value.
2090 if cookies := rp.header["Cookie"]; len(cookies) > 1 {
2091 rp.header.Set("Cookie", strings.Join(cookies, "; "))
2092 }
2093
2094 // Setup Trailers
2095 var trailer http.Header
2096 for _, v := range rp.header["Trailer"] {
2097 for _, key := range strings.Split(v, ",") {
Andrea Campanella764f1ed2022-03-24 11:46:38 +01002098 key = http.CanonicalHeaderKey(textproto.TrimString(key))
kesavand2cde6582020-06-22 04:56:23 -04002099 switch key {
2100 case "Transfer-Encoding", "Trailer", "Content-Length":
2101 // Bogus. (copy of http1 rules)
2102 // Ignore.
2103 default:
2104 if trailer == nil {
2105 trailer = make(http.Header)
2106 }
2107 trailer[key] = nil
2108 }
2109 }
2110 }
2111 delete(rp.header, "Trailer")
2112
2113 var url_ *url.URL
2114 var requestURI string
2115 if rp.method == "CONNECT" {
2116 url_ = &url.URL{Host: rp.authority}
2117 requestURI = rp.authority // mimic HTTP/1 server behavior
2118 } else {
2119 var err error
2120 url_, err = url.ParseRequestURI(rp.path)
2121 if err != nil {
kesavandc71914f2022-03-25 11:19:03 +05302122 return nil, nil, sc.countError("bad_path", streamError(st.id, ErrCodeProtocol))
kesavand2cde6582020-06-22 04:56:23 -04002123 }
2124 requestURI = rp.path
2125 }
2126
2127 body := &requestBody{
2128 conn: sc,
2129 stream: st,
2130 needsContinue: needsContinue,
2131 }
2132 req := &http.Request{
2133 Method: rp.method,
2134 URL: url_,
2135 RemoteAddr: sc.remoteAddrStr,
2136 Header: rp.header,
2137 RequestURI: requestURI,
2138 Proto: "HTTP/2.0",
2139 ProtoMajor: 2,
2140 ProtoMinor: 0,
2141 TLS: tlsState,
2142 Host: rp.authority,
2143 Body: body,
2144 Trailer: trailer,
2145 }
2146 req = req.WithContext(st.ctx)
2147
2148 rws := responseWriterStatePool.Get().(*responseWriterState)
2149 bwSave := rws.bw
2150 *rws = responseWriterState{} // zero all the fields
2151 rws.conn = sc
2152 rws.bw = bwSave
2153 rws.bw.Reset(chunkWriter{rws})
2154 rws.stream = st
2155 rws.req = req
2156 rws.body = body
2157
2158 rw := &responseWriter{rws: rws}
2159 return rw, req, nil
2160}
2161
2162// Run on its own goroutine.
2163func (sc *serverConn) runHandler(rw *responseWriter, req *http.Request, handler func(http.ResponseWriter, *http.Request)) {
2164 didPanic := true
2165 defer func() {
2166 rw.rws.stream.cancelCtx()
2167 if didPanic {
2168 e := recover()
2169 sc.writeFrameFromHandler(FrameWriteRequest{
2170 write: handlerPanicRST{rw.rws.stream.id},
2171 stream: rw.rws.stream,
2172 })
2173 // Same as net/http:
2174 if e != nil && e != http.ErrAbortHandler {
2175 const size = 64 << 10
2176 buf := make([]byte, size)
2177 buf = buf[:runtime.Stack(buf, false)]
2178 sc.logf("http2: panic serving %v: %v\n%s", sc.conn.RemoteAddr(), e, buf)
2179 }
2180 return
2181 }
2182 rw.handlerDone()
2183 }()
2184 handler(rw, req)
2185 didPanic = false
2186}
2187
2188func handleHeaderListTooLong(w http.ResponseWriter, r *http.Request) {
2189 // 10.5.1 Limits on Header Block Size:
2190 // .. "A server that receives a larger header block than it is
2191 // willing to handle can send an HTTP 431 (Request Header Fields Too
2192 // Large) status code"
2193 const statusRequestHeaderFieldsTooLarge = 431 // only in Go 1.6+
2194 w.WriteHeader(statusRequestHeaderFieldsTooLarge)
2195 io.WriteString(w, "<h1>HTTP Error 431</h1><p>Request Header Field(s) Too Large</p>")
2196}
2197
2198// called from handler goroutines.
2199// h may be nil.
2200func (sc *serverConn) writeHeaders(st *stream, headerData *writeResHeaders) error {
2201 sc.serveG.checkNotOn() // NOT on
2202 var errc chan error
2203 if headerData.h != nil {
2204 // If there's a header map (which we don't own), so we have to block on
2205 // waiting for this frame to be written, so an http.Flush mid-handler
2206 // writes out the correct value of keys, before a handler later potentially
2207 // mutates it.
2208 errc = errChanPool.Get().(chan error)
2209 }
2210 if err := sc.writeFrameFromHandler(FrameWriteRequest{
2211 write: headerData,
2212 stream: st,
2213 done: errc,
2214 }); err != nil {
2215 return err
2216 }
2217 if errc != nil {
2218 select {
2219 case err := <-errc:
2220 errChanPool.Put(errc)
2221 return err
2222 case <-sc.doneServing:
2223 return errClientDisconnected
2224 case <-st.cw:
2225 return errStreamClosed
2226 }
2227 }
2228 return nil
2229}
2230
2231// called from handler goroutines.
2232func (sc *serverConn) write100ContinueHeaders(st *stream) {
2233 sc.writeFrameFromHandler(FrameWriteRequest{
2234 write: write100ContinueHeadersFrame{st.id},
2235 stream: st,
2236 })
2237}
2238
2239// A bodyReadMsg tells the server loop that the http.Handler read n
2240// bytes of the DATA from the client on the given stream.
2241type bodyReadMsg struct {
2242 st *stream
2243 n int
2244}
2245
2246// called from handler goroutines.
2247// Notes that the handler for the given stream ID read n bytes of its body
2248// and schedules flow control tokens to be sent.
2249func (sc *serverConn) noteBodyReadFromHandler(st *stream, n int, err error) {
2250 sc.serveG.checkNotOn() // NOT on
2251 if n > 0 {
2252 select {
2253 case sc.bodyReadCh <- bodyReadMsg{st, n}:
2254 case <-sc.doneServing:
2255 }
2256 }
2257}
2258
2259func (sc *serverConn) noteBodyRead(st *stream, n int) {
2260 sc.serveG.check()
2261 sc.sendWindowUpdate(nil, n) // conn-level
2262 if st.state != stateHalfClosedRemote && st.state != stateClosed {
2263 // Don't send this WINDOW_UPDATE if the stream is closed
2264 // remotely.
2265 sc.sendWindowUpdate(st, n)
2266 }
2267}
2268
2269// st may be nil for conn-level
2270func (sc *serverConn) sendWindowUpdate(st *stream, n int) {
2271 sc.serveG.check()
2272 // "The legal range for the increment to the flow control
2273 // window is 1 to 2^31-1 (2,147,483,647) octets."
2274 // A Go Read call on 64-bit machines could in theory read
2275 // a larger Read than this. Very unlikely, but we handle it here
2276 // rather than elsewhere for now.
2277 const maxUint31 = 1<<31 - 1
2278 for n >= maxUint31 {
2279 sc.sendWindowUpdate32(st, maxUint31)
2280 n -= maxUint31
2281 }
2282 sc.sendWindowUpdate32(st, int32(n))
2283}
2284
2285// st may be nil for conn-level
2286func (sc *serverConn) sendWindowUpdate32(st *stream, n int32) {
2287 sc.serveG.check()
2288 if n == 0 {
2289 return
2290 }
2291 if n < 0 {
2292 panic("negative update")
2293 }
2294 var streamID uint32
2295 if st != nil {
2296 streamID = st.id
2297 }
2298 sc.writeFrame(FrameWriteRequest{
2299 write: writeWindowUpdate{streamID: streamID, n: uint32(n)},
2300 stream: st,
2301 })
2302 var ok bool
2303 if st == nil {
2304 ok = sc.inflow.add(n)
2305 } else {
2306 ok = st.inflow.add(n)
2307 }
2308 if !ok {
2309 panic("internal error; sent too many window updates without decrements?")
2310 }
2311}
2312
2313// requestBody is the Handler's Request.Body type.
2314// Read and Close may be called concurrently.
2315type requestBody struct {
Andrea Campanella764f1ed2022-03-24 11:46:38 +01002316 _ incomparable
kesavand2cde6582020-06-22 04:56:23 -04002317 stream *stream
2318 conn *serverConn
2319 closed bool // for use by Close only
2320 sawEOF bool // for use by Read only
2321 pipe *pipe // non-nil if we have a HTTP entity message body
2322 needsContinue bool // need to send a 100-continue
2323}
2324
2325func (b *requestBody) Close() error {
2326 if b.pipe != nil && !b.closed {
2327 b.pipe.BreakWithError(errClosedBody)
2328 }
2329 b.closed = true
2330 return nil
2331}
2332
2333func (b *requestBody) Read(p []byte) (n int, err error) {
2334 if b.needsContinue {
2335 b.needsContinue = false
2336 b.conn.write100ContinueHeaders(b.stream)
2337 }
2338 if b.pipe == nil || b.sawEOF {
2339 return 0, io.EOF
2340 }
2341 n, err = b.pipe.Read(p)
2342 if err == io.EOF {
2343 b.sawEOF = true
2344 }
2345 if b.conn == nil && inTests {
2346 return
2347 }
2348 b.conn.noteBodyReadFromHandler(b.stream, n, err)
2349 return
2350}
2351
2352// responseWriter is the http.ResponseWriter implementation. It's
2353// intentionally small (1 pointer wide) to minimize garbage. The
2354// responseWriterState pointer inside is zeroed at the end of a
2355// request (in handlerDone) and calls on the responseWriter thereafter
2356// simply crash (caller's mistake), but the much larger responseWriterState
2357// and buffers are reused between multiple requests.
2358type responseWriter struct {
2359 rws *responseWriterState
2360}
2361
2362// Optional http.ResponseWriter interfaces implemented.
2363var (
2364 _ http.CloseNotifier = (*responseWriter)(nil)
2365 _ http.Flusher = (*responseWriter)(nil)
2366 _ stringWriter = (*responseWriter)(nil)
2367)
2368
2369type responseWriterState struct {
2370 // immutable within a request:
2371 stream *stream
2372 req *http.Request
2373 body *requestBody // to close at end of request, if DATA frames didn't
2374 conn *serverConn
2375
2376 // TODO: adjust buffer writing sizes based on server config, frame size updates from peer, etc
2377 bw *bufio.Writer // writing to a chunkWriter{this *responseWriterState}
2378
2379 // mutated by http.Handler goroutine:
2380 handlerHeader http.Header // nil until called
2381 snapHeader http.Header // snapshot of handlerHeader at WriteHeader time
2382 trailers []string // set in writeChunk
2383 status int // status code passed to WriteHeader
2384 wroteHeader bool // WriteHeader called (explicitly or implicitly). Not necessarily sent to user yet.
2385 sentHeader bool // have we sent the header frame?
2386 handlerDone bool // handler has finished
2387 dirty bool // a Write failed; don't reuse this responseWriterState
2388
2389 sentContentLen int64 // non-zero if handler set a Content-Length header
2390 wroteBytes int64
2391
2392 closeNotifierMu sync.Mutex // guards closeNotifierCh
2393 closeNotifierCh chan bool // nil until first used
2394}
2395
2396type chunkWriter struct{ rws *responseWriterState }
2397
2398func (cw chunkWriter) Write(p []byte) (n int, err error) { return cw.rws.writeChunk(p) }
2399
2400func (rws *responseWriterState) hasTrailers() bool { return len(rws.trailers) > 0 }
2401
2402func (rws *responseWriterState) hasNonemptyTrailers() bool {
2403 for _, trailer := range rws.trailers {
2404 if _, ok := rws.handlerHeader[trailer]; ok {
2405 return true
2406 }
2407 }
2408 return false
2409}
2410
2411// declareTrailer is called for each Trailer header when the
2412// response header is written. It notes that a header will need to be
2413// written in the trailers at the end of the response.
2414func (rws *responseWriterState) declareTrailer(k string) {
2415 k = http.CanonicalHeaderKey(k)
2416 if !httpguts.ValidTrailerHeader(k) {
2417 // Forbidden by RFC 7230, section 4.1.2.
2418 rws.conn.logf("ignoring invalid trailer %q", k)
2419 return
2420 }
2421 if !strSliceContains(rws.trailers, k) {
2422 rws.trailers = append(rws.trailers, k)
2423 }
2424}
2425
2426// writeChunk writes chunks from the bufio.Writer. But because
2427// bufio.Writer may bypass its chunking, sometimes p may be
2428// arbitrarily large.
2429//
2430// writeChunk is also responsible (on the first chunk) for sending the
2431// HEADER response.
2432func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
2433 if !rws.wroteHeader {
2434 rws.writeHeader(200)
2435 }
2436
2437 isHeadResp := rws.req.Method == "HEAD"
2438 if !rws.sentHeader {
2439 rws.sentHeader = true
2440 var ctype, clen string
2441 if clen = rws.snapHeader.Get("Content-Length"); clen != "" {
2442 rws.snapHeader.Del("Content-Length")
Andrea Campanella764f1ed2022-03-24 11:46:38 +01002443 if cl, err := strconv.ParseUint(clen, 10, 63); err == nil {
2444 rws.sentContentLen = int64(cl)
kesavand2cde6582020-06-22 04:56:23 -04002445 } else {
2446 clen = ""
2447 }
2448 }
2449 if clen == "" && rws.handlerDone && bodyAllowedForStatus(rws.status) && (len(p) > 0 || !isHeadResp) {
2450 clen = strconv.Itoa(len(p))
2451 }
2452 _, hasContentType := rws.snapHeader["Content-Type"]
Andrea Campanella764f1ed2022-03-24 11:46:38 +01002453 // If the Content-Encoding is non-blank, we shouldn't
2454 // sniff the body. See Issue golang.org/issue/31753.
2455 ce := rws.snapHeader.Get("Content-Encoding")
2456 hasCE := len(ce) > 0
2457 if !hasCE && !hasContentType && bodyAllowedForStatus(rws.status) && len(p) > 0 {
kesavand2cde6582020-06-22 04:56:23 -04002458 ctype = http.DetectContentType(p)
2459 }
2460 var date string
2461 if _, ok := rws.snapHeader["Date"]; !ok {
2462 // TODO(bradfitz): be faster here, like net/http? measure.
2463 date = time.Now().UTC().Format(http.TimeFormat)
2464 }
2465
2466 for _, v := range rws.snapHeader["Trailer"] {
2467 foreachHeaderElement(v, rws.declareTrailer)
2468 }
2469
2470 // "Connection" headers aren't allowed in HTTP/2 (RFC 7540, 8.1.2.2),
2471 // but respect "Connection" == "close" to mean sending a GOAWAY and tearing
2472 // down the TCP connection when idle, like we do for HTTP/1.
2473 // TODO: remove more Connection-specific header fields here, in addition
2474 // to "Connection".
2475 if _, ok := rws.snapHeader["Connection"]; ok {
2476 v := rws.snapHeader.Get("Connection")
2477 delete(rws.snapHeader, "Connection")
2478 if v == "close" {
2479 rws.conn.startGracefulShutdown()
2480 }
2481 }
2482
2483 endStream := (rws.handlerDone && !rws.hasTrailers() && len(p) == 0) || isHeadResp
2484 err = rws.conn.writeHeaders(rws.stream, &writeResHeaders{
2485 streamID: rws.stream.id,
2486 httpResCode: rws.status,
2487 h: rws.snapHeader,
2488 endStream: endStream,
2489 contentType: ctype,
2490 contentLength: clen,
2491 date: date,
2492 })
2493 if err != nil {
2494 rws.dirty = true
2495 return 0, err
2496 }
2497 if endStream {
2498 return 0, nil
2499 }
2500 }
2501 if isHeadResp {
2502 return len(p), nil
2503 }
2504 if len(p) == 0 && !rws.handlerDone {
2505 return 0, nil
2506 }
2507
2508 if rws.handlerDone {
2509 rws.promoteUndeclaredTrailers()
2510 }
2511
2512 // only send trailers if they have actually been defined by the
2513 // server handler.
2514 hasNonemptyTrailers := rws.hasNonemptyTrailers()
2515 endStream := rws.handlerDone && !hasNonemptyTrailers
2516 if len(p) > 0 || endStream {
2517 // only send a 0 byte DATA frame if we're ending the stream.
2518 if err := rws.conn.writeDataFromHandler(rws.stream, p, endStream); err != nil {
2519 rws.dirty = true
2520 return 0, err
2521 }
2522 }
2523
2524 if rws.handlerDone && hasNonemptyTrailers {
2525 err = rws.conn.writeHeaders(rws.stream, &writeResHeaders{
2526 streamID: rws.stream.id,
2527 h: rws.handlerHeader,
2528 trailers: rws.trailers,
2529 endStream: true,
2530 })
2531 if err != nil {
2532 rws.dirty = true
2533 }
2534 return len(p), err
2535 }
2536 return len(p), nil
2537}
2538
2539// TrailerPrefix is a magic prefix for ResponseWriter.Header map keys
2540// that, if present, signals that the map entry is actually for
2541// the response trailers, and not the response headers. The prefix
2542// is stripped after the ServeHTTP call finishes and the values are
2543// sent in the trailers.
2544//
2545// This mechanism is intended only for trailers that are not known
2546// prior to the headers being written. If the set of trailers is fixed
2547// or known before the header is written, the normal Go trailers mechanism
2548// is preferred:
2549// https://golang.org/pkg/net/http/#ResponseWriter
2550// https://golang.org/pkg/net/http/#example_ResponseWriter_trailers
2551const TrailerPrefix = "Trailer:"
2552
2553// promoteUndeclaredTrailers permits http.Handlers to set trailers
2554// after the header has already been flushed. Because the Go
2555// ResponseWriter interface has no way to set Trailers (only the
2556// Header), and because we didn't want to expand the ResponseWriter
2557// interface, and because nobody used trailers, and because RFC 7230
2558// says you SHOULD (but not must) predeclare any trailers in the
2559// header, the official ResponseWriter rules said trailers in Go must
2560// be predeclared, and then we reuse the same ResponseWriter.Header()
2561// map to mean both Headers and Trailers. When it's time to write the
2562// Trailers, we pick out the fields of Headers that were declared as
2563// trailers. That worked for a while, until we found the first major
2564// user of Trailers in the wild: gRPC (using them only over http2),
2565// and gRPC libraries permit setting trailers mid-stream without
Andrea Campanella764f1ed2022-03-24 11:46:38 +01002566// predeclaring them. So: change of plans. We still permit the old
kesavand2cde6582020-06-22 04:56:23 -04002567// way, but we also permit this hack: if a Header() key begins with
2568// "Trailer:", the suffix of that key is a Trailer. Because ':' is an
2569// invalid token byte anyway, there is no ambiguity. (And it's already
2570// filtered out) It's mildly hacky, but not terrible.
2571//
2572// This method runs after the Handler is done and promotes any Header
2573// fields to be trailers.
2574func (rws *responseWriterState) promoteUndeclaredTrailers() {
2575 for k, vv := range rws.handlerHeader {
2576 if !strings.HasPrefix(k, TrailerPrefix) {
2577 continue
2578 }
2579 trailerKey := strings.TrimPrefix(k, TrailerPrefix)
2580 rws.declareTrailer(trailerKey)
2581 rws.handlerHeader[http.CanonicalHeaderKey(trailerKey)] = vv
2582 }
2583
2584 if len(rws.trailers) > 1 {
2585 sorter := sorterPool.Get().(*sorter)
2586 sorter.SortStrings(rws.trailers)
2587 sorterPool.Put(sorter)
2588 }
2589}
2590
2591func (w *responseWriter) Flush() {
2592 rws := w.rws
2593 if rws == nil {
2594 panic("Header called after Handler finished")
2595 }
2596 if rws.bw.Buffered() > 0 {
2597 if err := rws.bw.Flush(); err != nil {
2598 // Ignore the error. The frame writer already knows.
2599 return
2600 }
2601 } else {
2602 // The bufio.Writer won't call chunkWriter.Write
2603 // (writeChunk with zero bytes, so we have to do it
2604 // ourselves to force the HTTP response header and/or
2605 // final DATA frame (with END_STREAM) to be sent.
2606 rws.writeChunk(nil)
2607 }
2608}
2609
2610func (w *responseWriter) CloseNotify() <-chan bool {
2611 rws := w.rws
2612 if rws == nil {
2613 panic("CloseNotify called after Handler finished")
2614 }
2615 rws.closeNotifierMu.Lock()
2616 ch := rws.closeNotifierCh
2617 if ch == nil {
2618 ch = make(chan bool, 1)
2619 rws.closeNotifierCh = ch
2620 cw := rws.stream.cw
2621 go func() {
2622 cw.Wait() // wait for close
2623 ch <- true
2624 }()
2625 }
2626 rws.closeNotifierMu.Unlock()
2627 return ch
2628}
2629
2630func (w *responseWriter) Header() http.Header {
2631 rws := w.rws
2632 if rws == nil {
2633 panic("Header called after Handler finished")
2634 }
2635 if rws.handlerHeader == nil {
2636 rws.handlerHeader = make(http.Header)
2637 }
2638 return rws.handlerHeader
2639}
2640
2641// checkWriteHeaderCode is a copy of net/http's checkWriteHeaderCode.
2642func checkWriteHeaderCode(code int) {
2643 // Issue 22880: require valid WriteHeader status codes.
2644 // For now we only enforce that it's three digits.
2645 // In the future we might block things over 599 (600 and above aren't defined
2646 // at http://httpwg.org/specs/rfc7231.html#status.codes)
2647 // and we might block under 200 (once we have more mature 1xx support).
2648 // But for now any three digits.
2649 //
2650 // We used to send "HTTP/1.1 000 0" on the wire in responses but there's
2651 // no equivalent bogus thing we can realistically send in HTTP/2,
2652 // so we'll consistently panic instead and help people find their bugs
2653 // early. (We can't return an error from WriteHeader even if we wanted to.)
2654 if code < 100 || code > 999 {
2655 panic(fmt.Sprintf("invalid WriteHeader code %v", code))
2656 }
2657}
2658
2659func (w *responseWriter) WriteHeader(code int) {
2660 rws := w.rws
2661 if rws == nil {
2662 panic("WriteHeader called after Handler finished")
2663 }
2664 rws.writeHeader(code)
2665}
2666
2667func (rws *responseWriterState) writeHeader(code int) {
2668 if !rws.wroteHeader {
2669 checkWriteHeaderCode(code)
2670 rws.wroteHeader = true
2671 rws.status = code
2672 if len(rws.handlerHeader) > 0 {
2673 rws.snapHeader = cloneHeader(rws.handlerHeader)
2674 }
2675 }
2676}
2677
2678func cloneHeader(h http.Header) http.Header {
2679 h2 := make(http.Header, len(h))
2680 for k, vv := range h {
2681 vv2 := make([]string, len(vv))
2682 copy(vv2, vv)
2683 h2[k] = vv2
2684 }
2685 return h2
2686}
2687
2688// The Life Of A Write is like this:
2689//
2690// * Handler calls w.Write or w.WriteString ->
2691// * -> rws.bw (*bufio.Writer) ->
2692// * (Handler might call Flush)
2693// * -> chunkWriter{rws}
2694// * -> responseWriterState.writeChunk(p []byte)
2695// * -> responseWriterState.writeChunk (most of the magic; see comment there)
2696func (w *responseWriter) Write(p []byte) (n int, err error) {
2697 return w.write(len(p), p, "")
2698}
2699
2700func (w *responseWriter) WriteString(s string) (n int, err error) {
2701 return w.write(len(s), nil, s)
2702}
2703
2704// either dataB or dataS is non-zero.
2705func (w *responseWriter) write(lenData int, dataB []byte, dataS string) (n int, err error) {
2706 rws := w.rws
2707 if rws == nil {
2708 panic("Write called after Handler finished")
2709 }
2710 if !rws.wroteHeader {
2711 w.WriteHeader(200)
2712 }
2713 if !bodyAllowedForStatus(rws.status) {
2714 return 0, http.ErrBodyNotAllowed
2715 }
2716 rws.wroteBytes += int64(len(dataB)) + int64(len(dataS)) // only one can be set
2717 if rws.sentContentLen != 0 && rws.wroteBytes > rws.sentContentLen {
2718 // TODO: send a RST_STREAM
2719 return 0, errors.New("http2: handler wrote more than declared Content-Length")
2720 }
2721
2722 if dataB != nil {
2723 return rws.bw.Write(dataB)
2724 } else {
2725 return rws.bw.WriteString(dataS)
2726 }
2727}
2728
2729func (w *responseWriter) handlerDone() {
2730 rws := w.rws
2731 dirty := rws.dirty
2732 rws.handlerDone = true
2733 w.Flush()
2734 w.rws = nil
2735 if !dirty {
2736 // Only recycle the pool if all prior Write calls to
2737 // the serverConn goroutine completed successfully. If
2738 // they returned earlier due to resets from the peer
2739 // there might still be write goroutines outstanding
2740 // from the serverConn referencing the rws memory. See
2741 // issue 20704.
2742 responseWriterStatePool.Put(rws)
2743 }
2744}
2745
2746// Push errors.
2747var (
2748 ErrRecursivePush = errors.New("http2: recursive push not allowed")
2749 ErrPushLimitReached = errors.New("http2: push would exceed peer's SETTINGS_MAX_CONCURRENT_STREAMS")
2750)
2751
2752var _ http.Pusher = (*responseWriter)(nil)
2753
2754func (w *responseWriter) Push(target string, opts *http.PushOptions) error {
2755 st := w.rws.stream
2756 sc := st.sc
2757 sc.serveG.checkNotOn()
2758
2759 // No recursive pushes: "PUSH_PROMISE frames MUST only be sent on a peer-initiated stream."
2760 // http://tools.ietf.org/html/rfc7540#section-6.6
2761 if st.isPushed() {
2762 return ErrRecursivePush
2763 }
2764
2765 if opts == nil {
2766 opts = new(http.PushOptions)
2767 }
2768
2769 // Default options.
2770 if opts.Method == "" {
2771 opts.Method = "GET"
2772 }
2773 if opts.Header == nil {
2774 opts.Header = http.Header{}
2775 }
2776 wantScheme := "http"
2777 if w.rws.req.TLS != nil {
2778 wantScheme = "https"
2779 }
2780
2781 // Validate the request.
2782 u, err := url.Parse(target)
2783 if err != nil {
2784 return err
2785 }
2786 if u.Scheme == "" {
2787 if !strings.HasPrefix(target, "/") {
2788 return fmt.Errorf("target must be an absolute URL or an absolute path: %q", target)
2789 }
2790 u.Scheme = wantScheme
2791 u.Host = w.rws.req.Host
2792 } else {
2793 if u.Scheme != wantScheme {
2794 return fmt.Errorf("cannot push URL with scheme %q from request with scheme %q", u.Scheme, wantScheme)
2795 }
2796 if u.Host == "" {
2797 return errors.New("URL must have a host")
2798 }
2799 }
2800 for k := range opts.Header {
2801 if strings.HasPrefix(k, ":") {
2802 return fmt.Errorf("promised request headers cannot include pseudo header %q", k)
2803 }
2804 // These headers are meaningful only if the request has a body,
2805 // but PUSH_PROMISE requests cannot have a body.
2806 // http://tools.ietf.org/html/rfc7540#section-8.2
2807 // Also disallow Host, since the promised URL must be absolute.
kesavandc71914f2022-03-25 11:19:03 +05302808 if asciiEqualFold(k, "content-length") ||
2809 asciiEqualFold(k, "content-encoding") ||
2810 asciiEqualFold(k, "trailer") ||
2811 asciiEqualFold(k, "te") ||
2812 asciiEqualFold(k, "expect") ||
2813 asciiEqualFold(k, "host") {
kesavand2cde6582020-06-22 04:56:23 -04002814 return fmt.Errorf("promised request headers cannot include %q", k)
2815 }
2816 }
2817 if err := checkValidHTTP2RequestHeaders(opts.Header); err != nil {
2818 return err
2819 }
2820
2821 // The RFC effectively limits promised requests to GET and HEAD:
2822 // "Promised requests MUST be cacheable [GET, HEAD, or POST], and MUST be safe [GET or HEAD]"
2823 // http://tools.ietf.org/html/rfc7540#section-8.2
2824 if opts.Method != "GET" && opts.Method != "HEAD" {
2825 return fmt.Errorf("method %q must be GET or HEAD", opts.Method)
2826 }
2827
2828 msg := &startPushRequest{
2829 parent: st,
2830 method: opts.Method,
2831 url: u,
2832 header: cloneHeader(opts.Header),
2833 done: errChanPool.Get().(chan error),
2834 }
2835
2836 select {
2837 case <-sc.doneServing:
2838 return errClientDisconnected
2839 case <-st.cw:
2840 return errStreamClosed
2841 case sc.serveMsgCh <- msg:
2842 }
2843
2844 select {
2845 case <-sc.doneServing:
2846 return errClientDisconnected
2847 case <-st.cw:
2848 return errStreamClosed
2849 case err := <-msg.done:
2850 errChanPool.Put(msg.done)
2851 return err
2852 }
2853}
2854
2855type startPushRequest struct {
2856 parent *stream
2857 method string
2858 url *url.URL
2859 header http.Header
2860 done chan error
2861}
2862
2863func (sc *serverConn) startPush(msg *startPushRequest) {
2864 sc.serveG.check()
2865
2866 // http://tools.ietf.org/html/rfc7540#section-6.6.
2867 // PUSH_PROMISE frames MUST only be sent on a peer-initiated stream that
2868 // is in either the "open" or "half-closed (remote)" state.
2869 if msg.parent.state != stateOpen && msg.parent.state != stateHalfClosedRemote {
Andrea Campanella764f1ed2022-03-24 11:46:38 +01002870 // responseWriter.Push checks that the stream is peer-initiated.
kesavand2cde6582020-06-22 04:56:23 -04002871 msg.done <- errStreamClosed
2872 return
2873 }
2874
2875 // http://tools.ietf.org/html/rfc7540#section-6.6.
2876 if !sc.pushEnabled {
2877 msg.done <- http.ErrNotSupported
2878 return
2879 }
2880
2881 // PUSH_PROMISE frames must be sent in increasing order by stream ID, so
2882 // we allocate an ID for the promised stream lazily, when the PUSH_PROMISE
2883 // is written. Once the ID is allocated, we start the request handler.
2884 allocatePromisedID := func() (uint32, error) {
2885 sc.serveG.check()
2886
2887 // Check this again, just in case. Technically, we might have received
2888 // an updated SETTINGS by the time we got around to writing this frame.
2889 if !sc.pushEnabled {
2890 return 0, http.ErrNotSupported
2891 }
2892 // http://tools.ietf.org/html/rfc7540#section-6.5.2.
2893 if sc.curPushedStreams+1 > sc.clientMaxStreams {
2894 return 0, ErrPushLimitReached
2895 }
2896
2897 // http://tools.ietf.org/html/rfc7540#section-5.1.1.
2898 // Streams initiated by the server MUST use even-numbered identifiers.
2899 // A server that is unable to establish a new stream identifier can send a GOAWAY
2900 // frame so that the client is forced to open a new connection for new streams.
2901 if sc.maxPushPromiseID+2 >= 1<<31 {
2902 sc.startGracefulShutdownInternal()
2903 return 0, ErrPushLimitReached
2904 }
2905 sc.maxPushPromiseID += 2
2906 promisedID := sc.maxPushPromiseID
2907
2908 // http://tools.ietf.org/html/rfc7540#section-8.2.
2909 // Strictly speaking, the new stream should start in "reserved (local)", then
2910 // transition to "half closed (remote)" after sending the initial HEADERS, but
2911 // we start in "half closed (remote)" for simplicity.
2912 // See further comments at the definition of stateHalfClosedRemote.
2913 promised := sc.newStream(promisedID, msg.parent.id, stateHalfClosedRemote)
2914 rw, req, err := sc.newWriterAndRequestNoBody(promised, requestParam{
2915 method: msg.method,
2916 scheme: msg.url.Scheme,
2917 authority: msg.url.Host,
2918 path: msg.url.RequestURI(),
2919 header: cloneHeader(msg.header), // clone since handler runs concurrently with writing the PUSH_PROMISE
2920 })
2921 if err != nil {
2922 // Should not happen, since we've already validated msg.url.
2923 panic(fmt.Sprintf("newWriterAndRequestNoBody(%+v): %v", msg.url, err))
2924 }
2925
2926 go sc.runHandler(rw, req, sc.handler.ServeHTTP)
2927 return promisedID, nil
2928 }
2929
2930 sc.writeFrame(FrameWriteRequest{
2931 write: &writePushPromise{
2932 streamID: msg.parent.id,
2933 method: msg.method,
2934 url: msg.url,
2935 h: msg.header,
2936 allocatePromisedID: allocatePromisedID,
2937 },
2938 stream: msg.parent,
2939 done: msg.done,
2940 })
2941}
2942
2943// foreachHeaderElement splits v according to the "#rule" construction
2944// in RFC 7230 section 7 and calls fn for each non-empty element.
2945func foreachHeaderElement(v string, fn func(string)) {
2946 v = textproto.TrimString(v)
2947 if v == "" {
2948 return
2949 }
2950 if !strings.Contains(v, ",") {
2951 fn(v)
2952 return
2953 }
2954 for _, f := range strings.Split(v, ",") {
2955 if f = textproto.TrimString(f); f != "" {
2956 fn(f)
2957 }
2958 }
2959}
2960
2961// From http://httpwg.org/specs/rfc7540.html#rfc.section.8.1.2.2
2962var connHeaders = []string{
2963 "Connection",
2964 "Keep-Alive",
2965 "Proxy-Connection",
2966 "Transfer-Encoding",
2967 "Upgrade",
2968}
2969
2970// checkValidHTTP2RequestHeaders checks whether h is a valid HTTP/2 request,
2971// per RFC 7540 Section 8.1.2.2.
2972// The returned error is reported to users.
2973func checkValidHTTP2RequestHeaders(h http.Header) error {
2974 for _, k := range connHeaders {
2975 if _, ok := h[k]; ok {
2976 return fmt.Errorf("request header %q is not valid in HTTP/2", k)
2977 }
2978 }
2979 te := h["Te"]
2980 if len(te) > 0 && (len(te) > 1 || (te[0] != "trailers" && te[0] != "")) {
2981 return errors.New(`request header "TE" may only be "trailers" in HTTP/2`)
2982 }
2983 return nil
2984}
2985
2986func new400Handler(err error) http.HandlerFunc {
2987 return func(w http.ResponseWriter, r *http.Request) {
2988 http.Error(w, err.Error(), http.StatusBadRequest)
2989 }
2990}
2991
2992// h1ServerKeepAlivesDisabled reports whether hs has its keep-alives
2993// disabled. See comments on h1ServerShutdownChan above for why
2994// the code is written this way.
2995func h1ServerKeepAlivesDisabled(hs *http.Server) bool {
2996 var x interface{} = hs
2997 type I interface {
2998 doKeepAlives() bool
2999 }
3000 if hs, ok := x.(I); ok {
3001 return !hs.doKeepAlives()
3002 }
3003 return false
3004}
kesavandc71914f2022-03-25 11:19:03 +05303005
3006func (sc *serverConn) countError(name string, err error) error {
3007 if sc == nil || sc.srv == nil {
3008 return err
3009 }
3010 f := sc.srv.CountError
3011 if f == nil {
3012 return err
3013 }
3014 var typ string
3015 var code ErrCode
3016 switch e := err.(type) {
3017 case ConnectionError:
3018 typ = "conn"
3019 code = ErrCode(e)
3020 case StreamError:
3021 typ = "stream"
3022 code = ErrCode(e.Code)
3023 default:
3024 return err
3025 }
3026 codeStr := errCodeName[code]
3027 if codeStr == "" {
3028 codeStr = strconv.Itoa(int(code))
3029 }
3030 f(fmt.Sprintf("%s_%s_%s", typ, codeStr, name))
3031 return err
3032}