blob: d790c3b3d598e86dda012ed24e3181417825babb [file] [log] [blame]
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001// 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.
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08004
Brad Fitzpatrickcf896632014-12-09 07:15:26 +11005// 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
Brad Fitzpatrickb331b812014-11-13 11:51:54 -080026package http2
27
28import (
Brad Fitzpatrick390047e2014-11-14 20:37:08 -080029 "bufio"
Brad Fitzpatrickb331b812014-11-13 11:51:54 -080030 "bytes"
31 "crypto/tls"
32 "errors"
33 "fmt"
34 "io"
35 "log"
Tom Berganc46f2652016-10-25 10:13:20 -070036 "math"
Brad Fitzpatrickb331b812014-11-13 11:51:54 -080037 "net"
38 "net/http"
Blake Mizeranyb4be4942015-12-15 17:33:14 -080039 "net/textproto"
Brad Fitzpatrickb331b812014-11-13 11:51:54 -080040 "net/url"
Brad Fitzpatrickeb066e32016-01-26 18:31:02 +000041 "os"
42 "reflect"
Brad Fitzpatrick74bd44b2015-12-15 00:47:28 +000043 "runtime"
Brad Fitzpatrickb331b812014-11-13 11:51:54 -080044 "strconv"
45 "strings"
Brad Fitzpatrick729bd722014-11-13 14:09:36 -080046 "sync"
Brad Fitzpatrick95842032014-11-15 09:47:42 -080047 "time"
Brad Fitzpatrickb331b812014-11-13 11:51:54 -080048
Brad Fitzpatrickae54c552015-09-24 09:19:02 +020049 "golang.org/x/net/http2/hpack"
Brad Fitzpatrickb331b812014-11-13 11:51:54 -080050)
51
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -080052const (
Brad Fitzpatrick9581fe12014-11-28 13:51:46 -080053 prefaceTimeout = 10 * time.Second
Brad Fitzpatrick4e3c9222014-11-22 17:35:09 -080054 firstSettingsTimeout = 2 * time.Second // should be in-flight with preface anyway
55 handlerChunkWriteSize = 4 << 10
Brad Fitzpatrick068d35d2014-12-09 07:10:31 +110056 defaultMaxStreams = 250 // TODO: make this 100 as the GFE seems to?
Brad Fitzpatrick4e3c9222014-11-22 17:35:09 -080057)
58
59var (
60 errClientDisconnected = errors.New("client disconnected")
61 errClosedBody = errors.New("body closed by handler")
Brad Fitzpatrickb7f5d982015-10-26 13:59:20 -050062 errHandlerComplete = errors.New("http2: request body closed due to handler exiting")
Brad Fitzpatrick56401052015-10-20 22:27:39 +000063 errStreamClosed = errors.New("http2: stream closed")
Brad Fitzpatrick4e3c9222014-11-22 17:35:09 -080064)
65
66var responseWriterStatePool = sync.Pool{
67 New: func() interface{} {
68 rws := &responseWriterState{}
69 rws.bw = bufio.NewWriterSize(chunkWriter{rws}, handlerChunkWriteSize)
70 return rws
71 },
72}
73
74// Test hooks.
75var (
76 testHookOnConn func()
77 testHookGetServerConn func(*serverConn)
Brad Fitzpatrickf3a6d9a2014-12-08 07:53:36 -080078 testHookOnPanicMu *sync.Mutex // nil except in tests
Brad Fitzpatrick996adcb2014-12-08 01:08:19 -080079 testHookOnPanic func(sc *serverConn, panicVal interface{}) (rePanic bool)
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -080080)
81
Brad Fitzpatrickb331b812014-11-13 11:51:54 -080082// Server is an HTTP/2 server.
83type Server struct {
Brad Fitzpatrick6ec17312014-11-23 10:07:07 -080084 // MaxHandlers limits the number of http.Handler ServeHTTP goroutines
85 // which may run at a time over all connections.
86 // Negative or zero no limit.
87 // TODO: implement
88 MaxHandlers int
89
90 // MaxConcurrentStreams optionally specifies the number of
91 // concurrent streams that each client may have open at a
92 // time. This is unrelated to the number of http.Handler goroutines
93 // which may be active globally, which is MaxHandlers.
94 // If zero, MaxConcurrentStreams defaults to at least 100, per
95 // the HTTP/2 spec's recommendations.
96 MaxConcurrentStreams uint32
Brad Fitzpatrick21896bb2014-11-19 16:05:21 -080097
98 // MaxReadFrameSize optionally specifies the largest frame
99 // this server is willing to read. A valid value is between
Brad Fitzpatrick6ec17312014-11-23 10:07:07 -0800100 // 16k and 16M, inclusive. If zero or otherwise invalid, a
101 // default value is used.
Brad Fitzpatrick21896bb2014-11-19 16:05:21 -0800102 MaxReadFrameSize uint32
Brad Fitzpatricke4cd9ad2015-01-17 18:03:57 -0800103
104 // PermitProhibitedCipherSuites, if true, permits the use of
105 // cipher suites prohibited by the HTTP/2 spec.
106 PermitProhibitedCipherSuites bool
Brad Fitzpatrickc33d3782016-10-22 11:37:19 -0700107
108 // IdleTimeout specifies how long until idle clients should be
109 // closed with a GOAWAY frame. PING frames are not considered
110 // activity for the purposes of IdleTimeout.
111 IdleTimeout time.Duration
Tom Bergan4be9b972016-08-01 18:07:35 -0700112
Tom Bergan906cda92017-02-18 12:36:51 -0800113 // MaxUploadBufferPerConnection is the size of the initial flow
114 // control window for each connections. The HTTP/2 spec does not
115 // allow this to be smaller than 65535 or larger than 2^32-1.
116 // If the value is outside this range, a default value will be
117 // used instead.
118 MaxUploadBufferPerConnection int32
119
120 // MaxUploadBufferPerStream is the size of the initial flow control
121 // window for each stream. The HTTP/2 spec does not allow this to
122 // be larger than 2^32-1. If the value is zero or larger than the
123 // maximum, a default value will be used instead.
124 MaxUploadBufferPerStream int32
125
Tom Bergan4be9b972016-08-01 18:07:35 -0700126 // NewWriteScheduler constructs a write scheduler for a connection.
127 // If nil, a default scheduler is chosen.
128 NewWriteScheduler func() WriteScheduler
Tom Bergana8e8f922017-05-15 12:29:23 -0700129
130 // Internal state. This is a pointer (rather than embedded directly)
131 // so that we don't embed a Mutex in this struct, which will make the
132 // struct non-copyable, which might break some callers.
133 state *serverInternalState
Brad Fitzpatrick21896bb2014-11-19 16:05:21 -0800134}
135
Tom Bergan906cda92017-02-18 12:36:51 -0800136func (s *Server) initialConnRecvWindowSize() int32 {
137 if s.MaxUploadBufferPerConnection > initialWindowSize {
138 return s.MaxUploadBufferPerConnection
139 }
140 return 1 << 20
141}
142
143func (s *Server) initialStreamRecvWindowSize() int32 {
144 if s.MaxUploadBufferPerStream > 0 {
145 return s.MaxUploadBufferPerStream
146 }
147 return 1 << 20
148}
149
Brad Fitzpatrick21896bb2014-11-19 16:05:21 -0800150func (s *Server) maxReadFrameSize() uint32 {
151 if v := s.MaxReadFrameSize; v >= minMaxFrameSize && v <= maxFrameSize {
152 return v
153 }
154 return defaultMaxReadFrameSize
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800155}
156
Brad Fitzpatrick6ec17312014-11-23 10:07:07 -0800157func (s *Server) maxConcurrentStreams() uint32 {
158 if v := s.MaxConcurrentStreams; v > 0 {
159 return v
160 }
161 return defaultMaxStreams
162}
163
Tom Bergana8e8f922017-05-15 12:29:23 -0700164type serverInternalState struct {
165 mu sync.Mutex
166 activeConns map[*serverConn]struct{}
167}
168
169func (s *serverInternalState) registerConn(sc *serverConn) {
170 if s == nil {
171 return // if the Server was used without calling ConfigureServer
172 }
173 s.mu.Lock()
174 s.activeConns[sc] = struct{}{}
175 s.mu.Unlock()
176}
177
178func (s *serverInternalState) unregisterConn(sc *serverConn) {
179 if s == nil {
180 return // if the Server was used without calling ConfigureServer
181 }
182 s.mu.Lock()
183 delete(s.activeConns, sc)
184 s.mu.Unlock()
185}
186
187func (s *serverInternalState) startGracefulShutdown() {
188 if s == nil {
189 return // if the Server was used without calling ConfigureServer
190 }
191 s.mu.Lock()
192 for sc := range s.activeConns {
193 sc.startGracefulShutdown()
194 }
195 s.mu.Unlock()
196}
197
Brad Fitzpatrickb5469d22014-11-13 12:17:52 -0800198// ConfigureServer adds HTTP/2 support to a net/http Server.
199//
200// The configuration conf may be nil.
201//
202// ConfigureServer must be called before s begins serving.
Brad Fitzpatrick42ad5082015-10-15 01:02:25 +0000203func ConfigureServer(s *http.Server, conf *Server) error {
Brad Fitzpatrickb336a972016-10-27 19:58:04 +0000204 if s == nil {
205 panic("nil *http.Server")
206 }
Brad Fitzpatrickb5469d22014-11-13 12:17:52 -0800207 if conf == nil {
208 conf = new(Server)
209 }
Tom Bergana8e8f922017-05-15 12:29:23 -0700210 conf.state = &serverInternalState{activeConns: make(map[*serverConn]struct{})}
Brad Fitzpatrick76c1a112016-10-29 19:01:05 +0000211 if err := configureServer18(s, conf); err != nil {
212 return err
Brad Fitzpatrickb336a972016-10-27 19:58:04 +0000213 }
Tom Bergana8e8f922017-05-15 12:29:23 -0700214 if err := configureServer19(s, conf); err != nil {
215 return err
216 }
Brad Fitzpatrick42ad5082015-10-15 01:02:25 +0000217
Brad Fitzpatrickb5469d22014-11-13 12:17:52 -0800218 if s.TLSConfig == nil {
219 s.TLSConfig = new(tls.Config)
Brad Fitzpatrick42ad5082015-10-15 01:02:25 +0000220 } else if s.TLSConfig.CipherSuites != nil {
221 // If they already provided a CipherSuite list, return
222 // an error if it has a bad order or is missing
223 // ECDHE_RSA_WITH_AES_128_GCM_SHA256.
224 const requiredCipher = tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
225 haveRequired := false
226 sawBad := false
227 for i, cs := range s.TLSConfig.CipherSuites {
228 if cs == requiredCipher {
229 haveRequired = true
230 }
231 if isBadCipher(cs) {
232 sawBad = true
233 } else if sawBad {
234 return fmt.Errorf("http2: TLSConfig.CipherSuites index %d contains an HTTP/2-approved cipher suite (%#04x), but it comes after unapproved cipher suites. With this configuration, clients that don't support previous, approved cipher suites may be given an unapproved one and reject the connection.", i, cs)
235 }
236 }
237 if !haveRequired {
238 return fmt.Errorf("http2: TLSConfig.CipherSuites is missing HTTP/2-required TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256")
239 }
Brad Fitzpatrickb5469d22014-11-13 12:17:52 -0800240 }
Brad Fitzpatrick5df015f2014-12-08 11:16:59 -0800241
242 // Note: not setting MinVersion to tls.VersionTLS12,
243 // as we don't want to interfere with HTTP/1.1 traffic
244 // on the user's server. We enforce TLS 1.2 later once
245 // we accept a connection. Ideally this should be done
246 // during next-proto selection, but using TLS <1.2 with
247 // HTTP/2 is still the client's bug.
248
Brad Fitzpatrick42ad5082015-10-15 01:02:25 +0000249 s.TLSConfig.PreferServerCipherSuites = true
Brad Fitzpatrick5df015f2014-12-08 11:16:59 -0800250
Brad Fitzpatrickb5469d22014-11-13 12:17:52 -0800251 haveNPN := false
252 for _, p := range s.TLSConfig.NextProtos {
Brad Fitzpatrick36d9a672014-11-26 07:40:15 -0800253 if p == NextProtoTLS {
Brad Fitzpatrickb5469d22014-11-13 12:17:52 -0800254 haveNPN = true
255 break
256 }
257 }
258 if !haveNPN {
Brad Fitzpatrick36d9a672014-11-26 07:40:15 -0800259 s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, NextProtoTLS)
Brad Fitzpatrickb5469d22014-11-13 12:17:52 -0800260 }
261
262 if s.TLSNextProto == nil {
263 s.TLSNextProto = map[string]func(*http.Server, *tls.Conn, http.Handler){}
264 }
Brad Fitzpatrick13dfd892015-03-05 15:57:11 -0800265 protoHandler := func(hs *http.Server, c *tls.Conn, h http.Handler) {
Brad Fitzpatrickb5469d22014-11-13 12:17:52 -0800266 if testHookOnConn != nil {
267 testHookOnConn()
268 }
Brad Fitzpatrick6ccd6692016-02-02 14:37:19 -0800269 conf.ServeConn(c, &ServeConnOpts{
270 Handler: h,
271 BaseConfig: hs,
272 })
Brad Fitzpatrickb5469d22014-11-13 12:17:52 -0800273 }
Brad Fitzpatrick13dfd892015-03-05 15:57:11 -0800274 s.TLSNextProto[NextProtoTLS] = protoHandler
Brad Fitzpatrick42ad5082015-10-15 01:02:25 +0000275 return nil
Brad Fitzpatrickb5469d22014-11-13 12:17:52 -0800276}
277
Brad Fitzpatrick6ccd6692016-02-02 14:37:19 -0800278// ServeConnOpts are options for the Server.ServeConn method.
279type ServeConnOpts struct {
280 // BaseConfig optionally sets the base configuration
281 // for values. If nil, defaults are used.
282 BaseConfig *http.Server
283
284 // Handler specifies which handler to use for processing
285 // requests. If nil, BaseConfig.Handler is used. If BaseConfig
286 // or BaseConfig.Handler is nil, http.DefaultServeMux is used.
287 Handler http.Handler
288}
289
290func (o *ServeConnOpts) baseConfig() *http.Server {
291 if o != nil && o.BaseConfig != nil {
292 return o.BaseConfig
293 }
294 return new(http.Server)
295}
296
297func (o *ServeConnOpts) handler() http.Handler {
298 if o != nil {
299 if o.Handler != nil {
300 return o.Handler
301 }
302 if o.BaseConfig != nil && o.BaseConfig.Handler != nil {
303 return o.BaseConfig.Handler
304 }
305 }
306 return http.DefaultServeMux
307}
308
309// ServeConn serves HTTP/2 requests on the provided connection and
310// blocks until the connection is no longer readable.
311//
312// ServeConn starts speaking HTTP/2 assuming that c has not had any
313// reads or writes. It writes its initial settings frame and expects
314// to be able to read the preface and settings frame from the
315// client. If c has a ConnectionState method like a *tls.Conn, the
316// ConnectionState is used to verify the TLS ciphersuite and to set
317// the Request.TLS field in Handlers.
318//
319// ServeConn does not support h2c by itself. Any h2c support must be
320// implemented in terms of providing a suitably-behaving net.Conn.
321//
322// The opts parameter is optional. If nil, default values are used.
323func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) {
Brad Fitzpatrick8aacbec2016-05-18 19:54:31 +0000324 baseCtx, cancel := serverConnBaseContext(c, opts)
325 defer cancel()
326
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800327 sc := &serverConn{
Tom Bergan906cda92017-02-18 12:36:51 -0800328 srv: s,
329 hs: opts.baseConfig(),
330 conn: c,
331 baseCtx: baseCtx,
332 remoteAddrStr: c.RemoteAddr().String(),
333 bw: newBufferedWriter(c),
334 handler: opts.handler(),
335 streams: make(map[uint32]*stream),
336 readFrameCh: make(chan readFrameResult),
337 wantWriteFrameCh: make(chan FrameWriteRequest, 8),
Brad Fitzpatrick34057062017-05-09 12:22:37 -0700338 serveMsgCh: make(chan interface{}, 8),
Tom Bergan906cda92017-02-18 12:36:51 -0800339 wroteFrameCh: make(chan frameWriteResult, 1), // buffered; one send in writeFrameAsync
340 bodyReadCh: make(chan bodyReadMsg), // buffering doesn't matter either way
341 doneServing: make(chan struct{}),
342 clientMaxStreams: math.MaxUint32, // Section 6.5.2: "Initially, there is no limit to this value"
343 advMaxStreams: s.maxConcurrentStreams(),
344 initialStreamSendWindowSize: initialWindowSize,
345 maxFrameSize: initialMaxFrameSize,
346 headerTableSize: initialHeaderTableSize,
347 serveG: newGoroutineLock(),
348 pushEnabled: true,
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800349 }
Brad Fitzpatrick8aacbec2016-05-18 19:54:31 +0000350
Tom Bergana8e8f922017-05-15 12:29:23 -0700351 s.state.registerConn(sc)
352 defer s.state.unregisterConn(sc)
353
Kale Blankenship8fd7f252016-12-29 12:13:24 -0800354 // The net/http package sets the write deadline from the
355 // http.Server.WriteTimeout during the TLS handshake, but then
Kale Blankenshipd1e1b352016-12-29 14:47:41 -0800356 // passes the connection off to us with the deadline already set.
357 // Write deadlines are set per stream in serverConn.newStream.
358 // Disarm the net.Conn write deadline here.
Kale Blankenship8fd7f252016-12-29 12:13:24 -0800359 if sc.hs.WriteTimeout != 0 {
360 sc.conn.SetWriteDeadline(time.Time{})
361 }
362
Tom Bergan4be9b972016-08-01 18:07:35 -0700363 if s.NewWriteScheduler != nil {
364 sc.writeSched = s.NewWriteScheduler()
365 } else {
366 sc.writeSched = NewRandomWriteScheduler()
367 }
368
Tom Bergan906cda92017-02-18 12:36:51 -0800369 // These start at the RFC-specified defaults. If there is a higher
370 // configured value for inflow, that will be updated when we send a
371 // WINDOW_UPDATE shortly after sending SETTINGS.
Brad Fitzpatrick98766182014-12-02 10:30:08 -0800372 sc.flow.add(initialWindowSize)
Brad Fitzpatrick068d35d2014-12-09 07:10:31 +1100373 sc.inflow.add(initialWindowSize)
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800374 sc.hpackEncoder = hpack.NewEncoder(&sc.headerWriteBuf)
Brad Fitzpatrick5e4e2dc2014-11-19 16:49:43 -0800375
376 fr := NewFramer(sc.bw, c)
Brad Fitzpatrick9e1fb3c2016-02-20 14:24:27 +0530377 fr.ReadMetaHeaders = hpack.NewDecoder(initialHeaderTableSize, nil)
378 fr.MaxHeaderListSize = sc.maxHeaderListSize()
Brad Fitzpatrick6ccd6692016-02-02 14:37:19 -0800379 fr.SetMaxReadFrameSize(s.maxReadFrameSize())
Brad Fitzpatrick5e4e2dc2014-11-19 16:49:43 -0800380 sc.framer = fr
381
Brad Fitzpatrick6ccd6692016-02-02 14:37:19 -0800382 if tc, ok := c.(connectionStater); ok {
Brad Fitzpatrick30b16812014-12-08 10:10:39 -0800383 sc.tlsState = new(tls.ConnectionState)
384 *sc.tlsState = tc.ConnectionState()
385 // 9.2 Use of TLS Features
386 // An implementation of HTTP/2 over TLS MUST use TLS
387 // 1.2 or higher with the restrictions on feature set
388 // and cipher suite described in this section. Due to
389 // implementation limitations, it might not be
390 // possible to fail TLS negotiation. An endpoint MUST
391 // immediately terminate an HTTP/2 connection that
392 // does not meet the TLS requirements described in
393 // this section with a connection error (Section
394 // 5.4.1) of type INADEQUATE_SECURITY.
395 if sc.tlsState.Version < tls.VersionTLS12 {
Brad Fitzpatrick842bf9f2014-12-08 10:31:57 -0800396 sc.rejectConn(ErrCodeInadequateSecurity, "TLS version too low")
Brad Fitzpatrick30b16812014-12-08 10:10:39 -0800397 return
398 }
Brad Fitzpatrick842bf9f2014-12-08 10:31:57 -0800399
Brad Fitzpatrick842bf9f2014-12-08 10:31:57 -0800400 if sc.tlsState.ServerName == "" {
Brad Fitzpatrickf0f78762015-01-17 12:25:12 -0800401 // Client must use SNI, but we don't enforce that anymore,
402 // since it was causing problems when connecting to bare IP
403 // addresses during development.
404 //
405 // TODO: optionally enforce? Or enforce at the time we receive
406 // a new request, and verify the the ServerName matches the :authority?
407 // But that precludes proxy situations, perhaps.
408 //
409 // So for now, do nothing here again.
Brad Fitzpatrick842bf9f2014-12-08 10:31:57 -0800410 }
411
Brad Fitzpatrick6ccd6692016-02-02 14:37:19 -0800412 if !s.PermitProhibitedCipherSuites && isBadCipher(sc.tlsState.CipherSuite) {
Brad Fitzpatrick5df015f2014-12-08 11:16:59 -0800413 // "Endpoints MAY choose to generate a connection error
414 // (Section 5.4.1) of type INADEQUATE_SECURITY if one of
415 // the prohibited cipher suites are negotiated."
416 //
417 // We choose that. In my opinion, the spec is weak
418 // here. It also says both parties must support at least
419 // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 so there's no
420 // excuses here. If we really must, we could allow an
421 // "AllowInsecureWeakCiphers" option on the server later.
422 // Let's see how it plays out first.
Brad Fitzpatrick36f79342015-01-17 12:24:34 -0800423 sc.rejectConn(ErrCodeInadequateSecurity, fmt.Sprintf("Prohibited TLS 1.2 Cipher Suite: %x", sc.tlsState.CipherSuite))
Brad Fitzpatrick5df015f2014-12-08 11:16:59 -0800424 return
425 }
Brad Fitzpatrick30b16812014-12-08 10:10:39 -0800426 }
427
Brad Fitzpatrick0db6d652014-11-15 15:49:19 -0800428 if hook := testHookGetServerConn; hook != nil {
429 hook(sc)
430 }
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800431 sc.serve()
432}
433
Brad Fitzpatrick842bf9f2014-12-08 10:31:57 -0800434func (sc *serverConn) rejectConn(err ErrCode, debug string) {
Brad Fitzpatrick415f1912015-12-16 20:28:38 +0000435 sc.vlogf("http2: server rejecting conn: %v, %s", err, debug)
Brad Fitzpatrick842bf9f2014-12-08 10:31:57 -0800436 // ignoring errors. hanging up anyway.
437 sc.framer.WriteGoAway(0, err, []byte(debug))
438 sc.bw.Flush()
439 sc.conn.Close()
440}
441
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800442type serverConn struct {
443 // Immutable:
Brad Fitzpatrick21896bb2014-11-19 16:05:21 -0800444 srv *Server
Brad Fitzpatrick520123b2014-11-14 15:57:37 -0800445 hs *http.Server
446 conn net.Conn
Brad Fitzpatrick5e4e2dc2014-11-19 16:49:43 -0800447 bw *bufferedWriter // writing to conn
Brad Fitzpatrick520123b2014-11-14 15:57:37 -0800448 handler http.Handler
Brad Fitzpatrick8aacbec2016-05-18 19:54:31 +0000449 baseCtx contextContext
Brad Fitzpatrick520123b2014-11-14 15:57:37 -0800450 framer *Framer
Tom Bergan4be9b972016-08-01 18:07:35 -0700451 doneServing chan struct{} // closed when serverConn.serve ends
452 readFrameCh chan readFrameResult // written by serverConn.readFrames
453 wantWriteFrameCh chan FrameWriteRequest // from handlers -> serve
454 wroteFrameCh chan frameWriteResult // from writeFrameAsync -> serve, tickles more frame writes
455 bodyReadCh chan bodyReadMsg // from handlers -> serve
Brad Fitzpatrick34057062017-05-09 12:22:37 -0700456 serveMsgCh chan interface{} // misc messages & code to send to / run on the serve loop
Tom Bergan4be9b972016-08-01 18:07:35 -0700457 flow flow // conn-wide (not stream-specific) outbound flow control
458 inflow flow // conn-wide inbound flow control
459 tlsState *tls.ConnectionState // shared by all handlers, like net/http
Brad Fitzpatrickdf959c22014-12-09 07:20:20 +1100460 remoteAddrStr string
Tom Bergan4be9b972016-08-01 18:07:35 -0700461 writeSched WriteScheduler
Brad Fitzpatrick520123b2014-11-14 15:57:37 -0800462
463 // Everything following is owned by the serve loop; use serveG.check():
Tom Bergan906cda92017-02-18 12:36:51 -0800464 serveG goroutineLock // used to verify funcs are on serve()
465 pushEnabled bool
466 sawFirstSettings bool // got the initial SETTINGS frame after the preface
467 needToSendSettingsAck bool
468 unackedSettings int // how many SETTINGS have we sent without ACKs?
469 clientMaxStreams uint32 // SETTINGS_MAX_CONCURRENT_STREAMS from client (our PUSH_PROMISE limit)
470 advMaxStreams uint32 // our SETTINGS_MAX_CONCURRENT_STREAMS advertised the client
471 curClientStreams uint32 // number of open streams initiated by the client
472 curPushedStreams uint32 // number of open streams initiated by server push
473 maxClientStreamID uint32 // max ever seen from client (odd), or 0 if there have been no client requests
474 maxPushPromiseID uint32 // ID of the last push promise (even), or 0 if there have been no pushes
475 streams map[uint32]*stream
476 initialStreamSendWindowSize int32
477 maxFrameSize int32
478 headerTableSize uint32
479 peerMaxHeaderListSize uint32 // zero means unknown (default)
480 canonHeader map[string]string // http2-lower-case -> Go-Canonical-Case
481 writingFrame bool // started writing a frame (on serve goroutine or separate)
482 writingFrameAsync bool // started a frame on its own goroutine but haven't heard back on wroteFrameCh
483 needsFrameFlush bool // last frame write wasn't a flush
484 inGoAway bool // we've started to or sent GOAWAY
485 inFrameScheduleLoop bool // whether we're in the scheduleFrameWrite loop
486 needToSendGoAway bool // we need to schedule a GOAWAY frame write
487 goAwayCode ErrCode
Brad Fitzpatrick34057062017-05-09 12:22:37 -0700488 shutdownTimer *time.Timer // nil until used
489 idleTimer *time.Timer // nil if unused
Brad Fitzpatrick520123b2014-11-14 15:57:37 -0800490
Brad Fitzpatrick23564bf2014-11-27 19:40:04 -0800491 // Owned by the writeFrameAsync goroutine:
Brad Fitzpatrick520123b2014-11-14 15:57:37 -0800492 headerWriteBuf bytes.Buffer
493 hpackEncoder *hpack.Encoder
Tom Bergana8e8f922017-05-15 12:29:23 -0700494
495 // Used by startGracefulShutdown.
496 shutdownOnce sync.Once
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800497}
498
Brad Fitzpatrick29704b82015-10-10 18:01:18 -0700499func (sc *serverConn) maxHeaderListSize() uint32 {
500 n := sc.hs.MaxHeaderBytes
Brad Fitzpatrickd8f3c682015-10-12 20:56:49 +0000501 if n <= 0 {
Brad Fitzpatrick29704b82015-10-10 18:01:18 -0700502 n = http.DefaultMaxHeaderBytes
503 }
504 // http2's count is in a slightly different unit and includes 32 bytes per pair.
505 // So, take the net/http.Server value and pad it up a bit, assuming 10 headers.
506 const perFieldOverhead = 32 // per http2 spec
507 const typicalHeaders = 10 // conservative
508 return uint32(n + typicalHeaders*perFieldOverhead)
509}
510
Tom Bergan0c96df32016-12-05 22:33:37 -0800511func (sc *serverConn) curOpenStreams() uint32 {
512 sc.serveG.check()
513 return sc.curClientStreams + sc.curPushedStreams
514}
515
Gabriel Aszalos1aa5b312014-11-19 16:56:22 +0000516// stream represents a stream. This is the minimal metadata needed by
Brad Fitzpatrickbd391962014-11-17 18:58:58 -0800517// the serve goroutine. Most of the actual stream state is owned by
518// the http.Handler's goroutine in the responseWriter. Because the
519// responseWriter's responseWriterState is recycled at the end of a
520// handler, this struct intentionally has no pointer to the
521// *responseWriter{,State} itself, as the Handler ending nils out the
522// responseWriter's state field.
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800523type stream struct {
Brad Fitzpatrickbd391962014-11-17 18:58:58 -0800524 // immutable:
Brad Fitzpatrick8aacbec2016-05-18 19:54:31 +0000525 sc *serverConn
526 id uint32
527 body *pipe // non-nil if expecting DATA frames
528 cw closeWaiter // closed wait stream transitions to closed state
529 ctx contextContext
530 cancelCtx func()
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800531
Brad Fitzpatrickbd391962014-11-17 18:58:58 -0800532 // owned by serverConn's serve loop:
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +0000533 bodyBytes int64 // body bytes seen so far
534 declBodyBytes int64 // or -1 if undeclared
535 flow flow // limits writing from Handler to client
536 inflow flow // what the client is allowed to POST/etc to us
537 parent *stream // or nil
538 numTrailerValues int64
539 weight uint8
540 state streamState
Kale Blankenshipd1e1b352016-12-29 14:47:41 -0800541 resetQueued bool // RST_STREAM queued for write; set by sc.resetStream
542 gotTrailerHeader bool // HEADER frame for trailers was seen
543 wroteHeaders bool // whether we wrote headers (not status 100)
544 writeDeadline *time.Timer // nil if unused
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +0000545
546 trailer http.Header // accumulated trailers
547 reqTrailer http.Header // handler's Request.Trailer
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800548}
549
Brad Fitzpatrick23564bf2014-11-27 19:40:04 -0800550func (sc *serverConn) Framer() *Framer { return sc.framer }
551func (sc *serverConn) CloseConn() error { return sc.conn.Close() }
552func (sc *serverConn) Flush() error { return sc.bw.Flush() }
553func (sc *serverConn) HeaderEncoder() (*hpack.Encoder, *bytes.Buffer) {
554 return sc.hpackEncoder, &sc.headerWriteBuf
555}
556
Brad Fitzpatricka98415a2014-12-08 00:47:45 -0800557func (sc *serverConn) state(streamID uint32) (streamState, *stream) {
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800558 sc.serveG.check()
Tom Berganc46f2652016-10-25 10:13:20 -0700559 // http://tools.ietf.org/html/rfc7540#section-5.1
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800560 if st, ok := sc.streams[streamID]; ok {
Brad Fitzpatricka98415a2014-12-08 00:47:45 -0800561 return st.state, st
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800562 }
563 // "The first use of a new stream identifier implicitly closes all
564 // streams in the "idle" state that might have been initiated by
565 // that peer with a lower-valued stream identifier. For example, if
566 // a client sends a HEADERS frame on stream 7 without ever sending a
567 // frame on stream 5, then stream 5 transitions to the "closed"
568 // state when the first frame for stream 7 is sent or received."
Tom Bergan55a30842016-11-04 15:18:50 -0700569 if streamID%2 == 1 {
570 if streamID <= sc.maxClientStreamID {
571 return stateClosed, nil
572 }
573 } else {
574 if streamID <= sc.maxPushPromiseID {
575 return stateClosed, nil
576 }
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800577 }
Brad Fitzpatricka98415a2014-12-08 00:47:45 -0800578 return stateIdle, nil
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800579}
580
Brad Fitzpatrickcd8c2702015-10-15 20:01:14 +0000581// setConnState calls the net/http ConnState hook for this connection, if configured.
582// Note that the net/http package does StateNew and StateClosed for us.
583// There is currently no plan for StateHijacked or hijacking HTTP/2 connections.
584func (sc *serverConn) setConnState(state http.ConnState) {
585 if sc.hs.ConnState != nil {
586 sc.hs.ConnState(sc.conn, state)
587 }
588}
589
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800590func (sc *serverConn) vlogf(format string, args ...interface{}) {
591 if VerboseLogs {
592 sc.logf(format, args...)
593 }
594}
595
596func (sc *serverConn) logf(format string, args ...interface{}) {
597 if lg := sc.hs.ErrorLog; lg != nil {
598 lg.Printf(format, args...)
599 } else {
600 log.Printf(format, args...)
601 }
602}
603
Brad Fitzpatrickeb066e32016-01-26 18:31:02 +0000604// errno returns v's underlying uintptr, else 0.
605//
606// TODO: remove this helper function once http2 can use build
607// tags. See comment in isClosedConnError.
608func errno(v error) uintptr {
609 if rv := reflect.ValueOf(v); rv.Kind() == reflect.Uintptr {
610 return uintptr(rv.Uint())
611 }
612 return 0
613}
614
615// isClosedConnError reports whether err is an error from use of a closed
616// network connection.
617func isClosedConnError(err error) bool {
618 if err == nil {
619 return false
620 }
621
622 // TODO: remove this string search and be more like the Windows
623 // case below. That might involve modifying the standard library
624 // to return better error types.
625 str := err.Error()
626 if strings.Contains(str, "use of closed network connection") {
627 return true
628 }
629
630 // TODO(bradfitz): x/tools/cmd/bundle doesn't really support
631 // build tags, so I can't make an http2_windows.go file with
632 // Windows-specific stuff. Fix that and move this, once we
633 // have a way to bundle this into std's net/http somehow.
634 if runtime.GOOS == "windows" {
635 if oe, ok := err.(*net.OpError); ok && oe.Op == "read" {
636 if se, ok := oe.Err.(*os.SyscallError); ok && se.Syscall == "wsarecv" {
637 const WSAECONNABORTED = 10053
638 const WSAECONNRESET = 10054
639 if n := errno(se.Err); n == WSAECONNRESET || n == WSAECONNABORTED {
640 return true
641 }
642 }
643 }
644 }
645 return false
646}
647
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800648func (sc *serverConn) condlogf(err error, format string, args ...interface{}) {
649 if err == nil {
650 return
651 }
Brad Fitzpatrickeb066e32016-01-26 18:31:02 +0000652 if err == io.EOF || err == io.ErrUnexpectedEOF || isClosedConnError(err) {
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800653 // Boring, expected errors.
654 sc.vlogf(format, args...)
655 } else {
656 sc.logf(format, args...)
657 }
658}
659
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800660func (sc *serverConn) canonicalHeader(v string) string {
661 sc.serveG.check()
Brad Fitzpatrick6520e262014-11-15 09:36:47 -0800662 cv, ok := commonCanonHeader[v]
663 if ok {
664 return cv
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800665 }
Brad Fitzpatrick6520e262014-11-15 09:36:47 -0800666 cv, ok = sc.canonHeader[v]
667 if ok {
668 return cv
669 }
670 if sc.canonHeader == nil {
671 sc.canonHeader = make(map[string]string)
672 }
673 cv = http.CanonicalHeaderKey(v)
674 sc.canonHeader[v] = cv
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800675 return cv
676}
677
Brad Fitzpatrick271cfc12015-10-12 23:49:56 +0000678type readFrameResult struct {
679 f Frame // valid until readMore is called
680 err error
681
682 // readMore should be called once the consumer no longer needs or
683 // retains f. After readMore, f is invalid and more frames can be
684 // read.
685 readMore func()
686}
687
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800688// readFrames is the loop that reads incoming frames.
Brad Fitzpatrick271cfc12015-10-12 23:49:56 +0000689// It takes care to only read one frame at a time, blocking until the
690// consumer is done with the frame.
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800691// It's run on its own goroutine.
692func (sc *serverConn) readFrames() {
Brad Fitzpatrick271cfc12015-10-12 23:49:56 +0000693 gate := make(gate)
Brad Fitzpatrickc5617802016-03-22 01:45:52 +0000694 gateDone := gate.Done
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800695 for {
696 f, err := sc.framer.ReadFrame()
Brad Fitzpatrick271cfc12015-10-12 23:49:56 +0000697 select {
Brad Fitzpatrickc5617802016-03-22 01:45:52 +0000698 case sc.readFrameCh <- readFrameResult{f, err, gateDone}:
Brad Fitzpatrick271cfc12015-10-12 23:49:56 +0000699 case <-sc.doneServing:
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800700 return
701 }
Brad Fitzpatrick271cfc12015-10-12 23:49:56 +0000702 select {
703 case <-gate:
704 case <-sc.doneServing:
705 return
706 }
Brad Fitzpatrickea6dba82015-12-23 08:43:06 -0800707 if terminalReadFrameError(err) {
708 return
709 }
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800710 }
711}
712
Brad Fitzpatrick56401052015-10-20 22:27:39 +0000713// frameWriteResult is the message passed from writeFrameAsync to the serve goroutine.
714type frameWriteResult struct {
Tom Bergan4be9b972016-08-01 18:07:35 -0700715 wr FrameWriteRequest // what was written (or attempted)
716 err error // result of the writeFrame call
Brad Fitzpatrick56401052015-10-20 22:27:39 +0000717}
718
Brad Fitzpatrickaa524f62014-11-25 10:31:37 -0800719// writeFrameAsync runs in its own goroutine and writes a single frame
720// and then reports when it's done.
721// At most one goroutine can be running writeFrameAsync at a time per
722// serverConn.
Tom Bergan4be9b972016-08-01 18:07:35 -0700723func (sc *serverConn) writeFrameAsync(wr FrameWriteRequest) {
724 err := wr.write.writeFrame(sc)
725 sc.wroteFrameCh <- frameWriteResult{wr, err}
Brad Fitzpatrick520123b2014-11-14 15:57:37 -0800726}
727
Brad Fitzpatrick9b41faf2014-11-19 10:45:13 -0800728func (sc *serverConn) closeAllStreamsOnConnClose() {
Brad Fitzpatrick6d3aa4f2014-11-15 14:55:57 -0800729 sc.serveG.check()
Brad Fitzpatrickbd391962014-11-17 18:58:58 -0800730 for _, st := range sc.streams {
731 sc.closeStream(st, errClientDisconnected)
Brad Fitzpatrick6d3aa4f2014-11-15 14:55:57 -0800732 }
733}
734
Brad Fitzpatrick21896bb2014-11-19 16:05:21 -0800735func (sc *serverConn) stopShutdownTimer() {
736 sc.serveG.check()
737 if t := sc.shutdownTimer; t != nil {
738 t.Stop()
739 }
740}
741
Brad Fitzpatrick996adcb2014-12-08 01:08:19 -0800742func (sc *serverConn) notePanic() {
Brad Fitzpatrick74bd44b2015-12-15 00:47:28 +0000743 // Note: this is for serverConn.serve panicking, not http.Handler code.
Brad Fitzpatrickf3a6d9a2014-12-08 07:53:36 -0800744 if testHookOnPanicMu != nil {
745 testHookOnPanicMu.Lock()
746 defer testHookOnPanicMu.Unlock()
747 }
Brad Fitzpatrick996adcb2014-12-08 01:08:19 -0800748 if testHookOnPanic != nil {
749 if e := recover(); e != nil {
750 if testHookOnPanic(sc, e) {
751 panic(e)
752 }
753 }
754 }
755}
756
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800757func (sc *serverConn) serve() {
758 sc.serveG.check()
Brad Fitzpatrick996adcb2014-12-08 01:08:19 -0800759 defer sc.notePanic()
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800760 defer sc.conn.Close()
Brad Fitzpatrick9b41faf2014-11-19 10:45:13 -0800761 defer sc.closeAllStreamsOnConnClose()
Brad Fitzpatrick21896bb2014-11-19 16:05:21 -0800762 defer sc.stopShutdownTimer()
Brad Fitzpatrickaa524f62014-11-25 10:31:37 -0800763 defer close(sc.doneServing) // unblocks handlers trying to send
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800764
Brad Fitzpatrick415f1912015-12-16 20:28:38 +0000765 if VerboseLogs {
766 sc.vlogf("http2: server connection from %v on %p", sc.conn.RemoteAddr(), sc.hs)
767 }
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800768
Tom Bergan4be9b972016-08-01 18:07:35 -0700769 sc.writeFrame(FrameWriteRequest{
Brad Fitzpatrickf16a0b32014-11-28 13:49:30 -0800770 write: writeSettings{
Brad Fitzpatrick23564bf2014-11-27 19:40:04 -0800771 {SettingMaxFrameSize, sc.srv.maxReadFrameSize()},
772 {SettingMaxConcurrentStreams, sc.advMaxStreams},
Brad Fitzpatrick29704b82015-10-10 18:01:18 -0700773 {SettingMaxHeaderListSize, sc.maxHeaderListSize()},
Tom Bergan906cda92017-02-18 12:36:51 -0800774 {SettingInitialWindowSize, uint32(sc.srv.initialStreamRecvWindowSize())},
Brad Fitzpatrick23564bf2014-11-27 19:40:04 -0800775 },
776 })
Brad Fitzpatrick6a9b77b2014-12-03 13:56:36 -0800777 sc.unackedSettings++
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -0800778
Tom Bergan906cda92017-02-18 12:36:51 -0800779 // Each connection starts with intialWindowSize inflow tokens.
780 // If a higher value is configured, we add more tokens.
781 if diff := sc.srv.initialConnRecvWindowSize() - initialWindowSize; diff > 0 {
782 sc.sendWindowUpdate(nil, int(diff))
783 }
784
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -0800785 if err := sc.readPreface(); err != nil {
Brad Fitzpatrick415f1912015-12-16 20:28:38 +0000786 sc.condlogf(err, "http2: server: error reading preface from client %v: %v", sc.conn.RemoteAddr(), err)
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800787 return
788 }
Brad Fitzpatrickcd8c2702015-10-15 20:01:14 +0000789 // Now that we've got the preface, get us out of the
Dmitri Shuralyov357296a2016-11-07 15:02:51 -0800790 // "StateNew" state. We can't go directly to idle, though.
Brad Fitzpatrickcd8c2702015-10-15 20:01:14 +0000791 // Active means we read some data and anticipate a request. We'll
792 // do another Active when we get a HEADERS frame.
793 sc.setConnState(http.StateActive)
794 sc.setConnState(http.StateIdle)
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800795
Brad Fitzpatrickc33d3782016-10-22 11:37:19 -0700796 if sc.srv.IdleTimeout != 0 {
Brad Fitzpatrick34057062017-05-09 12:22:37 -0700797 sc.idleTimer = time.AfterFunc(sc.srv.IdleTimeout, sc.onIdleTimer)
Brad Fitzpatrickc33d3782016-10-22 11:37:19 -0700798 defer sc.idleTimer.Stop()
Brad Fitzpatrickc33d3782016-10-22 11:37:19 -0700799 }
800
Brad Fitzpatrickaa524f62014-11-25 10:31:37 -0800801 go sc.readFrames() // closed by defer sc.conn.Close above
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800802
Brad Fitzpatrick34057062017-05-09 12:22:37 -0700803 settingsTimer := time.AfterFunc(firstSettingsTimeout, sc.onSettingsTimer)
804 defer settingsTimer.Stop()
805
Brad Fitzpatrickc94bffa2015-10-13 18:18:12 +0000806 loopNum := 0
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800807 for {
Brad Fitzpatrickc94bffa2015-10-13 18:18:12 +0000808 loopNum++
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800809 select {
Tom Bergan4be9b972016-08-01 18:07:35 -0700810 case wr := <-sc.wantWriteFrameCh:
Kale Blankenshipd1e1b352016-12-29 14:47:41 -0800811 if se, ok := wr.write.(StreamError); ok {
812 sc.resetStream(se)
813 break
814 }
Tom Bergan4be9b972016-08-01 18:07:35 -0700815 sc.writeFrame(wr)
Brad Fitzpatrick56401052015-10-20 22:27:39 +0000816 case res := <-sc.wroteFrameCh:
817 sc.wroteFrame(res)
Brad Fitzpatrick271cfc12015-10-12 23:49:56 +0000818 case res := <-sc.readFrameCh:
819 if !sc.processFrameFromReader(res) {
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800820 return
821 }
Brad Fitzpatrick271cfc12015-10-12 23:49:56 +0000822 res.readMore()
Brad Fitzpatrick34057062017-05-09 12:22:37 -0700823 if settingsTimer != nil {
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -0800824 settingsTimer.Stop()
Brad Fitzpatrick34057062017-05-09 12:22:37 -0700825 settingsTimer = nil
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800826 }
Brad Fitzpatrickc8bab6a2014-12-07 18:51:56 -0800827 case m := <-sc.bodyReadCh:
828 sc.noteBodyRead(m.st, m.n)
Brad Fitzpatrick34057062017-05-09 12:22:37 -0700829 case msg := <-sc.serveMsgCh:
830 switch v := msg.(type) {
831 case func(int):
832 v(loopNum) // for testing
Tom Bergana8e8f922017-05-15 12:29:23 -0700833 case *serverMessage:
Brad Fitzpatrick34057062017-05-09 12:22:37 -0700834 switch v {
835 case settingsTimerMsg:
836 sc.logf("timeout waiting for SETTINGS frames from %v", sc.conn.RemoteAddr())
837 return
838 case idleTimerMsg:
839 sc.vlogf("connection is idle")
840 sc.goAway(ErrCodeNo)
841 case shutdownTimerMsg:
842 sc.vlogf("GOAWAY close timer fired; closing conn from %v", sc.conn.RemoteAddr())
843 return
Tom Bergana8e8f922017-05-15 12:29:23 -0700844 case gracefulShutdownMsg:
845 sc.startGracefulShutdownInternal()
Brad Fitzpatrick34057062017-05-09 12:22:37 -0700846 default:
847 panic("unknown timer")
848 }
849 case *startPushRequest:
850 sc.startPush(v)
851 default:
852 panic(fmt.Sprintf("unexpected type %T", v))
853 }
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800854 }
Brad Fitzpatrick73058b02016-10-30 16:20:31 +0000855
Tom Bergancd69bc32017-10-17 13:25:22 -0700856 // Start the shutdown timer after sending a GOAWAY. When sending GOAWAY
857 // with no error code (graceful shutdown), don't start the timer until
858 // all open streams have been completed.
859 sentGoAway := sc.inGoAway && !sc.needToSendGoAway && !sc.writingFrame
860 gracefulShutdownComplete := sc.goAwayCode == ErrCodeNo && sc.curOpenStreams() == 0
861 if sentGoAway && sc.shutdownTimer == nil && (sc.goAwayCode != ErrCodeNo || gracefulShutdownComplete) {
862 sc.shutDownIn(goAwayTimeout)
Brad Fitzpatrick73058b02016-10-30 16:20:31 +0000863 }
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800864 }
865}
866
Tom Bergan84f0e6f2017-05-12 14:27:43 -0700867func (sc *serverConn) awaitGracefulShutdown(sharedCh <-chan struct{}, privateCh chan struct{}) {
868 select {
869 case <-sc.doneServing:
870 case <-sharedCh:
871 close(privateCh)
872 }
873}
874
Tom Bergana8e8f922017-05-15 12:29:23 -0700875type serverMessage int
Brad Fitzpatrick34057062017-05-09 12:22:37 -0700876
Tom Bergana8e8f922017-05-15 12:29:23 -0700877// Message values sent to serveMsgCh.
Brad Fitzpatrick34057062017-05-09 12:22:37 -0700878var (
Tom Bergana8e8f922017-05-15 12:29:23 -0700879 settingsTimerMsg = new(serverMessage)
880 idleTimerMsg = new(serverMessage)
881 shutdownTimerMsg = new(serverMessage)
882 gracefulShutdownMsg = new(serverMessage)
Brad Fitzpatrick34057062017-05-09 12:22:37 -0700883)
884
885func (sc *serverConn) onSettingsTimer() { sc.sendServeMsg(settingsTimerMsg) }
886func (sc *serverConn) onIdleTimer() { sc.sendServeMsg(idleTimerMsg) }
887func (sc *serverConn) onShutdownTimer() { sc.sendServeMsg(shutdownTimerMsg) }
888
889func (sc *serverConn) sendServeMsg(msg interface{}) {
890 sc.serveG.checkNotOn() // NOT
891 select {
892 case sc.serveMsgCh <- msg:
893 case <-sc.doneServing:
894 }
895}
896
Brad Fitzpatrick95842032014-11-15 09:47:42 -0800897// readPreface reads the ClientPreface greeting from the peer
898// or returns an error on timeout or an invalid greeting.
899func (sc *serverConn) readPreface() error {
900 errc := make(chan error, 1)
901 go func() {
902 // Read the client preface
903 buf := make([]byte, len(ClientPreface))
Brad Fitzpatrick95842032014-11-15 09:47:42 -0800904 if _, err := io.ReadFull(sc.conn, buf); err != nil {
905 errc <- err
906 } else if !bytes.Equal(buf, clientPreface) {
907 errc <- fmt.Errorf("bogus greeting %q", buf)
908 } else {
909 errc <- nil
910 }
911 }()
Brad Fitzpatrick068d35d2014-12-09 07:10:31 +1100912 timer := time.NewTimer(prefaceTimeout) // TODO: configurable on *Server?
Brad Fitzpatrick95842032014-11-15 09:47:42 -0800913 defer timer.Stop()
914 select {
915 case <-timer.C:
916 return errors.New("timeout waiting for client preface")
917 case err := <-errc:
918 if err == nil {
Brad Fitzpatrick415f1912015-12-16 20:28:38 +0000919 if VerboseLogs {
920 sc.vlogf("http2: server: client %v said hello", sc.conn.RemoteAddr())
921 }
Brad Fitzpatrick95842032014-11-15 09:47:42 -0800922 }
923 return err
924 }
925}
926
Brad Fitzpatrickc94bffa2015-10-13 18:18:12 +0000927var errChanPool = sync.Pool{
928 New: func() interface{} { return make(chan error, 1) },
929}
930
Brad Fitzpatrickc95266f2015-10-29 12:35:12 -0700931var writeDataPool = sync.Pool{
932 New: func() interface{} { return new(writeData) },
933}
934
935// writeDataFromHandler writes DATA response frames from a handler on
936// the given stream.
937func (sc *serverConn) writeDataFromHandler(stream *stream, data []byte, endStream bool) error {
Brad Fitzpatrickc94bffa2015-10-13 18:18:12 +0000938 ch := errChanPool.Get().(chan error)
Brad Fitzpatrickc95266f2015-10-29 12:35:12 -0700939 writeArg := writeDataPool.Get().(*writeData)
940 *writeArg = writeData{stream.id, data, endStream}
Tom Bergan4be9b972016-08-01 18:07:35 -0700941 err := sc.writeFrameFromHandler(FrameWriteRequest{
Brad Fitzpatrickc95266f2015-10-29 12:35:12 -0700942 write: writeArg,
Brad Fitzpatrickf16a0b32014-11-28 13:49:30 -0800943 stream: stream,
944 done: ch,
Brad Fitzpatrickdc0c5c02014-11-20 14:15:26 -0800945 })
Brad Fitzpatrick56401052015-10-20 22:27:39 +0000946 if err != nil {
Brad Fitzpatrickdc0c5c02014-11-20 14:15:26 -0800947 return err
Brad Fitzpatrick56401052015-10-20 22:27:39 +0000948 }
Brad Fitzpatrickc95266f2015-10-29 12:35:12 -0700949 var frameWriteDone bool // the frame write is done (successfully or not)
Brad Fitzpatrick56401052015-10-20 22:27:39 +0000950 select {
951 case err = <-ch:
Brad Fitzpatrickc95266f2015-10-29 12:35:12 -0700952 frameWriteDone = true
Brad Fitzpatrickdc0c5c02014-11-20 14:15:26 -0800953 case <-sc.doneServing:
954 return errClientDisconnected
Brad Fitzpatrick2b459472014-11-30 19:18:57 -0800955 case <-stream.cw:
Brad Fitzpatrick56401052015-10-20 22:27:39 +0000956 // If both ch and stream.cw were ready (as might
957 // happen on the final Write after an http.Handler
958 // ends), prefer the write result. Otherwise this
959 // might just be us successfully closing the stream.
960 // The writeFrameAsync and serve goroutines guarantee
961 // that the ch send will happen before the stream.cw
962 // close.
963 select {
964 case err = <-ch:
Brad Fitzpatrickc95266f2015-10-29 12:35:12 -0700965 frameWriteDone = true
Brad Fitzpatrick56401052015-10-20 22:27:39 +0000966 default:
967 return errStreamClosed
968 }
Brad Fitzpatrickdc0c5c02014-11-20 14:15:26 -0800969 }
Brad Fitzpatrick56401052015-10-20 22:27:39 +0000970 errChanPool.Put(ch)
Brad Fitzpatrickc95266f2015-10-29 12:35:12 -0700971 if frameWriteDone {
972 writeDataPool.Put(writeArg)
973 }
Brad Fitzpatrick56401052015-10-20 22:27:39 +0000974 return err
Brad Fitzpatrickdc0c5c02014-11-20 14:15:26 -0800975}
976
Tom Bergan4be9b972016-08-01 18:07:35 -0700977// writeFrameFromHandler sends wr to sc.wantWriteFrameCh, but aborts
Brad Fitzpatrick4e3c9222014-11-22 17:35:09 -0800978// if the connection has gone away.
Brad Fitzpatrickdc0c5c02014-11-20 14:15:26 -0800979//
980// This must not be run from the serve goroutine itself, else it might
981// deadlock writing to sc.wantWriteFrameCh (which is only mildly
982// buffered and is read by serve itself). If you're on the serve
Brad Fitzpatrick4e3c9222014-11-22 17:35:09 -0800983// goroutine, call writeFrame instead.
Tom Bergan4be9b972016-08-01 18:07:35 -0700984func (sc *serverConn) writeFrameFromHandler(wr FrameWriteRequest) error {
Brad Fitzpatrick9b41faf2014-11-19 10:45:13 -0800985 sc.serveG.checkNotOn() // NOT
986 select {
Tom Bergan4be9b972016-08-01 18:07:35 -0700987 case sc.wantWriteFrameCh <- wr:
Brad Fitzpatrick56401052015-10-20 22:27:39 +0000988 return nil
Brad Fitzpatrick9b41faf2014-11-19 10:45:13 -0800989 case <-sc.doneServing:
Brad Fitzpatrick56401052015-10-20 22:27:39 +0000990 // Serve loop is gone.
Brad Fitzpatrick9b41faf2014-11-19 10:45:13 -0800991 // Client has closed their connection to the server.
Brad Fitzpatrick56401052015-10-20 22:27:39 +0000992 return errClientDisconnected
Brad Fitzpatrick9b41faf2014-11-19 10:45:13 -0800993 }
Brad Fitzpatricka29a3232014-11-15 11:18:25 -0800994}
995
Brad Fitzpatricka92fa952014-12-02 10:31:34 -0800996// writeFrame schedules a frame to write and sends it if there's nothing
997// already being written.
Brad Fitzpatrickdc0c5c02014-11-20 14:15:26 -0800998//
Brad Fitzpatricka92fa952014-12-02 10:31:34 -0800999// There is no pushback here (the serve goroutine never blocks). It's
1000// the http.Handlers that block, waiting for their previous frames to
1001// make it onto the wire
1002//
1003// If you're not on the serve goroutine, use writeFrameFromHandler instead.
Tom Bergan4be9b972016-08-01 18:07:35 -07001004func (sc *serverConn) writeFrame(wr FrameWriteRequest) {
Brad Fitzpatrick520123b2014-11-14 15:57:37 -08001005 sc.serveG.check()
Brad Fitzpatrick0c607072016-05-21 00:18:04 +00001006
Tom Bergan3d9a20a2016-12-08 17:01:56 -08001007 // If true, wr will not be written and wr.done will not be signaled.
Brad Fitzpatrick0c607072016-05-21 00:18:04 +00001008 var ignoreWrite bool
1009
Tom Bergan3d9a20a2016-12-08 17:01:56 -08001010 // We are not allowed to write frames on closed streams. RFC 7540 Section
1011 // 5.1.1 says: "An endpoint MUST NOT send frames other than PRIORITY on
1012 // a closed stream." Our server never sends PRIORITY, so that exception
1013 // does not apply.
1014 //
1015 // The serverConn might close an open stream while the stream's handler
1016 // is still running. For example, the server might close a stream when it
1017 // receives bad data from the client. If this happens, the handler might
1018 // attempt to write a frame after the stream has been closed (since the
1019 // handler hasn't yet been notified of the close). In this case, we simply
1020 // ignore the frame. The handler will notice that the stream is closed when
1021 // it waits for the frame to be written.
1022 //
1023 // As an exception to this rule, we allow sending RST_STREAM after close.
1024 // This allows us to immediately reject new streams without tracking any
1025 // state for those streams (except for the queued RST_STREAM frame). This
1026 // may result in duplicate RST_STREAMs in some cases, but the client should
1027 // ignore those.
1028 if wr.StreamID() != 0 {
1029 _, isReset := wr.write.(StreamError)
1030 if state, _ := sc.state(wr.StreamID()); state == stateClosed && !isReset {
1031 ignoreWrite = true
1032 }
1033 }
1034
Brad Fitzpatrick0c607072016-05-21 00:18:04 +00001035 // Don't send a 100-continue response if we've already sent headers.
1036 // See golang.org/issue/14030.
Tom Bergan4be9b972016-08-01 18:07:35 -07001037 switch wr.write.(type) {
Brad Fitzpatrick0c607072016-05-21 00:18:04 +00001038 case *writeResHeaders:
Tom Bergan4be9b972016-08-01 18:07:35 -07001039 wr.stream.wroteHeaders = true
Brad Fitzpatrick0c607072016-05-21 00:18:04 +00001040 case write100ContinueHeadersFrame:
Tom Bergan4be9b972016-08-01 18:07:35 -07001041 if wr.stream.wroteHeaders {
Tom Bergan3d9a20a2016-12-08 17:01:56 -08001042 // We do not need to notify wr.done because this frame is
1043 // never written with wr.done != nil.
1044 if wr.done != nil {
1045 panic("wr.done != nil for write100ContinueHeadersFrame")
1046 }
Brad Fitzpatrick0c607072016-05-21 00:18:04 +00001047 ignoreWrite = true
1048 }
1049 }
1050
1051 if !ignoreWrite {
Tom Bergan4be9b972016-08-01 18:07:35 -07001052 sc.writeSched.Push(wr)
Brad Fitzpatrick0c607072016-05-21 00:18:04 +00001053 }
Tatsuhiro Tsujikawacc1e1da2014-12-02 20:04:27 +09001054 sc.scheduleFrameWrite()
Brad Fitzpatrick520123b2014-11-14 15:57:37 -08001055}
1056
Tom Bergan4be9b972016-08-01 18:07:35 -07001057// startFrameWrite starts a goroutine to write wr (in a separate
Brad Fitzpatrick165c0982014-11-26 08:53:01 -08001058// goroutine since that might block on the network), and updates the
Tom Bergan4be9b972016-08-01 18:07:35 -07001059// serve goroutine's state about the world, updated from info in wr.
1060func (sc *serverConn) startFrameWrite(wr FrameWriteRequest) {
Brad Fitzpatrick3d7a3ad2014-11-15 21:38:23 -08001061 sc.serveG.check()
1062 if sc.writingFrame {
Brad Fitzpatrick165c0982014-11-26 08:53:01 -08001063 panic("internal error: can only be writing one frame at a time")
Brad Fitzpatrick3d7a3ad2014-11-15 21:38:23 -08001064 }
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08001065
Tom Bergan4be9b972016-08-01 18:07:35 -07001066 st := wr.stream
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08001067 if st != nil {
1068 switch st.state {
1069 case stateHalfClosedLocal:
Tom Bergan4909c4c2016-12-15 11:30:25 -08001070 switch wr.write.(type) {
1071 case StreamError, handlerPanicRST, writeWindowUpdate:
1072 // RFC 7540 Section 5.1 allows sending RST_STREAM, PRIORITY, and WINDOW_UPDATE
1073 // in this state. (We never send PRIORITY from the server, so that is not checked.)
1074 default:
1075 panic(fmt.Sprintf("internal error: attempt to send frame on a half-closed-local stream: %v", wr))
1076 }
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08001077 case stateClosed:
Brad Fitzpatrick45e77172016-12-15 19:42:18 +00001078 panic(fmt.Sprintf("internal error: attempt to send frame on a closed stream: %v", wr))
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08001079 }
1080 }
Tom Berganc46f2652016-10-25 10:13:20 -07001081 if wpp, ok := wr.write.(*writePushPromise); ok {
1082 var err error
1083 wpp.promisedID, err = wpp.allocatePromisedID()
1084 if err != nil {
Brad Fitzpatrickb626cca2016-10-27 01:46:15 +00001085 sc.writingFrameAsync = false
Tom Bergan3d9a20a2016-12-08 17:01:56 -08001086 wr.replyToWriter(err)
Tom Berganc46f2652016-10-25 10:13:20 -07001087 return
1088 }
1089 }
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08001090
Brad Fitzpatrick56401052015-10-20 22:27:39 +00001091 sc.writingFrame = true
Brad Fitzpatrick5e4e2dc2014-11-19 16:49:43 -08001092 sc.needsFrameFlush = true
Brad Fitzpatricke7b14352016-10-19 19:12:55 +00001093 if wr.write.staysWithinBuffer(sc.bw.Available()) {
Brad Fitzpatrickb626cca2016-10-27 01:46:15 +00001094 sc.writingFrameAsync = false
Brad Fitzpatricke7b14352016-10-19 19:12:55 +00001095 err := wr.write.writeFrame(sc)
1096 sc.wroteFrame(frameWriteResult{wr, err})
1097 } else {
Brad Fitzpatrickb626cca2016-10-27 01:46:15 +00001098 sc.writingFrameAsync = true
Brad Fitzpatricke7b14352016-10-19 19:12:55 +00001099 go sc.writeFrameAsync(wr)
1100 }
Brad Fitzpatrick56401052015-10-20 22:27:39 +00001101}
1102
Brad Fitzpatrick74bd44b2015-12-15 00:47:28 +00001103// errHandlerPanicked is the error given to any callers blocked in a read from
1104// Request.Body when the main goroutine panics. Since most handlers read in the
1105// the main ServeHTTP goroutine, this will show up rarely.
1106var errHandlerPanicked = errors.New("http2: handler panicked")
1107
Brad Fitzpatrick56401052015-10-20 22:27:39 +00001108// wroteFrame is called on the serve goroutine with the result of
1109// whatever happened on writeFrameAsync.
1110func (sc *serverConn) wroteFrame(res frameWriteResult) {
1111 sc.serveG.check()
1112 if !sc.writingFrame {
1113 panic("internal error: expected to be already writing a frame")
1114 }
1115 sc.writingFrame = false
Brad Fitzpatrickb626cca2016-10-27 01:46:15 +00001116 sc.writingFrameAsync = false
Brad Fitzpatrick56401052015-10-20 22:27:39 +00001117
Tom Bergan4be9b972016-08-01 18:07:35 -07001118 wr := res.wr
Brad Fitzpatrick56401052015-10-20 22:27:39 +00001119
Tom Bergan3d9a20a2016-12-08 17:01:56 -08001120 if writeEndsStream(wr.write) {
1121 st := wr.stream
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08001122 if st == nil {
Brad Fitzpatrickf16a0b32014-11-28 13:49:30 -08001123 panic("internal error: expecting non-nil stream")
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08001124 }
1125 switch st.state {
1126 case stateOpen:
Brad Fitzpatrickf3a6d9a2014-12-08 07:53:36 -08001127 // Here we would go to stateHalfClosedLocal in
1128 // theory, but since our handler is done and
1129 // the net/http package provides no mechanism
Brad Fitzpatrick3bafa332016-10-19 14:40:54 +00001130 // for closing a ResponseWriter while still
1131 // reading data (see possible TODO at top of
1132 // this file), we go into closed state here
1133 // anyway, after telling the peer we're
Tom Bergan3d9a20a2016-12-08 17:01:56 -08001134 // hanging up on them. We'll transition to
1135 // stateClosed after the RST_STREAM frame is
1136 // written.
1137 st.state = stateHalfClosedLocal
Tom Bergan5602c732017-04-13 10:15:43 -07001138 // Section 8.1: a server MAY request that the client abort
1139 // transmission of a request without error by sending a
1140 // RST_STREAM with an error code of NO_ERROR after sending
1141 // a complete response.
1142 sc.resetStream(streamError(st.id, ErrCodeNo))
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08001143 case stateHalfClosedRemote:
Brad Fitzpatrickb7f5d982015-10-26 13:59:20 -05001144 sc.closeStream(st, errHandlerComplete)
Brad Fitzpatrick3d7a3ad2014-11-15 21:38:23 -08001145 }
Tom Bergan3d9a20a2016-12-08 17:01:56 -08001146 } else {
1147 switch v := wr.write.(type) {
1148 case StreamError:
1149 // st may be unknown if the RST_STREAM was generated to reject bad input.
1150 if st, ok := sc.streams[v.StreamID]; ok {
1151 sc.closeStream(st, v)
1152 }
1153 case handlerPanicRST:
1154 sc.closeStream(wr.stream, errHandlerPanicked)
1155 }
Brad Fitzpatrick3d7a3ad2014-11-15 21:38:23 -08001156 }
Brad Fitzpatrick56401052015-10-20 22:27:39 +00001157
Tom Bergan3d9a20a2016-12-08 17:01:56 -08001158 // Reply (if requested) to unblock the ServeHTTP goroutine.
1159 wr.replyToWriter(res.err)
1160
Brad Fitzpatrick56401052015-10-20 22:27:39 +00001161 sc.scheduleFrameWrite()
Brad Fitzpatrick3d7a3ad2014-11-15 21:38:23 -08001162}
1163
Brad Fitzpatrick4e3c9222014-11-22 17:35:09 -08001164// scheduleFrameWrite tickles the frame writing scheduler.
1165//
1166// If a frame is already being written, nothing happens. This will be called again
1167// when the frame is done being written.
1168//
1169// If a frame isn't being written we need to send one, the best frame
1170// to send is selected, preferring first things that aren't
1171// stream-specific (e.g. ACKing settings), and then finding the
1172// highest priority stream.
1173//
1174// If a frame isn't being written and there's nothing else to send, we
1175// flush the write buffer.
Brad Fitzpatrick520123b2014-11-14 15:57:37 -08001176func (sc *serverConn) scheduleFrameWrite() {
1177 sc.serveG.check()
Brad Fitzpatrickb626cca2016-10-27 01:46:15 +00001178 if sc.writingFrame || sc.inFrameScheduleLoop {
Brad Fitzpatrick21896bb2014-11-19 16:05:21 -08001179 return
1180 }
Brad Fitzpatrickb626cca2016-10-27 01:46:15 +00001181 sc.inFrameScheduleLoop = true
1182 for !sc.writingFrameAsync {
1183 if sc.needToSendGoAway {
1184 sc.needToSendGoAway = false
1185 sc.startFrameWrite(FrameWriteRequest{
1186 write: &writeGoAway{
Tom Bergan55a30842016-11-04 15:18:50 -07001187 maxStreamID: sc.maxClientStreamID,
Brad Fitzpatrickb626cca2016-10-27 01:46:15 +00001188 code: sc.goAwayCode,
1189 },
1190 })
1191 continue
Brad Fitzpatrick2b459472014-11-30 19:18:57 -08001192 }
Brad Fitzpatrickb626cca2016-10-27 01:46:15 +00001193 if sc.needToSendSettingsAck {
1194 sc.needToSendSettingsAck = false
1195 sc.startFrameWrite(FrameWriteRequest{write: writeSettingsAck{}})
1196 continue
1197 }
Brad Fitzpatrick73058b02016-10-30 16:20:31 +00001198 if !sc.inGoAway || sc.goAwayCode == ErrCodeNo {
Brad Fitzpatrickb626cca2016-10-27 01:46:15 +00001199 if wr, ok := sc.writeSched.Pop(); ok {
1200 sc.startFrameWrite(wr)
1201 continue
1202 }
1203 }
1204 if sc.needsFrameFlush {
1205 sc.startFrameWrite(FrameWriteRequest{write: flushFrameWriter{}})
1206 sc.needsFrameFlush = false // after startFrameWrite, since it sets this true
1207 continue
1208 }
1209 break
Brad Fitzpatrick2b459472014-11-30 19:18:57 -08001210 }
Brad Fitzpatrickb626cca2016-10-27 01:46:15 +00001211 sc.inFrameScheduleLoop = false
Brad Fitzpatrick520123b2014-11-14 15:57:37 -08001212}
1213
Tom Bergana8e8f922017-05-15 12:29:23 -07001214// startGracefulShutdown gracefully shuts down a connection. This
1215// sends GOAWAY with ErrCodeNo to tell the client we're gracefully
1216// shutting down. The connection isn't closed until all current
1217// streams are done.
1218//
1219// startGracefulShutdown returns immediately; it does not wait until
1220// the connection has shut down.
Brad Fitzpatrick6dfeb342016-11-11 23:53:59 +00001221func (sc *serverConn) startGracefulShutdown() {
Tom Bergana8e8f922017-05-15 12:29:23 -07001222 sc.serveG.checkNotOn() // NOT
1223 sc.shutdownOnce.Do(func() { sc.sendServeMsg(gracefulShutdownMsg) })
1224}
1225
Tom Bergancd69bc32017-10-17 13:25:22 -07001226// After sending GOAWAY, the connection will close after goAwayTimeout.
1227// If we close the connection immediately after sending GOAWAY, there may
1228// be unsent data in our kernel receive buffer, which will cause the kernel
1229// to send a TCP RST on close() instead of a FIN. This RST will abort the
1230// connection immediately, whether or not the client had received the GOAWAY.
1231//
1232// Ideally we should delay for at least 1 RTT + epsilon so the client has
1233// a chance to read the GOAWAY and stop sending messages. Measuring RTT
1234// is hard, so we approximate with 1 second. See golang.org/issue/18701.
1235//
1236// This is a var so it can be shorter in tests, where all requests uses the
1237// loopback interface making the expected RTT very small.
1238//
1239// TODO: configurable?
1240var goAwayTimeout = 1 * time.Second
1241
Tom Bergana8e8f922017-05-15 12:29:23 -07001242func (sc *serverConn) startGracefulShutdownInternal() {
Tom Bergancd69bc32017-10-17 13:25:22 -07001243 sc.goAway(ErrCodeNo)
Brad Fitzpatrick6dfeb342016-11-11 23:53:59 +00001244}
1245
Brad Fitzpatrick55815ec2014-11-15 13:29:57 -08001246func (sc *serverConn) goAway(code ErrCode) {
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001247 sc.serveG.check()
Brad Fitzpatrick21896bb2014-11-19 16:05:21 -08001248 if sc.inGoAway {
Brad Fitzpatrick55815ec2014-11-15 13:29:57 -08001249 return
1250 }
Brad Fitzpatrick21896bb2014-11-19 16:05:21 -08001251 sc.inGoAway = true
1252 sc.needToSendGoAway = true
1253 sc.goAwayCode = code
1254 sc.scheduleFrameWrite()
1255}
1256
1257func (sc *serverConn) shutDownIn(d time.Duration) {
1258 sc.serveG.check()
Brad Fitzpatrick34057062017-05-09 12:22:37 -07001259 sc.shutdownTimer = time.AfterFunc(d, sc.onShutdownTimer)
Brad Fitzpatrick55815ec2014-11-15 13:29:57 -08001260}
1261
Brad Fitzpatrick6ec17312014-11-23 10:07:07 -08001262func (sc *serverConn) resetStream(se StreamError) {
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001263 sc.serveG.check()
Tom Bergan4be9b972016-08-01 18:07:35 -07001264 sc.writeFrame(FrameWriteRequest{write: se})
Brad Fitzpatrickf3a6d9a2014-12-08 07:53:36 -08001265 if st, ok := sc.streams[se.StreamID]; ok {
Tom Bergan3d9a20a2016-12-08 17:01:56 -08001266 st.resetQueued = true
Brad Fitzpatrickf3a6d9a2014-12-08 07:53:36 -08001267 }
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001268}
1269
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -08001270// processFrameFromReader processes the serve loop's read from readFrameCh from the
1271// frame-reading goroutine.
1272// processFrameFromReader returns whether the connection should be kept open.
Brad Fitzpatrick271cfc12015-10-12 23:49:56 +00001273func (sc *serverConn) processFrameFromReader(res readFrameResult) bool {
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -08001274 sc.serveG.check()
Brad Fitzpatrick271cfc12015-10-12 23:49:56 +00001275 err := res.err
1276 if err != nil {
Brad Fitzpatrick21896bb2014-11-19 16:05:21 -08001277 if err == ErrFrameTooLarge {
1278 sc.goAway(ErrCodeFrameSize)
1279 return true // goAway will close the loop
1280 }
Brad Fitzpatrickeb066e32016-01-26 18:31:02 +00001281 clientGone := err == io.EOF || err == io.ErrUnexpectedEOF || isClosedConnError(err)
Brad Fitzpatrick8ec321e2014-11-25 14:08:16 -08001282 if clientGone {
1283 // TODO: could we also get into this state if
1284 // the peer does a half close
1285 // (e.g. CloseWrite) because they're done
1286 // sending frames but they're still wanting
1287 // our open replies? Investigate.
Brad Fitzpatrickb2ca8da2014-12-08 00:41:28 -08001288 // TODO: add CloseWrite to crypto/tls.Conn first
1289 // so we have a way to test this? I suppose
1290 // just for testing we could have a non-TLS mode.
Brad Fitzpatrick8ec321e2014-11-25 14:08:16 -08001291 return false
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -08001292 }
Brad Fitzpatrick271cfc12015-10-12 23:49:56 +00001293 } else {
1294 f := res.f
Brad Fitzpatrick415f1912015-12-16 20:28:38 +00001295 if VerboseLogs {
1296 sc.vlogf("http2: server read frame %v", summarizeFrame(f))
1297 }
Brad Fitzpatrick8ec321e2014-11-25 14:08:16 -08001298 err = sc.processFrame(f)
Brad Fitzpatrick8ec321e2014-11-25 14:08:16 -08001299 if err == nil {
1300 return true
1301 }
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -08001302 }
1303
1304 switch ev := err.(type) {
1305 case StreamError:
Brad Fitzpatrick6ec17312014-11-23 10:07:07 -08001306 sc.resetStream(ev)
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -08001307 return true
1308 case goAwayFlowError:
Brad Fitzpatrick55815ec2014-11-15 13:29:57 -08001309 sc.goAway(ErrCodeFlowControl)
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -08001310 return true
1311 case ConnectionError:
Brad Fitzpatrick415f1912015-12-16 20:28:38 +00001312 sc.logf("http2: server connection error from %v: %v", sc.conn.RemoteAddr(), ev)
Brad Fitzpatrick21896bb2014-11-19 16:05:21 -08001313 sc.goAway(ErrCode(ev))
1314 return true // goAway will handle shutdown
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -08001315 default:
Brad Fitzpatrick271cfc12015-10-12 23:49:56 +00001316 if res.err != nil {
Brad Fitzpatrickeb066e32016-01-26 18:31:02 +00001317 sc.vlogf("http2: server closing client connection; error reading frame from client %s: %v", sc.conn.RemoteAddr(), err)
Brad Fitzpatrick8ec321e2014-11-25 14:08:16 -08001318 } else {
Brad Fitzpatrick415f1912015-12-16 20:28:38 +00001319 sc.logf("http2: server closing client connection: %v", err)
Brad Fitzpatrick8ec321e2014-11-25 14:08:16 -08001320 }
Brad Fitzpatrick271cfc12015-10-12 23:49:56 +00001321 return false
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -08001322 }
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -08001323}
1324
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001325func (sc *serverConn) processFrame(f Frame) error {
1326 sc.serveG.check()
1327
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -08001328 // First frame received must be SETTINGS.
1329 if !sc.sawFirstSettings {
1330 if _, ok := f.(*SettingsFrame); !ok {
1331 return ConnectionError(ErrCodeProtocol)
1332 }
1333 sc.sawFirstSettings = true
1334 }
1335
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001336 switch f := f.(type) {
1337 case *SettingsFrame:
1338 return sc.processSettings(f)
Brad Fitzpatrick9e1fb3c2016-02-20 14:24:27 +05301339 case *MetaHeadersFrame:
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001340 return sc.processHeaders(f)
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001341 case *WindowUpdateFrame:
1342 return sc.processWindowUpdate(f)
1343 case *PingFrame:
1344 return sc.processPing(f)
1345 case *DataFrame:
1346 return sc.processData(f)
Brad Fitzpatrick6d3aa4f2014-11-15 14:55:57 -08001347 case *RSTStreamFrame:
1348 return sc.processResetStream(f)
Brad Fitzpatrick2ee3a492014-11-30 23:18:32 -08001349 case *PriorityFrame:
1350 return sc.processPriority(f)
Tom Bergan87635b22016-11-07 17:51:22 -08001351 case *GoAwayFrame:
1352 return sc.processGoAway(f)
Daniel Morsing9f251692014-12-05 18:17:30 +00001353 case *PushPromiseFrame:
1354 // A client cannot push. Thus, servers MUST treat the receipt of a PUSH_PROMISE
1355 // frame as a connection error (Section 5.4.1) of type PROTOCOL_ERROR.
1356 return ConnectionError(ErrCodeProtocol)
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001357 default:
Brad Fitzpatrick415f1912015-12-16 20:28:38 +00001358 sc.vlogf("http2: server ignoring frame: %v", f.Header())
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001359 return nil
1360 }
1361}
1362
1363func (sc *serverConn) processPing(f *PingFrame) error {
1364 sc.serveG.check()
Brad Fitzpatricka179abb2015-11-07 16:46:24 +01001365 if f.IsAck() {
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001366 // 6.7 PING: " An endpoint MUST NOT respond to PING frames
1367 // containing this flag."
1368 return nil
1369 }
1370 if f.StreamID != 0 {
1371 // "PING frames are not associated with any individual
1372 // stream. If a PING frame is received with a stream
1373 // identifier field value other than 0x0, the recipient MUST
1374 // respond with a connection error (Section 5.4.1) of type
1375 // PROTOCOL_ERROR."
1376 return ConnectionError(ErrCodeProtocol)
1377 }
Brad Fitzpatrick569280f2016-11-03 00:14:07 +00001378 if sc.inGoAway && sc.goAwayCode != ErrCodeNo {
Brad Fitzpatrickc33d3782016-10-22 11:37:19 -07001379 return nil
1380 }
Tom Bergan4be9b972016-08-01 18:07:35 -07001381 sc.writeFrame(FrameWriteRequest{write: writePingAck{f}})
Brad Fitzpatrick9e0eccc2014-11-15 09:14:49 -08001382 return nil
1383}
1384
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001385func (sc *serverConn) processWindowUpdate(f *WindowUpdateFrame) error {
1386 sc.serveG.check()
1387 switch {
1388 case f.StreamID != 0: // stream-level flow control
Brad Fitzpatrick41c5c5c2016-10-21 05:57:00 -07001389 state, st := sc.state(f.StreamID)
1390 if state == stateIdle {
1391 // Section 5.1: "Receiving any frame other than HEADERS
1392 // or PRIORITY on a stream in this state MUST be
1393 // treated as a connection error (Section 5.4.1) of
1394 // type PROTOCOL_ERROR."
1395 return ConnectionError(ErrCodeProtocol)
1396 }
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001397 if st == nil {
1398 // "WINDOW_UPDATE can be sent by a peer that has sent a
1399 // frame bearing the END_STREAM flag. This means that a
1400 // receiver could receive a WINDOW_UPDATE frame on a "half
1401 // closed (remote)" or "closed" stream. A receiver MUST
1402 // NOT treat this as an error, see Section 5.1."
1403 return nil
1404 }
1405 if !st.flow.add(int32(f.Increment)) {
Brad Fitzpatricke2ba55e2016-08-02 15:44:32 +00001406 return streamError(f.StreamID, ErrCodeFlowControl)
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001407 }
1408 default: // connection-level flow control
1409 if !sc.flow.add(int32(f.Increment)) {
1410 return goAwayFlowError{}
1411 }
1412 }
Brad Fitzpatrick2b459472014-11-30 19:18:57 -08001413 sc.scheduleFrameWrite()
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001414 return nil
1415}
1416
Brad Fitzpatrick6d3aa4f2014-11-15 14:55:57 -08001417func (sc *serverConn) processResetStream(f *RSTStreamFrame) error {
1418 sc.serveG.check()
Brad Fitzpatricka98415a2014-12-08 00:47:45 -08001419
1420 state, st := sc.state(f.StreamID)
1421 if state == stateIdle {
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08001422 // 6.4 "RST_STREAM frames MUST NOT be sent for a
1423 // stream in the "idle" state. If a RST_STREAM frame
1424 // identifying an idle stream is received, the
1425 // recipient MUST treat this as a connection error
1426 // (Section 5.4.1) of type PROTOCOL_ERROR.
1427 return ConnectionError(ErrCodeProtocol)
1428 }
Brad Fitzpatricka98415a2014-12-08 00:47:45 -08001429 if st != nil {
Brad Fitzpatrick8aacbec2016-05-18 19:54:31 +00001430 st.cancelCtx()
Brad Fitzpatricke2ba55e2016-08-02 15:44:32 +00001431 sc.closeStream(st, streamError(f.StreamID, f.ErrCode))
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08001432 }
Brad Fitzpatrick6d3aa4f2014-11-15 14:55:57 -08001433 return nil
1434}
1435
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08001436func (sc *serverConn) closeStream(st *stream, err error) {
Brad Fitzpatrick6d3aa4f2014-11-15 14:55:57 -08001437 sc.serveG.check()
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08001438 if st.state == stateIdle || st.state == stateClosed {
Brad Fitzpatrickf3a6d9a2014-12-08 07:53:36 -08001439 panic(fmt.Sprintf("invariant; can't close stream in state %v", st.state))
Brad Fitzpatrick6d3aa4f2014-11-15 14:55:57 -08001440 }
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08001441 st.state = stateClosed
Kale Blankenshipd1e1b352016-12-29 14:47:41 -08001442 if st.writeDeadline != nil {
1443 st.writeDeadline.Stop()
1444 }
Tom Berganc46f2652016-10-25 10:13:20 -07001445 if st.isPushed() {
1446 sc.curPushedStreams--
1447 } else {
1448 sc.curClientStreams--
1449 }
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08001450 delete(sc.streams, st.id)
Brad Fitzpatrick6dfeb342016-11-11 23:53:59 +00001451 if len(sc.streams) == 0 {
1452 sc.setConnState(http.StateIdle)
1453 if sc.srv.IdleTimeout != 0 {
1454 sc.idleTimer.Reset(sc.srv.IdleTimeout)
1455 }
1456 if h1ServerKeepAlivesDisabled(sc.hs) {
Tom Bergana8e8f922017-05-15 12:29:23 -07001457 sc.startGracefulShutdownInternal()
Brad Fitzpatrick6dfeb342016-11-11 23:53:59 +00001458 }
Brad Fitzpatrickc33d3782016-10-22 11:37:19 -07001459 }
Brad Fitzpatrick6d3aa4f2014-11-15 14:55:57 -08001460 if p := st.body; p != nil {
Brad Fitzpatrick6a513af2016-07-26 10:19:14 +02001461 // Return any buffered unread bytes worth of conn-level flow control.
1462 // See golang.org/issue/16481
1463 sc.sendWindowUpdate(nil, p.Len())
1464
Brad Fitzpatrickb7f5d982015-10-26 13:59:20 -05001465 p.CloseWithError(err)
Brad Fitzpatrick6d3aa4f2014-11-15 14:55:57 -08001466 }
Brad Fitzpatrick2b459472014-11-30 19:18:57 -08001467 st.cw.Close() // signals Handler's CloseNotifier, unblocks writes, etc
Tom Bergan4be9b972016-08-01 18:07:35 -07001468 sc.writeSched.CloseStream(st.id)
Brad Fitzpatrick6d3aa4f2014-11-15 14:55:57 -08001469}
1470
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001471func (sc *serverConn) processSettings(f *SettingsFrame) error {
1472 sc.serveG.check()
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -08001473 if f.IsAck() {
Brad Fitzpatrick6a9b77b2014-12-03 13:56:36 -08001474 sc.unackedSettings--
1475 if sc.unackedSettings < 0 {
1476 // Why is the peer ACKing settings we never sent?
1477 // The spec doesn't mention this case, but
1478 // hang up on them anyway.
1479 return ConnectionError(ErrCodeProtocol)
1480 }
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -08001481 return nil
1482 }
1483 if err := f.ForeachSetting(sc.processSetting); err != nil {
1484 return err
1485 }
Brad Fitzpatrick4e3c9222014-11-22 17:35:09 -08001486 sc.needToSendSettingsAck = true
1487 sc.scheduleFrameWrite()
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -08001488 return nil
1489}
1490
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001491func (sc *serverConn) processSetting(s Setting) error {
1492 sc.serveG.check()
Brad Fitzpatrickbc00c572014-11-17 12:28:01 -08001493 if err := s.Valid(); err != nil {
1494 return err
1495 }
Brad Fitzpatrick415f1912015-12-16 20:28:38 +00001496 if VerboseLogs {
1497 sc.vlogf("http2: server processing setting %v", s)
1498 }
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001499 switch s.ID {
Brad Fitzpatrickbc00c572014-11-17 12:28:01 -08001500 case SettingHeaderTableSize:
1501 sc.headerTableSize = s.Val
Tatsuhiro Tsujikawac7d67a52014-11-20 01:01:39 +09001502 sc.hpackEncoder.SetMaxDynamicTableSize(s.Val)
Brad Fitzpatrickbc00c572014-11-17 12:28:01 -08001503 case SettingEnablePush:
1504 sc.pushEnabled = s.Val != 0
Brad Fitzpatrickbc00c572014-11-17 12:28:01 -08001505 case SettingMaxConcurrentStreams:
Brad Fitzpatrick6ec17312014-11-23 10:07:07 -08001506 sc.clientMaxStreams = s.Val
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001507 case SettingInitialWindowSize:
1508 return sc.processSettingInitialWindowSize(s.Val)
Brad Fitzpatrickbc00c572014-11-17 12:28:01 -08001509 case SettingMaxFrameSize:
Tom Bergan4be9b972016-08-01 18:07:35 -07001510 sc.maxFrameSize = int32(s.Val) // the maximum valid s.Val is < 2^31
Brad Fitzpatrickbc00c572014-11-17 12:28:01 -08001511 case SettingMaxHeaderListSize:
Brad Fitzpatrick29704b82015-10-10 18:01:18 -07001512 sc.peerMaxHeaderListSize = s.Val
gbbr0b3b5742014-11-23 00:44:48 +00001513 default:
1514 // Unknown setting: "An endpoint that receives a SETTINGS
1515 // frame with any unknown or unsupported identifier MUST
1516 // ignore that setting."
Brad Fitzpatrick415f1912015-12-16 20:28:38 +00001517 if VerboseLogs {
1518 sc.vlogf("http2: server ignoring unknown setting %v", s)
1519 }
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001520 }
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001521 return nil
1522}
1523
1524func (sc *serverConn) processSettingInitialWindowSize(val uint32) error {
1525 sc.serveG.check()
Brad Fitzpatrickbc00c572014-11-17 12:28:01 -08001526 // Note: val already validated to be within range by
1527 // processSetting's Valid call.
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001528
1529 // "A SETTINGS frame can alter the initial flow control window
1530 // size for all current streams. When the value of
1531 // SETTINGS_INITIAL_WINDOW_SIZE changes, a receiver MUST
1532 // adjust the size of all stream flow control windows that it
1533 // maintains by the difference between the new value and the
1534 // old value."
Tom Bergan906cda92017-02-18 12:36:51 -08001535 old := sc.initialStreamSendWindowSize
1536 sc.initialStreamSendWindowSize = int32(val)
1537 growth := int32(val) - old // may be negative
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001538 for _, st := range sc.streams {
1539 if !st.flow.add(growth) {
1540 // 6.9.2 Initial Flow Control Window Size
1541 // "An endpoint MUST treat a change to
1542 // SETTINGS_INITIAL_WINDOW_SIZE that causes any flow
1543 // control window to exceed the maximum size as a
1544 // connection error (Section 5.4.1) of type
1545 // FLOW_CONTROL_ERROR."
1546 return ConnectionError(ErrCodeFlowControl)
1547 }
1548 }
1549 return nil
1550}
1551
1552func (sc *serverConn) processData(f *DataFrame) error {
1553 sc.serveG.check()
Brad Fitzpatrick569280f2016-11-03 00:14:07 +00001554 if sc.inGoAway && sc.goAwayCode != ErrCodeNo {
Brad Fitzpatrickc33d3782016-10-22 11:37:19 -07001555 return nil
1556 }
Brad Fitzpatrick6a513af2016-07-26 10:19:14 +02001557 data := f.Data()
1558
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001559 // "If a DATA frame is received whose stream is not in "open"
1560 // or "half closed (local)" state, the recipient MUST respond
1561 // with a stream error (Section 5.4.2) of type STREAM_CLOSED."
1562 id := f.Header().StreamID
Brad Fitzpatrick41c5c5c2016-10-21 05:57:00 -07001563 state, st := sc.state(id)
1564 if id == 0 || state == stateIdle {
1565 // Section 5.1: "Receiving any frame other than HEADERS
1566 // or PRIORITY on a stream in this state MUST be
1567 // treated as a connection error (Section 5.4.1) of
1568 // type PROTOCOL_ERROR."
1569 return ConnectionError(ErrCodeProtocol)
1570 }
Tom Bergan3d9a20a2016-12-08 17:01:56 -08001571 if st == nil || state != stateOpen || st.gotTrailerHeader || st.resetQueued {
Brad Fitzpatrickf3a6d9a2014-12-08 07:53:36 -08001572 // This includes sending a RST_STREAM if the stream is
1573 // in stateHalfClosedLocal (which currently means that
1574 // the http.Handler returned, so it's done reading &
1575 // done writing). Try to stop the client from sending
1576 // more DATA.
Brad Fitzpatrick6a513af2016-07-26 10:19:14 +02001577
1578 // But still enforce their connection-level flow control,
1579 // and return any flow control bytes since we're not going
1580 // to consume them.
Brad Fitzpatrick35028a42016-07-31 15:09:09 -07001581 if sc.inflow.available() < int32(f.Length) {
Brad Fitzpatricke2ba55e2016-08-02 15:44:32 +00001582 return streamError(id, ErrCodeFlowControl)
Brad Fitzpatrick6a513af2016-07-26 10:19:14 +02001583 }
1584 // Deduct the flow control from inflow, since we're
1585 // going to immediately add it back in
1586 // sendWindowUpdate, which also schedules sending the
1587 // frames.
Brad Fitzpatrick35028a42016-07-31 15:09:09 -07001588 sc.inflow.take(int32(f.Length))
1589 sc.sendWindowUpdate(nil, int(f.Length)) // conn-level
Brad Fitzpatrick6a513af2016-07-26 10:19:14 +02001590
Tom Bergan3d9a20a2016-12-08 17:01:56 -08001591 if st != nil && st.resetQueued {
1592 // Already have a stream error in flight. Don't send another.
1593 return nil
1594 }
Brad Fitzpatricke2ba55e2016-08-02 15:44:32 +00001595 return streamError(id, ErrCodeStreamClosed)
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001596 }
1597 if st.body == nil {
Brad Fitzpatrickb0a06c82014-11-26 09:21:28 -08001598 panic("internal error: should have a body in this state")
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001599 }
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001600
1601 // Sender sending more than they'd declared?
1602 if st.declBodyBytes != -1 && st.bodyBytes+int64(len(data)) > st.declBodyBytes {
Brad Fitzpatrickb7f5d982015-10-26 13:59:20 -05001603 st.body.CloseWithError(fmt.Errorf("sender tried to send more than declared Content-Length of %d bytes", st.declBodyBytes))
Brad Fitzpatricke2ba55e2016-08-02 15:44:32 +00001604 return streamError(id, ErrCodeStreamClosed)
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001605 }
Brad Fitzpatrick35028a42016-07-31 15:09:09 -07001606 if f.Length > 0 {
Brad Fitzpatrick068d35d2014-12-09 07:10:31 +11001607 // Check whether the client has flow control quota.
Brad Fitzpatrick35028a42016-07-31 15:09:09 -07001608 if st.inflow.available() < int32(f.Length) {
Brad Fitzpatricke2ba55e2016-08-02 15:44:32 +00001609 return streamError(id, ErrCodeFlowControl)
Brad Fitzpatrick068d35d2014-12-09 07:10:31 +11001610 }
Brad Fitzpatrick35028a42016-07-31 15:09:09 -07001611 st.inflow.take(int32(f.Length))
1612
1613 if len(data) > 0 {
1614 wrote, err := st.body.Write(data)
1615 if err != nil {
Brad Fitzpatricke2ba55e2016-08-02 15:44:32 +00001616 return streamError(id, ErrCodeStreamClosed)
Brad Fitzpatrick35028a42016-07-31 15:09:09 -07001617 }
1618 if wrote != len(data) {
1619 panic("internal error: bad Writer")
1620 }
1621 st.bodyBytes += int64(len(data))
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001622 }
Brad Fitzpatrick35028a42016-07-31 15:09:09 -07001623
1624 // Return any padded flow control now, since we won't
1625 // refund it later on body reads.
1626 if pad := int32(f.Length) - int32(len(data)); pad > 0 {
1627 sc.sendWindowUpdate32(nil, pad)
1628 sc.sendWindowUpdate32(st, pad)
Brad Fitzpatrick0218ba62014-11-26 09:36:05 -08001629 }
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001630 }
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08001631 if f.StreamEnded() {
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +00001632 st.endStream()
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001633 }
1634 return nil
1635}
1636
Tom Bergan87635b22016-11-07 17:51:22 -08001637func (sc *serverConn) processGoAway(f *GoAwayFrame) error {
1638 sc.serveG.check()
1639 if f.ErrCode != ErrCodeNo {
1640 sc.logf("http2: received GOAWAY %+v, starting graceful shutdown", f)
1641 } else {
1642 sc.vlogf("http2: received GOAWAY %+v, starting graceful shutdown", f)
1643 }
Tom Bergana8e8f922017-05-15 12:29:23 -07001644 sc.startGracefulShutdownInternal()
Tom Bergan87635b22016-11-07 17:51:22 -08001645 // http://tools.ietf.org/html/rfc7540#section-6.8
1646 // We should not create any new streams, which means we should disable push.
1647 sc.pushEnabled = false
1648 return nil
1649}
1650
Tom Berganc46f2652016-10-25 10:13:20 -07001651// isPushed reports whether the stream is server-initiated.
1652func (st *stream) isPushed() bool {
1653 return st.id%2 == 0
1654}
1655
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +00001656// endStream closes a Request.Body's pipe. It is called when a DATA
1657// frame says a request body is over (or after trailers).
1658func (st *stream) endStream() {
1659 sc := st.sc
1660 sc.serveG.check()
1661
1662 if st.declBodyBytes != -1 && st.declBodyBytes != st.bodyBytes {
1663 st.body.CloseWithError(fmt.Errorf("request declared a Content-Length of %d but only wrote %d bytes",
1664 st.declBodyBytes, st.bodyBytes))
1665 } else {
1666 st.body.closeWithErrorAndCode(io.EOF, st.copyTrailersToHandlerRequest)
1667 st.body.CloseWithError(io.EOF)
1668 }
1669 st.state = stateHalfClosedRemote
1670}
1671
1672// copyTrailersToHandlerRequest is run in the Handler's goroutine in
1673// its Request.Body.Read just before it gets io.EOF.
1674func (st *stream) copyTrailersToHandlerRequest() {
1675 for k, vv := range st.trailer {
1676 if _, ok := st.reqTrailer[k]; ok {
1677 // Only copy it over it was pre-declared.
1678 st.reqTrailer[k] = vv
1679 }
1680 }
1681}
1682
Kale Blankenshipd1e1b352016-12-29 14:47:41 -08001683// onWriteTimeout is run on its own goroutine (from time.AfterFunc)
1684// when the stream's WriteTimeout has fired.
1685func (st *stream) onWriteTimeout() {
1686 st.sc.writeFrameFromHandler(FrameWriteRequest{write: streamError(st.id, ErrCodeInternal)})
1687}
1688
Brad Fitzpatrick9e1fb3c2016-02-20 14:24:27 +05301689func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error {
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001690 sc.serveG.check()
Tom Berganc46f2652016-10-25 10:13:20 -07001691 id := f.StreamID
Brad Fitzpatrick21896bb2014-11-19 16:05:21 -08001692 if sc.inGoAway {
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001693 // Ignore.
1694 return nil
1695 }
Tom Berganc46f2652016-10-25 10:13:20 -07001696 // http://tools.ietf.org/html/rfc7540#section-5.1.1
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +00001697 // Streams initiated by a client MUST use odd-numbered stream
1698 // identifiers. [...] An endpoint that receives an unexpected
1699 // stream identifier MUST respond with a connection error
1700 // (Section 5.4.1) of type PROTOCOL_ERROR.
1701 if id%2 != 1 {
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001702 return ConnectionError(ErrCodeProtocol)
1703 }
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +00001704 // A HEADERS frame can be used to create a new stream or
1705 // send a trailer for an open one. If we already have a stream
1706 // open, let it process its own HEADERS frame (trailers at this
1707 // point, if it's valid).
Tom Berganc46f2652016-10-25 10:13:20 -07001708 if st := sc.streams[f.StreamID]; st != nil {
Tom Bergan3d9a20a2016-12-08 17:01:56 -08001709 if st.resetQueued {
1710 // We're sending RST_STREAM to close the stream, so don't bother
1711 // processing this frame.
1712 return nil
1713 }
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +00001714 return st.processTrailerHeaders(f)
1715 }
1716
1717 // [...] The identifier of a newly established stream MUST be
1718 // numerically greater than all streams that the initiating
1719 // endpoint has opened or reserved. [...] An endpoint that
1720 // receives an unexpected stream identifier MUST respond with
1721 // a connection error (Section 5.4.1) of type PROTOCOL_ERROR.
Tom Bergan55a30842016-11-04 15:18:50 -07001722 if id <= sc.maxClientStreamID {
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +00001723 return ConnectionError(ErrCodeProtocol)
1724 }
Tom Bergan55a30842016-11-04 15:18:50 -07001725 sc.maxClientStreamID = id
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +00001726
Brad Fitzpatrickc33d3782016-10-22 11:37:19 -07001727 if sc.idleTimer != nil {
1728 sc.idleTimer.Stop()
1729 }
1730
Tom Berganc46f2652016-10-25 10:13:20 -07001731 // http://tools.ietf.org/html/rfc7540#section-5.1.2
1732 // [...] Endpoints MUST NOT exceed the limit set by their peer. An
1733 // endpoint that receives a HEADERS frame that causes their
1734 // advertised concurrent stream limit to be exceeded MUST treat
1735 // this as a stream error (Section 5.4.2) of type PROTOCOL_ERROR
1736 // or REFUSED_STREAM.
1737 if sc.curClientStreams+1 > sc.advMaxStreams {
Brad Fitzpatrick6a9b77b2014-12-03 13:56:36 -08001738 if sc.unackedSettings == 0 {
1739 // They should know better.
Tom Berganc46f2652016-10-25 10:13:20 -07001740 return streamError(id, ErrCodeProtocol)
Brad Fitzpatrick6a9b77b2014-12-03 13:56:36 -08001741 }
1742 // Assume it's a network race, where they just haven't
1743 // received our last SETTINGS update. But actually
1744 // this can't happen yet, because we don't yet provide
1745 // a way for users to adjust server parameters at
1746 // runtime.
Tom Berganc46f2652016-10-25 10:13:20 -07001747 return streamError(id, ErrCodeRefusedStream)
Brad Fitzpatrickb3e0a872014-11-23 21:15:59 -08001748 }
Tom Berganc46f2652016-10-25 10:13:20 -07001749
1750 initialState := stateOpen
1751 if f.StreamEnded() {
1752 initialState = stateHalfClosedRemote
1753 }
1754 st := sc.newStream(id, 0, initialState)
1755
Tom Bergan65dfc082016-10-24 15:38:16 -07001756 if f.HasPriority() {
1757 if err := checkPriority(f.StreamID, f.Priority); err != nil {
1758 return err
1759 }
1760 sc.writeSched.AdjustStream(st.id, f.Priority)
1761 }
Brad Fitzpatrickb3e0a872014-11-23 21:15:59 -08001762
Brad Fitzpatrick9e1fb3c2016-02-20 14:24:27 +05301763 rw, req, err := sc.newWriterAndRequest(st, f)
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001764 if err != nil {
1765 return err
1766 }
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +00001767 st.reqTrailer = req.Trailer
1768 if st.reqTrailer != nil {
1769 st.trailer = make(http.Header)
1770 }
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001771 st.body = req.Body.(*requestBody).pipe // may be nil
1772 st.declBodyBytes = req.ContentLength
Brad Fitzpatrickd8f3c682015-10-12 20:56:49 +00001773
1774 handler := sc.handler.ServeHTTP
Brad Fitzpatrick9e1fb3c2016-02-20 14:24:27 +05301775 if f.Truncated {
Brad Fitzpatrickd8f3c682015-10-12 20:56:49 +00001776 // Their header list was too long. Send a 431 error.
1777 handler = handleHeaderListTooLong
Tom Berganc46f2652016-10-25 10:13:20 -07001778 } else if err := checkValidHTTP2RequestHeaders(req.Header); err != nil {
Brad Fitzpatrickaf4fee92016-04-05 16:55:11 +00001779 handler = new400Handler(err)
Brad Fitzpatrickd8f3c682015-10-12 20:56:49 +00001780 }
1781
Brad Fitzpatrick69729302016-09-29 17:31:05 -07001782 // The net/http package sets the read deadline from the
1783 // http.Server.ReadTimeout during the TLS handshake, but then
1784 // passes the connection off to us with the deadline already
Brad Fitzpatrickb336a972016-10-27 19:58:04 +00001785 // set. Disarm it here after the request headers are read,
1786 // similar to how the http1 server works. Here it's
1787 // technically more like the http1 Server's ReadHeaderTimeout
1788 // (in Go 1.8), though. That's a more sane option anyway.
Brad Fitzpatrick69729302016-09-29 17:31:05 -07001789 if sc.hs.ReadTimeout != 0 {
1790 sc.conn.SetReadDeadline(time.Time{})
1791 }
1792
Brad Fitzpatrickd8f3c682015-10-12 20:56:49 +00001793 go sc.runHandler(rw, req, handler)
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001794 return nil
1795}
1796
Brad Fitzpatrick9e1fb3c2016-02-20 14:24:27 +05301797func (st *stream) processTrailerHeaders(f *MetaHeadersFrame) error {
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +00001798 sc := st.sc
1799 sc.serveG.check()
Brad Fitzpatrick9e1fb3c2016-02-20 14:24:27 +05301800 if st.gotTrailerHeader {
1801 return ConnectionError(ErrCodeProtocol)
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +00001802 }
Brad Fitzpatrick9e1fb3c2016-02-20 14:24:27 +05301803 st.gotTrailerHeader = true
1804 if !f.StreamEnded() {
Brad Fitzpatricke2ba55e2016-08-02 15:44:32 +00001805 return streamError(st.id, ErrCodeProtocol)
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +00001806 }
Brad Fitzpatrickf530c4e2016-01-07 08:16:00 -08001807
Brad Fitzpatrick9e1fb3c2016-02-20 14:24:27 +05301808 if len(f.PseudoFields()) > 0 {
Brad Fitzpatricke2ba55e2016-08-02 15:44:32 +00001809 return streamError(st.id, ErrCodeProtocol)
Brad Fitzpatrickf530c4e2016-01-07 08:16:00 -08001810 }
Brad Fitzpatrick9e1fb3c2016-02-20 14:24:27 +05301811 if st.trailer != nil {
1812 for _, hf := range f.RegularFields() {
1813 key := sc.canonicalHeader(hf.Name)
Brad Fitzpatrick3c5cb152016-05-19 01:21:59 +00001814 if !ValidTrailerHeader(key) {
1815 // TODO: send more details to the peer somehow. But http2 has
1816 // no way to send debug data at a stream level. Discuss with
1817 // HTTP folk.
Brad Fitzpatricke2ba55e2016-08-02 15:44:32 +00001818 return streamError(st.id, ErrCodeProtocol)
Brad Fitzpatrick3c5cb152016-05-19 01:21:59 +00001819 }
Brad Fitzpatrick9e1fb3c2016-02-20 14:24:27 +05301820 st.trailer[key] = append(st.trailer[key], hf.Value)
1821 }
1822 }
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +00001823 st.endStream()
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +00001824 return nil
1825}
1826
Tom Bergan65dfc082016-10-24 15:38:16 -07001827func checkPriority(streamID uint32, p PriorityParam) error {
1828 if streamID == p.StreamDep {
1829 // Section 5.3.1: "A stream cannot depend on itself. An endpoint MUST treat
1830 // this as a stream error (Section 5.4.2) of type PROTOCOL_ERROR."
1831 // Section 5.3.3 says that a stream can depend on one of its dependencies,
1832 // so it's only self-dependencies that are forbidden.
1833 return streamError(streamID, ErrCodeProtocol)
1834 }
1835 return nil
1836}
1837
Brad Fitzpatrick2ee3a492014-11-30 23:18:32 -08001838func (sc *serverConn) processPriority(f *PriorityFrame) error {
Brad Fitzpatrickc33d3782016-10-22 11:37:19 -07001839 if sc.inGoAway {
1840 return nil
1841 }
Tom Bergan65dfc082016-10-24 15:38:16 -07001842 if err := checkPriority(f.StreamID, f.PriorityParam); err != nil {
1843 return err
1844 }
Tom Bergan4be9b972016-08-01 18:07:35 -07001845 sc.writeSched.AdjustStream(f.StreamID, f.PriorityParam)
Brad Fitzpatrick2ee3a492014-11-30 23:18:32 -08001846 return nil
1847}
1848
Tom Berganc46f2652016-10-25 10:13:20 -07001849func (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream {
1850 sc.serveG.check()
1851 if id == 0 {
1852 panic("internal error: cannot create stream with id 0")
1853 }
1854
1855 ctx, cancelCtx := contextWithCancel(sc.baseCtx)
1856 st := &stream{
1857 sc: sc,
1858 id: id,
1859 state: state,
1860 ctx: ctx,
1861 cancelCtx: cancelCtx,
1862 }
1863 st.cw.Init()
1864 st.flow.conn = &sc.flow // link to conn-level counter
Tom Bergan906cda92017-02-18 12:36:51 -08001865 st.flow.add(sc.initialStreamSendWindowSize)
1866 st.inflow.conn = &sc.inflow // link to conn-level counter
1867 st.inflow.add(sc.srv.initialStreamRecvWindowSize())
Kale Blankenshipd1e1b352016-12-29 14:47:41 -08001868 if sc.hs.WriteTimeout != 0 {
1869 st.writeDeadline = time.AfterFunc(sc.hs.WriteTimeout, st.onWriteTimeout)
1870 }
Tom Berganc46f2652016-10-25 10:13:20 -07001871
1872 sc.streams[id] = st
1873 sc.writeSched.OpenStream(st.id, OpenStreamOptions{PusherID: pusherID})
1874 if st.isPushed() {
1875 sc.curPushedStreams++
1876 } else {
1877 sc.curClientStreams++
1878 }
Tom Bergan0c96df32016-12-05 22:33:37 -08001879 if sc.curOpenStreams() == 1 {
Tom Berganc46f2652016-10-25 10:13:20 -07001880 sc.setConnState(http.StateActive)
1881 }
1882
1883 return st
1884}
1885
Brad Fitzpatrick9e1fb3c2016-02-20 14:24:27 +05301886func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*responseWriter, *http.Request, error) {
Brad Fitzpatrickb3e0a872014-11-23 21:15:59 -08001887 sc.serveG.check()
Brad Fitzpatrickb3e0a872014-11-23 21:15:59 -08001888
Tom Berganc46f2652016-10-25 10:13:20 -07001889 rp := requestParam{
1890 method: f.PseudoValue("method"),
1891 scheme: f.PseudoValue("scheme"),
1892 authority: f.PseudoValue("authority"),
1893 path: f.PseudoValue("path"),
1894 }
Brad Fitzpatrick961116a2016-01-05 14:53:21 -08001895
Tom Berganc46f2652016-10-25 10:13:20 -07001896 isConnect := rp.method == "CONNECT"
Brad Fitzpatrick961116a2016-01-05 14:53:21 -08001897 if isConnect {
Tom Berganc46f2652016-10-25 10:13:20 -07001898 if rp.path != "" || rp.scheme != "" || rp.authority == "" {
Brad Fitzpatricke2ba55e2016-08-02 15:44:32 +00001899 return nil, nil, streamError(f.StreamID, ErrCodeProtocol)
Brad Fitzpatrick961116a2016-01-05 14:53:21 -08001900 }
Tom Berganc46f2652016-10-25 10:13:20 -07001901 } else if rp.method == "" || rp.path == "" || (rp.scheme != "https" && rp.scheme != "http") {
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001902 // See 8.1.2.6 Malformed Requests and Responses:
1903 //
1904 // Malformed requests or responses that are detected
1905 // MUST be treated as a stream error (Section 5.4.2)
1906 // of type PROTOCOL_ERROR."
1907 //
1908 // 8.1.2.3 Request Pseudo-Header Fields
1909 // "All HTTP/2 requests MUST include exactly one valid
1910 // value for the :method, :scheme, and :path
1911 // pseudo-header fields"
Brad Fitzpatricke2ba55e2016-08-02 15:44:32 +00001912 return nil, nil, streamError(f.StreamID, ErrCodeProtocol)
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001913 }
Brad Fitzpatrick961116a2016-01-05 14:53:21 -08001914
Brad Fitzpatrick9e1fb3c2016-02-20 14:24:27 +05301915 bodyOpen := !f.StreamEnded()
Tom Berganc46f2652016-10-25 10:13:20 -07001916 if rp.method == "HEAD" && bodyOpen {
Brad Fitzpatrickc745c362015-11-24 17:14:16 -08001917 // HEAD requests can't have bodies
Brad Fitzpatricke2ba55e2016-08-02 15:44:32 +00001918 return nil, nil, streamError(f.StreamID, ErrCodeProtocol)
Brad Fitzpatrickc745c362015-11-24 17:14:16 -08001919 }
Brad Fitzpatrick961116a2016-01-05 14:53:21 -08001920
Tom Berganc46f2652016-10-25 10:13:20 -07001921 rp.header = make(http.Header)
1922 for _, hf := range f.RegularFields() {
1923 rp.header.Add(sc.canonicalHeader(hf.Name), hf.Value)
1924 }
1925 if rp.authority == "" {
1926 rp.authority = rp.header.Get("Host")
1927 }
1928
1929 rw, req, err := sc.newWriterAndRequestNoBody(st, rp)
1930 if err != nil {
1931 return nil, nil, err
1932 }
1933 if bodyOpen {
Tom Berganc46f2652016-10-25 10:13:20 -07001934 if vv, ok := rp.header["Content-Length"]; ok {
1935 req.ContentLength, _ = strconv.ParseInt(vv[0], 10, 64)
1936 } else {
1937 req.ContentLength = -1
1938 }
Tom Bergan10c134e2017-02-23 14:05:28 -08001939 req.Body.(*requestBody).pipe = &pipe{
1940 b: &dataBuffer{expected: req.ContentLength},
1941 }
Tom Berganc46f2652016-10-25 10:13:20 -07001942 }
1943 return rw, req, nil
1944}
1945
1946type requestParam struct {
1947 method string
1948 scheme, authority, path string
1949 header http.Header
1950}
1951
1952func (sc *serverConn) newWriterAndRequestNoBody(st *stream, rp requestParam) (*responseWriter, *http.Request, error) {
1953 sc.serveG.check()
1954
1955 var tlsState *tls.ConnectionState // nil if not scheme https
1956 if rp.scheme == "https" {
Brad Fitzpatrick30b16812014-12-08 10:10:39 -08001957 tlsState = sc.tlsState
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001958 }
Brad Fitzpatrick9e1fb3c2016-02-20 14:24:27 +05301959
Tom Berganc46f2652016-10-25 10:13:20 -07001960 needsContinue := rp.header.Get("Expect") == "100-continue"
Brad Fitzpatrick9d63ade2014-11-15 12:02:43 -08001961 if needsContinue {
Tom Berganc46f2652016-10-25 10:13:20 -07001962 rp.header.Del("Expect")
Brad Fitzpatrick9d63ade2014-11-15 12:02:43 -08001963 }
Brad Fitzpatrickb8469202015-10-07 22:10:10 -07001964 // Merge Cookie headers into one "; "-delimited value.
Tom Berganc46f2652016-10-25 10:13:20 -07001965 if cookies := rp.header["Cookie"]; len(cookies) > 1 {
1966 rp.header.Set("Cookie", strings.Join(cookies, "; "))
Brad Fitzpatrickb8469202015-10-07 22:10:10 -07001967 }
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +00001968
1969 // Setup Trailers
1970 var trailer http.Header
Tom Berganc46f2652016-10-25 10:13:20 -07001971 for _, v := range rp.header["Trailer"] {
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +00001972 for _, key := range strings.Split(v, ",") {
1973 key = http.CanonicalHeaderKey(strings.TrimSpace(key))
1974 switch key {
1975 case "Transfer-Encoding", "Trailer", "Content-Length":
1976 // Bogus. (copy of http1 rules)
1977 // Ignore.
1978 default:
1979 if trailer == nil {
1980 trailer = make(http.Header)
1981 }
1982 trailer[key] = nil
1983 }
1984 }
1985 }
Tom Berganc46f2652016-10-25 10:13:20 -07001986 delete(rp.header, "Trailer")
1987
1988 var url_ *url.URL
1989 var requestURI string
1990 if rp.method == "CONNECT" {
1991 url_ = &url.URL{Host: rp.authority}
1992 requestURI = rp.authority // mimic HTTP/1 server behavior
1993 } else {
1994 var err error
1995 url_, err = url.ParseRequestURI(rp.path)
1996 if err != nil {
1997 return nil, nil, streamError(st.id, ErrCodeProtocol)
1998 }
1999 requestURI = rp.path
2000 }
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +00002001
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002002 body := &requestBody{
Brad Fitzpatrick914bad52014-11-30 21:05:26 -08002003 conn: sc,
Brad Fitzpatrick9e1fb3c2016-02-20 14:24:27 +05302004 stream: st,
Brad Fitzpatrick9d63ade2014-11-15 12:02:43 -08002005 needsContinue: needsContinue,
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002006 }
2007 req := &http.Request{
Tom Berganc46f2652016-10-25 10:13:20 -07002008 Method: rp.method,
Brad Fitzpatrick961116a2016-01-05 14:53:21 -08002009 URL: url_,
Brad Fitzpatrickdf959c22014-12-09 07:20:20 +11002010 RemoteAddr: sc.remoteAddrStr,
Tom Berganc46f2652016-10-25 10:13:20 -07002011 Header: rp.header,
Brad Fitzpatrick961116a2016-01-05 14:53:21 -08002012 RequestURI: requestURI,
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002013 Proto: "HTTP/2.0",
2014 ProtoMajor: 2,
2015 ProtoMinor: 0,
2016 TLS: tlsState,
Tom Berganc46f2652016-10-25 10:13:20 -07002017 Host: rp.authority,
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002018 Body: body,
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +00002019 Trailer: trailer,
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002020 }
Brad Fitzpatrick8aacbec2016-05-18 19:54:31 +00002021 req = requestWithContext(req, st.ctx)
Brad Fitzpatrick729bd722014-11-13 14:09:36 -08002022
2023 rws := responseWriterStatePool.Get().(*responseWriterState)
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002024 bwSave := rws.bw
Brad Fitzpatrick520123b2014-11-14 15:57:37 -08002025 *rws = responseWriterState{} // zero all the fields
Brad Fitzpatrick914bad52014-11-30 21:05:26 -08002026 rws.conn = sc
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002027 rws.bw = bwSave
2028 rws.bw.Reset(chunkWriter{rws})
Brad Fitzpatrick9e1fb3c2016-02-20 14:24:27 +05302029 rws.stream = st
Brad Fitzpatrick729bd722014-11-13 14:09:36 -08002030 rws.req = req
2031 rws.body = body
Brad Fitzpatrick729bd722014-11-13 14:09:36 -08002032
2033 rw := &responseWriter{rws: rws}
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002034 return rw, req, nil
2035}
2036
2037// Run on its own goroutine.
Brad Fitzpatrickd8f3c682015-10-12 20:56:49 +00002038func (sc *serverConn) runHandler(rw *responseWriter, req *http.Request, handler func(http.ResponseWriter, *http.Request)) {
Brad Fitzpatrick74bd44b2015-12-15 00:47:28 +00002039 didPanic := true
2040 defer func() {
Brad Fitzpatrick8aacbec2016-05-18 19:54:31 +00002041 rw.rws.stream.cancelCtx()
Brad Fitzpatrick74bd44b2015-12-15 00:47:28 +00002042 if didPanic {
2043 e := recover()
Tom Bergan4be9b972016-08-01 18:07:35 -07002044 sc.writeFrameFromHandler(FrameWriteRequest{
Brad Fitzpatrick74bd44b2015-12-15 00:47:28 +00002045 write: handlerPanicRST{rw.rws.stream.id},
2046 stream: rw.rws.stream,
2047 })
Brad Fitzpatrick0e2717d2016-11-10 23:13:32 +00002048 // Same as net/http:
2049 if shouldLogPanic(e) {
2050 const size = 64 << 10
2051 buf := make([]byte, size)
2052 buf = buf[:runtime.Stack(buf, false)]
2053 sc.logf("http2: panic serving %v: %v\n%s", sc.conn.RemoteAddr(), e, buf)
2054 }
Brad Fitzpatrick74bd44b2015-12-15 00:47:28 +00002055 return
2056 }
2057 rw.handlerDone()
2058 }()
Brad Fitzpatrickd8f3c682015-10-12 20:56:49 +00002059 handler(rw, req)
Brad Fitzpatrick74bd44b2015-12-15 00:47:28 +00002060 didPanic = false
Brad Fitzpatrickd8f3c682015-10-12 20:56:49 +00002061}
2062
2063func handleHeaderListTooLong(w http.ResponseWriter, r *http.Request) {
2064 // 10.5.1 Limits on Header Block Size:
2065 // .. "A server that receives a larger header block than it is
2066 // willing to handle can send an HTTP 431 (Request Header Fields Too
2067 // Large) status code"
2068 const statusRequestHeaderFieldsTooLarge = 431 // only in Go 1.6+
2069 w.WriteHeader(statusRequestHeaderFieldsTooLarge)
2070 io.WriteString(w, "<h1>HTTP Error 431</h1><p>Request Header Field(s) Too Large</p>")
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002071}
2072
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002073// called from handler goroutines.
2074// h may be nil.
Brad Fitzpatrick56401052015-10-20 22:27:39 +00002075func (sc *serverConn) writeHeaders(st *stream, headerData *writeResHeaders) error {
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08002076 sc.serveG.checkNotOn() // NOT on
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002077 var errc chan error
Brad Fitzpatrickf16a0b32014-11-28 13:49:30 -08002078 if headerData.h != nil {
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002079 // If there's a header map (which we don't own), so we have to block on
2080 // waiting for this frame to be written, so an http.Flush mid-handler
2081 // writes out the correct value of keys, before a handler later potentially
2082 // mutates it.
Brad Fitzpatrickc94bffa2015-10-13 18:18:12 +00002083 errc = errChanPool.Get().(chan error)
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002084 }
Tom Bergan4be9b972016-08-01 18:07:35 -07002085 if err := sc.writeFrameFromHandler(FrameWriteRequest{
Brad Fitzpatrickf16a0b32014-11-28 13:49:30 -08002086 write: headerData,
2087 stream: st,
2088 done: errc,
Brad Fitzpatrick56401052015-10-20 22:27:39 +00002089 }); err != nil {
2090 return err
2091 }
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002092 if errc != nil {
Brad Fitzpatrick9b41faf2014-11-19 10:45:13 -08002093 select {
Brad Fitzpatrick56401052015-10-20 22:27:39 +00002094 case err := <-errc:
Brad Fitzpatrickc94bffa2015-10-13 18:18:12 +00002095 errChanPool.Put(errc)
Brad Fitzpatrick56401052015-10-20 22:27:39 +00002096 return err
Brad Fitzpatrick9b41faf2014-11-19 10:45:13 -08002097 case <-sc.doneServing:
Brad Fitzpatrick56401052015-10-20 22:27:39 +00002098 return errClientDisconnected
Brad Fitzpatrickc94bffa2015-10-13 18:18:12 +00002099 case <-st.cw:
Brad Fitzpatrick56401052015-10-20 22:27:39 +00002100 return errStreamClosed
Brad Fitzpatrick9b41faf2014-11-19 10:45:13 -08002101 }
Brad Fitzpatrick520123b2014-11-14 15:57:37 -08002102 }
Brad Fitzpatrick56401052015-10-20 22:27:39 +00002103 return nil
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002104}
2105
Brad Fitzpatrick9d63ade2014-11-15 12:02:43 -08002106// called from handler goroutines.
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08002107func (sc *serverConn) write100ContinueHeaders(st *stream) {
Tom Bergan4be9b972016-08-01 18:07:35 -07002108 sc.writeFrameFromHandler(FrameWriteRequest{
Brad Fitzpatrickf16a0b32014-11-28 13:49:30 -08002109 write: write100ContinueHeadersFrame{st.id},
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08002110 stream: st,
Brad Fitzpatrick9d63ade2014-11-15 12:02:43 -08002111 })
2112}
2113
Brad Fitzpatrickc8bab6a2014-12-07 18:51:56 -08002114// A bodyReadMsg tells the server loop that the http.Handler read n
2115// bytes of the DATA from the client on the given stream.
2116type bodyReadMsg struct {
2117 st *stream
2118 n int
2119}
2120
2121// called from handler goroutines.
2122// Notes that the handler for the given stream ID read n bytes of its body
2123// and schedules flow control tokens to be sent.
Brad Fitzpatrick3bafa332016-10-19 14:40:54 +00002124func (sc *serverConn) noteBodyReadFromHandler(st *stream, n int, err error) {
Brad Fitzpatrickc8bab6a2014-12-07 18:51:56 -08002125 sc.serveG.checkNotOn() // NOT on
Brad Fitzpatrick3bafa332016-10-19 14:40:54 +00002126 if n > 0 {
2127 select {
2128 case sc.bodyReadCh <- bodyReadMsg{st, n}:
2129 case <-sc.doneServing:
2130 }
2131 }
Brad Fitzpatrickc8bab6a2014-12-07 18:51:56 -08002132}
2133
2134func (sc *serverConn) noteBodyRead(st *stream, n int) {
2135 sc.serveG.check()
2136 sc.sendWindowUpdate(nil, n) // conn-level
Brad Fitzpatrick0f1a8652014-12-07 20:49:33 -08002137 if st.state != stateHalfClosedRemote && st.state != stateClosed {
2138 // Don't send this WINDOW_UPDATE if the stream is closed
2139 // remotely.
2140 sc.sendWindowUpdate(st, n)
2141 }
Brad Fitzpatrickc8bab6a2014-12-07 18:51:56 -08002142}
2143
2144// st may be nil for conn-level
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08002145func (sc *serverConn) sendWindowUpdate(st *stream, n int) {
Brad Fitzpatrickc8bab6a2014-12-07 18:51:56 -08002146 sc.serveG.check()
2147 // "The legal range for the increment to the flow control
2148 // window is 1 to 2^31-1 (2,147,483,647) octets."
Brad Fitzpatrick068d35d2014-12-09 07:10:31 +11002149 // A Go Read call on 64-bit machines could in theory read
2150 // a larger Read than this. Very unlikely, but we handle it here
2151 // rather than elsewhere for now.
2152 const maxUint31 = 1<<31 - 1
2153 for n >= maxUint31 {
2154 sc.sendWindowUpdate32(st, maxUint31)
2155 n -= maxUint31
2156 }
2157 sc.sendWindowUpdate32(st, int32(n))
2158}
2159
2160// st may be nil for conn-level
2161func (sc *serverConn) sendWindowUpdate32(st *stream, n int32) {
2162 sc.serveG.check()
2163 if n == 0 {
2164 return
2165 }
2166 if n < 0 {
2167 panic("negative update")
2168 }
Brad Fitzpatrickc8bab6a2014-12-07 18:51:56 -08002169 var streamID uint32
2170 if st != nil {
2171 streamID = st.id
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08002172 }
Tom Bergan4be9b972016-08-01 18:07:35 -07002173 sc.writeFrame(FrameWriteRequest{
Brad Fitzpatrick068d35d2014-12-09 07:10:31 +11002174 write: writeWindowUpdate{streamID: streamID, n: uint32(n)},
2175 stream: st,
2176 })
2177 var ok bool
2178 if st == nil {
2179 ok = sc.inflow.add(n)
2180 } else {
2181 ok = st.inflow.add(n)
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002182 }
Brad Fitzpatrick068d35d2014-12-09 07:10:31 +11002183 if !ok {
2184 panic("internal error; sent too many window updates without decrements?")
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002185 }
2186}
2187
Brad Fitzpatrick40a0a182016-10-21 09:23:26 +01002188// requestBody is the Handler's Request.Body type.
2189// Read and Close may be called concurrently.
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002190type requestBody struct {
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08002191 stream *stream
Brad Fitzpatrick914bad52014-11-30 21:05:26 -08002192 conn *serverConn
Brad Fitzpatrick40a0a182016-10-21 09:23:26 +01002193 closed bool // for use by Close only
2194 sawEOF bool // for use by Read only
Brad Fitzpatrick9d63ade2014-11-15 12:02:43 -08002195 pipe *pipe // non-nil if we have a HTTP entity message body
2196 needsContinue bool // need to send a 100-continue
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002197}
2198
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002199func (b *requestBody) Close() error {
Brad Fitzpatrick40a0a182016-10-21 09:23:26 +01002200 if b.pipe != nil && !b.closed {
Brad Fitzpatrick4d07e8a2016-05-20 18:55:47 +00002201 b.pipe.BreakWithError(errClosedBody)
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002202 }
2203 b.closed = true
2204 return nil
2205}
2206
2207func (b *requestBody) Read(p []byte) (n int, err error) {
Brad Fitzpatrick9d63ade2014-11-15 12:02:43 -08002208 if b.needsContinue {
2209 b.needsContinue = false
Brad Fitzpatrick914bad52014-11-30 21:05:26 -08002210 b.conn.write100ContinueHeaders(b.stream)
Brad Fitzpatrick9d63ade2014-11-15 12:02:43 -08002211 }
Brad Fitzpatrick40a0a182016-10-21 09:23:26 +01002212 if b.pipe == nil || b.sawEOF {
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002213 return 0, io.EOF
2214 }
2215 n, err = b.pipe.Read(p)
Brad Fitzpatrick3bafa332016-10-19 14:40:54 +00002216 if err == io.EOF {
Brad Fitzpatrick40a0a182016-10-21 09:23:26 +01002217 b.sawEOF = true
2218 }
2219 if b.conn == nil && inTests {
2220 return
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002221 }
Brad Fitzpatrick3bafa332016-10-19 14:40:54 +00002222 b.conn.noteBodyReadFromHandler(b.stream, n, err)
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002223 return
2224}
2225
Dmitri Shuralyov357296a2016-11-07 15:02:51 -08002226// responseWriter is the http.ResponseWriter implementation. It's
2227// intentionally small (1 pointer wide) to minimize garbage. The
Brad Fitzpatrick729bd722014-11-13 14:09:36 -08002228// responseWriterState pointer inside is zeroed at the end of a
2229// request (in handlerDone) and calls on the responseWriter thereafter
2230// simply crash (caller's mistake), but the much larger responseWriterState
2231// and buffers are reused between multiple requests.
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002232type responseWriter struct {
Brad Fitzpatrick729bd722014-11-13 14:09:36 -08002233 rws *responseWriterState
2234}
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002235
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002236// Optional http.ResponseWriter interfaces implemented.
2237var (
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08002238 _ http.CloseNotifier = (*responseWriter)(nil)
2239 _ http.Flusher = (*responseWriter)(nil)
2240 _ stringWriter = (*responseWriter)(nil)
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002241)
2242
Brad Fitzpatrick729bd722014-11-13 14:09:36 -08002243type responseWriterState struct {
2244 // immutable within a request:
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08002245 stream *stream
2246 req *http.Request
2247 body *requestBody // to close at end of request, if DATA frames didn't
Brad Fitzpatrick914bad52014-11-30 21:05:26 -08002248 conn *serverConn
Brad Fitzpatrick729bd722014-11-13 14:09:36 -08002249
Brad Fitzpatrick520123b2014-11-14 15:57:37 -08002250 // TODO: adjust buffer writing sizes based on server config, frame size updates from peer, etc
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002251 bw *bufio.Writer // writing to a chunkWriter{this *responseWriterState}
Brad Fitzpatrick729bd722014-11-13 14:09:36 -08002252
2253 // mutated by http.Handler goroutine:
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002254 handlerHeader http.Header // nil until called
2255 snapHeader http.Header // snapshot of handlerHeader at WriteHeader time
Blake Mizeranyb4be4942015-12-15 17:33:14 -08002256 trailers []string // set in writeChunk
Brad Fitzpatrick520123b2014-11-14 15:57:37 -08002257 status int // status code passed to WriteHeader
Brad Fitzpatrick3c8c6132014-11-20 18:34:52 -08002258 wroteHeader bool // WriteHeader called (explicitly or implicitly). Not necessarily sent to user yet.
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002259 sentHeader bool // have we sent the header frame?
2260 handlerDone bool // handler has finished
Brad Fitzpatrickfe686d42017-06-18 05:18:41 +00002261 dirty bool // a Write failed; don't reuse this responseWriterState
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08002262
Brad Fitzpatrickc745c362015-11-24 17:14:16 -08002263 sentContentLen int64 // non-zero if handler set a Content-Length header
2264 wroteBytes int64
2265
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08002266 closeNotifierMu sync.Mutex // guards closeNotifierCh
2267 closeNotifierCh chan bool // nil until first used
Brad Fitzpatrick729bd722014-11-13 14:09:36 -08002268}
2269
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002270type chunkWriter struct{ rws *responseWriterState }
2271
Brad Fitzpatrick3d7a3ad2014-11-15 21:38:23 -08002272func (cw chunkWriter) Write(p []byte) (n int, err error) { return cw.rws.writeChunk(p) }
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002273
Blake Mizeranyb4be4942015-12-15 17:33:14 -08002274func (rws *responseWriterState) hasTrailers() bool { return len(rws.trailers) != 0 }
2275
2276// declareTrailer is called for each Trailer header when the
2277// response header is written. It notes that a header will need to be
2278// written in the trailers at the end of the response.
2279func (rws *responseWriterState) declareTrailer(k string) {
2280 k = http.CanonicalHeaderKey(k)
Brad Fitzpatrick3c5cb152016-05-19 01:21:59 +00002281 if !ValidTrailerHeader(k) {
Blake Mizeranyb4be4942015-12-15 17:33:14 -08002282 // Forbidden by RFC 2616 14.40.
Brad Fitzpatrick3c5cb152016-05-19 01:21:59 +00002283 rws.conn.logf("ignoring invalid trailer %q", k)
Blake Mizeranyb4be4942015-12-15 17:33:14 -08002284 return
2285 }
Brad Fitzpatrickd513e582016-01-31 06:24:40 +00002286 if !strSliceContains(rws.trailers, k) {
2287 rws.trailers = append(rws.trailers, k)
2288 }
Blake Mizeranyb4be4942015-12-15 17:33:14 -08002289}
2290
Brad Fitzpatrick3d7a3ad2014-11-15 21:38:23 -08002291// writeChunk writes chunks from the bufio.Writer. But because
2292// bufio.Writer may bypass its chunking, sometimes p may be
2293// arbitrarily large.
2294//
2295// writeChunk is also responsible (on the first chunk) for sending the
2296// HEADER response.
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002297func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
2298 if !rws.wroteHeader {
2299 rws.writeHeader(200)
2300 }
Blake Mizeranyb4be4942015-12-15 17:33:14 -08002301
Brad Fitzpatrickc745c362015-11-24 17:14:16 -08002302 isHeadResp := rws.req.Method == "HEAD"
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002303 if !rws.sentHeader {
2304 rws.sentHeader = true
Brad Fitzpatrickc745c362015-11-24 17:14:16 -08002305 var ctype, clen string
2306 if clen = rws.snapHeader.Get("Content-Length"); clen != "" {
2307 rws.snapHeader.Del("Content-Length")
2308 clen64, err := strconv.ParseInt(clen, 10, 64)
2309 if err == nil && clen64 >= 0 {
2310 rws.sentContentLen = clen64
2311 } else {
2312 clen = ""
2313 }
2314 }
Brad Fitzpatrick1796f9b2015-12-08 22:22:07 +00002315 if clen == "" && rws.handlerDone && bodyAllowedForStatus(rws.status) && (len(p) > 0 || !isHeadResp) {
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002316 clen = strconv.Itoa(len(p))
2317 }
Brad Fitzpatrick1796f9b2015-12-08 22:22:07 +00002318 _, hasContentType := rws.snapHeader["Content-Type"]
2319 if !hasContentType && bodyAllowedForStatus(rws.status) {
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002320 ctype = http.DetectContentType(p)
2321 }
Brad Fitzpatrickc745c362015-11-24 17:14:16 -08002322 var date string
2323 if _, ok := rws.snapHeader["Date"]; !ok {
2324 // TODO(bradfitz): be faster here, like net/http? measure.
2325 date = time.Now().UTC().Format(http.TimeFormat)
2326 }
Blake Mizeranyb4be4942015-12-15 17:33:14 -08002327
2328 for _, v := range rws.snapHeader["Trailer"] {
2329 foreachHeaderElement(v, rws.declareTrailer)
2330 }
2331
2332 endStream := (rws.handlerDone && !rws.hasTrailers() && len(p) == 0) || isHeadResp
Brad Fitzpatrick56401052015-10-20 22:27:39 +00002333 err = rws.conn.writeHeaders(rws.stream, &writeResHeaders{
Brad Fitzpatrickf16a0b32014-11-28 13:49:30 -08002334 streamID: rws.stream.id,
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002335 httpResCode: rws.status,
2336 h: rws.snapHeader,
Brad Fitzpatrick3d7a3ad2014-11-15 21:38:23 -08002337 endStream: endStream,
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002338 contentType: ctype,
2339 contentLength: clen,
Brad Fitzpatrickc745c362015-11-24 17:14:16 -08002340 date: date,
Brad Fitzpatrickc94bffa2015-10-13 18:18:12 +00002341 })
Brad Fitzpatrick56401052015-10-20 22:27:39 +00002342 if err != nil {
Brad Fitzpatrickfe686d42017-06-18 05:18:41 +00002343 rws.dirty = true
Brad Fitzpatrick56401052015-10-20 22:27:39 +00002344 return 0, err
2345 }
Brad Fitzpatrick3d7a3ad2014-11-15 21:38:23 -08002346 if endStream {
Brad Fitzpatrick2b459472014-11-30 19:18:57 -08002347 return 0, nil
Brad Fitzpatrick3d7a3ad2014-11-15 21:38:23 -08002348 }
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002349 }
Brad Fitzpatrickc745c362015-11-24 17:14:16 -08002350 if isHeadResp {
2351 return len(p), nil
2352 }
Brad Fitzpatrick2b459472014-11-30 19:18:57 -08002353 if len(p) == 0 && !rws.handlerDone {
2354 return 0, nil
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002355 }
Brad Fitzpatrick56401052015-10-20 22:27:39 +00002356
Brad Fitzpatrickd513e582016-01-31 06:24:40 +00002357 if rws.handlerDone {
2358 rws.promoteUndeclaredTrailers()
2359 }
2360
Blake Mizeranyb4be4942015-12-15 17:33:14 -08002361 endStream := rws.handlerDone && !rws.hasTrailers()
2362 if len(p) > 0 || endStream {
2363 // only send a 0 byte DATA frame if we're ending the stream.
2364 if err := rws.conn.writeDataFromHandler(rws.stream, p, endStream); err != nil {
Brad Fitzpatrickfe686d42017-06-18 05:18:41 +00002365 rws.dirty = true
Blake Mizeranyb4be4942015-12-15 17:33:14 -08002366 return 0, err
2367 }
2368 }
2369
2370 if rws.handlerDone && rws.hasTrailers() {
2371 err = rws.conn.writeHeaders(rws.stream, &writeResHeaders{
2372 streamID: rws.stream.id,
2373 h: rws.handlerHeader,
2374 trailers: rws.trailers,
2375 endStream: true,
2376 })
Brad Fitzpatrickfe686d42017-06-18 05:18:41 +00002377 if err != nil {
2378 rws.dirty = true
2379 }
Blake Mizeranyb4be4942015-12-15 17:33:14 -08002380 return len(p), err
Brad Fitzpatrick3d7a3ad2014-11-15 21:38:23 -08002381 }
Brad Fitzpatrick2b459472014-11-30 19:18:57 -08002382 return len(p), nil
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002383}
Brad Fitzpatrick729bd722014-11-13 14:09:36 -08002384
Brad Fitzpatrickd513e582016-01-31 06:24:40 +00002385// TrailerPrefix is a magic prefix for ResponseWriter.Header map keys
2386// that, if present, signals that the map entry is actually for
2387// the response trailers, and not the response headers. The prefix
2388// is stripped after the ServeHTTP call finishes and the values are
2389// sent in the trailers.
2390//
2391// This mechanism is intended only for trailers that are not known
2392// prior to the headers being written. If the set of trailers is fixed
2393// or known before the header is written, the normal Go trailers mechanism
2394// is preferred:
2395// https://golang.org/pkg/net/http/#ResponseWriter
2396// https://golang.org/pkg/net/http/#example_ResponseWriter_trailers
2397const TrailerPrefix = "Trailer:"
2398
2399// promoteUndeclaredTrailers permits http.Handlers to set trailers
2400// after the header has already been flushed. Because the Go
2401// ResponseWriter interface has no way to set Trailers (only the
2402// Header), and because we didn't want to expand the ResponseWriter
2403// interface, and because nobody used trailers, and because RFC 2616
2404// says you SHOULD (but not must) predeclare any trailers in the
2405// header, the official ResponseWriter rules said trailers in Go must
2406// be predeclared, and then we reuse the same ResponseWriter.Header()
Dmitri Shuralyov357296a2016-11-07 15:02:51 -08002407// map to mean both Headers and Trailers. When it's time to write the
Brad Fitzpatrickd513e582016-01-31 06:24:40 +00002408// Trailers, we pick out the fields of Headers that were declared as
2409// trailers. That worked for a while, until we found the first major
2410// user of Trailers in the wild: gRPC (using them only over http2),
2411// and gRPC libraries permit setting trailers mid-stream without
2412// predeclarnig them. So: change of plans. We still permit the old
2413// way, but we also permit this hack: if a Header() key begins with
2414// "Trailer:", the suffix of that key is a Trailer. Because ':' is an
2415// invalid token byte anyway, there is no ambiguity. (And it's already
2416// filtered out) It's mildly hacky, but not terrible.
2417//
2418// This method runs after the Handler is done and promotes any Header
2419// fields to be trailers.
2420func (rws *responseWriterState) promoteUndeclaredTrailers() {
2421 for k, vv := range rws.handlerHeader {
2422 if !strings.HasPrefix(k, TrailerPrefix) {
2423 continue
2424 }
2425 trailerKey := strings.TrimPrefix(k, TrailerPrefix)
2426 rws.declareTrailer(trailerKey)
2427 rws.handlerHeader[http.CanonicalHeaderKey(trailerKey)] = vv
2428 }
Brad Fitzpatrick48765182016-03-22 02:00:46 +00002429
2430 if len(rws.trailers) > 1 {
2431 sorter := sorterPool.Get().(*sorter)
2432 sorter.SortStrings(rws.trailers)
2433 sorterPool.Put(sorter)
2434 }
Brad Fitzpatrickd513e582016-01-31 06:24:40 +00002435}
2436
Brad Fitzpatrick729bd722014-11-13 14:09:36 -08002437func (w *responseWriter) Flush() {
Brad Fitzpatrick520123b2014-11-14 15:57:37 -08002438 rws := w.rws
2439 if rws == nil {
2440 panic("Header called after Handler finished")
2441 }
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002442 if rws.bw.Buffered() > 0 {
2443 if err := rws.bw.Flush(); err != nil {
2444 // Ignore the error. The frame writer already knows.
2445 return
Brad Fitzpatrick520123b2014-11-14 15:57:37 -08002446 }
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002447 } else {
2448 // The bufio.Writer won't call chunkWriter.Write
2449 // (writeChunk with zero bytes, so we have to do it
2450 // ourselves to force the HTTP response header and/or
2451 // final DATA frame (with END_STREAM) to be sent.
2452 rws.writeChunk(nil)
Brad Fitzpatrick520123b2014-11-14 15:57:37 -08002453 }
Brad Fitzpatrick520123b2014-11-14 15:57:37 -08002454}
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002455
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08002456func (w *responseWriter) CloseNotify() <-chan bool {
2457 rws := w.rws
2458 if rws == nil {
2459 panic("CloseNotify called after Handler finished")
2460 }
2461 rws.closeNotifierMu.Lock()
2462 ch := rws.closeNotifierCh
2463 if ch == nil {
2464 ch = make(chan bool, 1)
2465 rws.closeNotifierCh = ch
Brad Fitzpatrick9ef22112016-11-09 21:27:32 +00002466 cw := rws.stream.cw
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08002467 go func() {
Brad Fitzpatrick9ef22112016-11-09 21:27:32 +00002468 cw.Wait() // wait for close
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08002469 ch <- true
2470 }()
2471 }
2472 rws.closeNotifierMu.Unlock()
2473 return ch
2474}
2475
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002476func (w *responseWriter) Header() http.Header {
Brad Fitzpatrick729bd722014-11-13 14:09:36 -08002477 rws := w.rws
2478 if rws == nil {
2479 panic("Header called after Handler finished")
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002480 }
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002481 if rws.handlerHeader == nil {
2482 rws.handlerHeader = make(http.Header)
Brad Fitzpatrick729bd722014-11-13 14:09:36 -08002483 }
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002484 return rws.handlerHeader
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002485}
2486
2487func (w *responseWriter) WriteHeader(code int) {
Brad Fitzpatrick729bd722014-11-13 14:09:36 -08002488 rws := w.rws
2489 if rws == nil {
2490 panic("WriteHeader called after Handler finished")
2491 }
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002492 rws.writeHeader(code)
2493}
2494
2495func (rws *responseWriterState) writeHeader(code int) {
2496 if !rws.wroteHeader {
2497 rws.wroteHeader = true
2498 rws.status = code
2499 if len(rws.handlerHeader) > 0 {
2500 rws.snapHeader = cloneHeader(rws.handlerHeader)
2501 }
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002502 }
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002503}
2504
2505func cloneHeader(h http.Header) http.Header {
2506 h2 := make(http.Header, len(h))
2507 for k, vv := range h {
2508 vv2 := make([]string, len(vv))
2509 copy(vv2, vv)
2510 h2[k] = vv2
2511 }
2512 return h2
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002513}
2514
Brad Fitzpatrick15a4bf32014-11-14 10:56:12 -08002515// The Life Of A Write is like this:
2516//
Brad Fitzpatricked26b482014-11-26 09:16:43 -08002517// * Handler calls w.Write or w.WriteString ->
2518// * -> rws.bw (*bufio.Writer) ->
Brad Fitzpatrickfe686d42017-06-18 05:18:41 +00002519// * (Handler might call Flush)
Brad Fitzpatricked26b482014-11-26 09:16:43 -08002520// * -> chunkWriter{rws}
2521// * -> responseWriterState.writeChunk(p []byte)
2522// * -> responseWriterState.writeChunk (most of the magic; see comment there)
Brad Fitzpatrick15a4bf32014-11-14 10:56:12 -08002523func (w *responseWriter) Write(p []byte) (n int, err error) {
2524 return w.write(len(p), p, "")
Brad Fitzpatrick729bd722014-11-13 14:09:36 -08002525}
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002526
Brad Fitzpatrick15a4bf32014-11-14 10:56:12 -08002527func (w *responseWriter) WriteString(s string) (n int, err error) {
2528 return w.write(len(s), nil, s)
2529}
2530
2531// either dataB or dataS is non-zero.
2532func (w *responseWriter) write(lenData int, dataB []byte, dataS string) (n int, err error) {
Brad Fitzpatrick729bd722014-11-13 14:09:36 -08002533 rws := w.rws
2534 if rws == nil {
2535 panic("Write called after Handler finished")
2536 }
Brad Fitzpatrick520123b2014-11-14 15:57:37 -08002537 if !rws.wroteHeader {
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002538 w.WriteHeader(200)
2539 }
Brad Fitzpatrickc745c362015-11-24 17:14:16 -08002540 if !bodyAllowedForStatus(rws.status) {
2541 return 0, http.ErrBodyNotAllowed
2542 }
2543 rws.wroteBytes += int64(len(dataB)) + int64(len(dataS)) // only one can be set
2544 if rws.sentContentLen != 0 && rws.wroteBytes > rws.sentContentLen {
2545 // TODO: send a RST_STREAM
2546 return 0, errors.New("http2: handler wrote more than declared Content-Length")
2547 }
2548
Brad Fitzpatrick15a4bf32014-11-14 10:56:12 -08002549 if dataB != nil {
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002550 return rws.bw.Write(dataB)
Brad Fitzpatrick15a4bf32014-11-14 10:56:12 -08002551 } else {
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002552 return rws.bw.WriteString(dataS)
Brad Fitzpatrick15a4bf32014-11-14 10:56:12 -08002553 }
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002554}
2555
2556func (w *responseWriter) handlerDone() {
Brad Fitzpatrick729bd722014-11-13 14:09:36 -08002557 rws := w.rws
Brad Fitzpatrickfe686d42017-06-18 05:18:41 +00002558 dirty := rws.dirty
Brad Fitzpatrick520123b2014-11-14 15:57:37 -08002559 rws.handlerDone = true
2560 w.Flush()
Brad Fitzpatrick729bd722014-11-13 14:09:36 -08002561 w.rws = nil
Brad Fitzpatrickfe686d42017-06-18 05:18:41 +00002562 if !dirty {
2563 // Only recycle the pool if all prior Write calls to
2564 // the serverConn goroutine completed successfully. If
2565 // they returned earlier due to resets from the peer
2566 // there might still be write goroutines outstanding
2567 // from the serverConn referencing the rws memory. See
2568 // issue 20704.
2569 responseWriterStatePool.Put(rws)
2570 }
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002571}
Blake Mizeranyb4be4942015-12-15 17:33:14 -08002572
Tom Berganc46f2652016-10-25 10:13:20 -07002573// Push errors.
2574var (
2575 ErrRecursivePush = errors.New("http2: recursive push not allowed")
2576 ErrPushLimitReached = errors.New("http2: push would exceed peer's SETTINGS_MAX_CONCURRENT_STREAMS")
2577)
2578
2579// pushOptions is the internal version of http.PushOptions, which we
2580// cannot include here because it's only defined in Go 1.8 and later.
2581type pushOptions struct {
2582 Method string
2583 Header http.Header
2584}
2585
2586func (w *responseWriter) push(target string, opts pushOptions) error {
2587 st := w.rws.stream
2588 sc := st.sc
2589 sc.serveG.checkNotOn()
2590
2591 // No recursive pushes: "PUSH_PROMISE frames MUST only be sent on a peer-initiated stream."
2592 // http://tools.ietf.org/html/rfc7540#section-6.6
2593 if st.isPushed() {
2594 return ErrRecursivePush
2595 }
2596
2597 // Default options.
2598 if opts.Method == "" {
2599 opts.Method = "GET"
2600 }
2601 if opts.Header == nil {
2602 opts.Header = http.Header{}
2603 }
2604 wantScheme := "http"
2605 if w.rws.req.TLS != nil {
2606 wantScheme = "https"
2607 }
2608
2609 // Validate the request.
2610 u, err := url.Parse(target)
2611 if err != nil {
2612 return err
2613 }
2614 if u.Scheme == "" {
2615 if !strings.HasPrefix(target, "/") {
2616 return fmt.Errorf("target must be an absolute URL or an absolute path: %q", target)
2617 }
2618 u.Scheme = wantScheme
2619 u.Host = w.rws.req.Host
2620 } else {
2621 if u.Scheme != wantScheme {
2622 return fmt.Errorf("cannot push URL with scheme %q from request with scheme %q", u.Scheme, wantScheme)
2623 }
2624 if u.Host == "" {
2625 return errors.New("URL must have a host")
2626 }
2627 }
2628 for k := range opts.Header {
2629 if strings.HasPrefix(k, ":") {
Mikio Hara1c5acb22016-11-16 13:55:47 +09002630 return fmt.Errorf("promised request headers cannot include pseudo header %q", k)
Tom Berganc46f2652016-10-25 10:13:20 -07002631 }
2632 // These headers are meaningful only if the request has a body,
2633 // but PUSH_PROMISE requests cannot have a body.
2634 // http://tools.ietf.org/html/rfc7540#section-8.2
2635 // Also disallow Host, since the promised URL must be absolute.
2636 switch strings.ToLower(k) {
2637 case "content-length", "content-encoding", "trailer", "te", "expect", "host":
2638 return fmt.Errorf("promised request headers cannot include %q", k)
2639 }
2640 }
2641 if err := checkValidHTTP2RequestHeaders(opts.Header); err != nil {
2642 return err
2643 }
2644
2645 // The RFC effectively limits promised requests to GET and HEAD:
2646 // "Promised requests MUST be cacheable [GET, HEAD, or POST], and MUST be safe [GET or HEAD]"
2647 // http://tools.ietf.org/html/rfc7540#section-8.2
2648 if opts.Method != "GET" && opts.Method != "HEAD" {
2649 return fmt.Errorf("method %q must be GET or HEAD", opts.Method)
2650 }
2651
Brad Fitzpatrick34057062017-05-09 12:22:37 -07002652 msg := &startPushRequest{
Tom Berganc46f2652016-10-25 10:13:20 -07002653 parent: st,
2654 method: opts.Method,
2655 url: u,
2656 header: cloneHeader(opts.Header),
2657 done: errChanPool.Get().(chan error),
2658 }
2659
2660 select {
2661 case <-sc.doneServing:
2662 return errClientDisconnected
2663 case <-st.cw:
2664 return errStreamClosed
Brad Fitzpatrick34057062017-05-09 12:22:37 -07002665 case sc.serveMsgCh <- msg:
Tom Berganc46f2652016-10-25 10:13:20 -07002666 }
2667
2668 select {
2669 case <-sc.doneServing:
2670 return errClientDisconnected
2671 case <-st.cw:
2672 return errStreamClosed
2673 case err := <-msg.done:
2674 errChanPool.Put(msg.done)
2675 return err
2676 }
2677}
2678
2679type startPushRequest struct {
2680 parent *stream
2681 method string
2682 url *url.URL
2683 header http.Header
2684 done chan error
2685}
2686
Brad Fitzpatrick34057062017-05-09 12:22:37 -07002687func (sc *serverConn) startPush(msg *startPushRequest) {
Tom Berganc46f2652016-10-25 10:13:20 -07002688 sc.serveG.check()
2689
2690 // http://tools.ietf.org/html/rfc7540#section-6.6.
2691 // PUSH_PROMISE frames MUST only be sent on a peer-initiated stream that
2692 // is in either the "open" or "half-closed (remote)" state.
2693 if msg.parent.state != stateOpen && msg.parent.state != stateHalfClosedRemote {
2694 // responseWriter.Push checks that the stream is peer-initiaed.
2695 msg.done <- errStreamClosed
2696 return
2697 }
2698
2699 // http://tools.ietf.org/html/rfc7540#section-6.6.
2700 if !sc.pushEnabled {
2701 msg.done <- http.ErrNotSupported
2702 return
2703 }
2704
2705 // PUSH_PROMISE frames must be sent in increasing order by stream ID, so
2706 // we allocate an ID for the promised stream lazily, when the PUSH_PROMISE
2707 // is written. Once the ID is allocated, we start the request handler.
2708 allocatePromisedID := func() (uint32, error) {
2709 sc.serveG.check()
2710
2711 // Check this again, just in case. Technically, we might have received
2712 // an updated SETTINGS by the time we got around to writing this frame.
2713 if !sc.pushEnabled {
2714 return 0, http.ErrNotSupported
2715 }
2716 // http://tools.ietf.org/html/rfc7540#section-6.5.2.
2717 if sc.curPushedStreams+1 > sc.clientMaxStreams {
2718 return 0, ErrPushLimitReached
2719 }
2720
2721 // http://tools.ietf.org/html/rfc7540#section-5.1.1.
2722 // Streams initiated by the server MUST use even-numbered identifiers.
Tom Bergan40d30342016-11-01 14:56:08 -07002723 // A server that is unable to establish a new stream identifier can send a GOAWAY
2724 // frame so that the client is forced to open a new connection for new streams.
2725 if sc.maxPushPromiseID+2 >= 1<<31 {
Tom Bergana8e8f922017-05-15 12:29:23 -07002726 sc.startGracefulShutdownInternal()
Tom Bergan40d30342016-11-01 14:56:08 -07002727 return 0, ErrPushLimitReached
2728 }
Tom Berganc46f2652016-10-25 10:13:20 -07002729 sc.maxPushPromiseID += 2
2730 promisedID := sc.maxPushPromiseID
2731
2732 // http://tools.ietf.org/html/rfc7540#section-8.2.
2733 // Strictly speaking, the new stream should start in "reserved (local)", then
2734 // transition to "half closed (remote)" after sending the initial HEADERS, but
2735 // we start in "half closed (remote)" for simplicity.
2736 // See further comments at the definition of stateHalfClosedRemote.
2737 promised := sc.newStream(promisedID, msg.parent.id, stateHalfClosedRemote)
2738 rw, req, err := sc.newWriterAndRequestNoBody(promised, requestParam{
2739 method: msg.method,
2740 scheme: msg.url.Scheme,
2741 authority: msg.url.Host,
2742 path: msg.url.RequestURI(),
Tom Bergan1195a052016-12-15 09:58:54 -08002743 header: cloneHeader(msg.header), // clone since handler runs concurrently with writing the PUSH_PROMISE
Tom Berganc46f2652016-10-25 10:13:20 -07002744 })
2745 if err != nil {
2746 // Should not happen, since we've already validated msg.url.
2747 panic(fmt.Sprintf("newWriterAndRequestNoBody(%+v): %v", msg.url, err))
2748 }
2749
2750 go sc.runHandler(rw, req, sc.handler.ServeHTTP)
2751 return promisedID, nil
2752 }
2753
2754 sc.writeFrame(FrameWriteRequest{
2755 write: &writePushPromise{
2756 streamID: msg.parent.id,
2757 method: msg.method,
2758 url: msg.url,
2759 h: msg.header,
2760 allocatePromisedID: allocatePromisedID,
2761 },
2762 stream: msg.parent,
2763 done: msg.done,
2764 })
2765}
2766
Blake Mizeranyb4be4942015-12-15 17:33:14 -08002767// foreachHeaderElement splits v according to the "#rule" construction
2768// in RFC 2616 section 2.1 and calls fn for each non-empty element.
2769func foreachHeaderElement(v string, fn func(string)) {
2770 v = textproto.TrimString(v)
2771 if v == "" {
2772 return
2773 }
2774 if !strings.Contains(v, ",") {
2775 fn(v)
2776 return
2777 }
2778 for _, f := range strings.Split(v, ",") {
2779 if f = textproto.TrimString(f); f != "" {
2780 fn(f)
2781 }
2782 }
2783}
Brad Fitzpatrickaf4fee92016-04-05 16:55:11 +00002784
2785// From http://httpwg.org/specs/rfc7540.html#rfc.section.8.1.2.2
2786var connHeaders = []string{
2787 "Connection",
2788 "Keep-Alive",
2789 "Proxy-Connection",
2790 "Transfer-Encoding",
2791 "Upgrade",
2792}
2793
Tom Berganc46f2652016-10-25 10:13:20 -07002794// checkValidHTTP2RequestHeaders checks whether h is a valid HTTP/2 request,
Brad Fitzpatrickaf4fee92016-04-05 16:55:11 +00002795// per RFC 7540 Section 8.1.2.2.
2796// The returned error is reported to users.
Tom Berganc46f2652016-10-25 10:13:20 -07002797func checkValidHTTP2RequestHeaders(h http.Header) error {
2798 for _, k := range connHeaders {
2799 if _, ok := h[k]; ok {
2800 return fmt.Errorf("request header %q is not valid in HTTP/2", k)
Brad Fitzpatrickaf4fee92016-04-05 16:55:11 +00002801 }
2802 }
Tom Berganc46f2652016-10-25 10:13:20 -07002803 te := h["Te"]
Brad Fitzpatrickaf4fee92016-04-05 16:55:11 +00002804 if len(te) > 0 && (len(te) > 1 || (te[0] != "trailers" && te[0] != "")) {
2805 return errors.New(`request header "TE" may only be "trailers" in HTTP/2`)
2806 }
2807 return nil
2808}
2809
2810func new400Handler(err error) http.HandlerFunc {
2811 return func(w http.ResponseWriter, r *http.Request) {
2812 http.Error(w, err.Error(), http.StatusBadRequest)
2813 }
2814}
Brad Fitzpatrick3c5cb152016-05-19 01:21:59 +00002815
2816// ValidTrailerHeader reports whether name is a valid header field name to appear
2817// in trailers.
2818// See: http://tools.ietf.org/html/rfc7230#section-4.1.2
2819func ValidTrailerHeader(name string) bool {
2820 name = http.CanonicalHeaderKey(name)
2821 if strings.HasPrefix(name, "If-") || badTrailer[name] {
2822 return false
2823 }
2824 return true
2825}
2826
2827var badTrailer = map[string]bool{
2828 "Authorization": true,
2829 "Cache-Control": true,
2830 "Connection": true,
2831 "Content-Encoding": true,
2832 "Content-Length": true,
2833 "Content-Range": true,
2834 "Content-Type": true,
2835 "Expect": true,
2836 "Host": true,
2837 "Keep-Alive": true,
2838 "Max-Forwards": true,
2839 "Pragma": true,
2840 "Proxy-Authenticate": true,
2841 "Proxy-Authorization": true,
2842 "Proxy-Connection": true,
2843 "Range": true,
2844 "Realm": true,
2845 "Te": true,
2846 "Trailer": true,
2847 "Transfer-Encoding": true,
2848 "Www-Authenticate": true,
2849}
Brad Fitzpatrick541150a2016-10-31 06:24:04 +00002850
Brad Fitzpatrick6dfeb342016-11-11 23:53:59 +00002851// h1ServerKeepAlivesDisabled reports whether hs has its keep-alives
2852// disabled. See comments on h1ServerShutdownChan above for why
2853// the code is written this way.
2854func h1ServerKeepAlivesDisabled(hs *http.Server) bool {
2855 var x interface{} = hs
2856 type I interface {
2857 doKeepAlives() bool
2858 }
2859 if hs, ok := x.(I); ok {
2860 return !hs.doKeepAlives()
2861 }
2862 return false
2863}