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