blob: 6f4c2bb7cd9c548ae71ebb208483ff41a1e2f17a [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 Fitzpatrick2b459472014-11-30 19:18:57 -08005// TODO: replace all <-sc.doneServing with reads from the stream's cw
6// instead, and make sure that on close we close all open
7// streams. then remove doneServing?
8
Brad Fitzpatrickf530c4e2016-01-07 08:16:00 -08009// TODO: re-audit GOAWAY support. Consider each incoming frame type and
10// whether it should be ignored during graceful shutdown.
Brad Fitzpatrickcf896632014-12-09 07:15:26 +110011
12// TODO: disconnect idle clients. GFE seems to do 4 minutes. make
13// configurable? or maximum number of idle clients and remove the
14// oldest?
15
16// TODO: turn off the serve goroutine when idle, so
17// an idle conn only has the readFrames goroutine active. (which could
18// also be optimized probably to pin less memory in crypto/tls). This
19// would involve tracking when the serve goroutine is active (atomic
20// int32 read/CAS probably?) and starting it up when frames arrive,
21// and shutting it down when all handlers exit. the occasional PING
22// packets could use time.AfterFunc to call sc.wakeStartServeLoop()
23// (which is a no-op if already running) and then queue the PING write
24// as normal. The serve loop would then exit in most cases (if no
25// Handlers running) and not be woken up again until the PING packet
26// returns.
27
28// TODO (maybe): add a mechanism for Handlers to going into
29// half-closed-local mode (rw.(io.Closer) test?) but not exit their
30// handler, and continue to be able to read from the
31// Request.Body. This would be a somewhat semantic change from HTTP/1
32// (or at least what we expose in net/http), so I'd probably want to
33// add it there too. For now, this package says that returning from
34// the Handler ServeHTTP function means you're both done reading and
35// done writing, without a way to stop just one or the other.
36
Brad Fitzpatrickb331b812014-11-13 11:51:54 -080037package http2
38
39import (
Brad Fitzpatrick390047e2014-11-14 20:37:08 -080040 "bufio"
Brad Fitzpatrickb331b812014-11-13 11:51:54 -080041 "bytes"
42 "crypto/tls"
43 "errors"
44 "fmt"
45 "io"
46 "log"
47 "net"
48 "net/http"
Blake Mizeranyb4be4942015-12-15 17:33:14 -080049 "net/textproto"
Brad Fitzpatrickb331b812014-11-13 11:51:54 -080050 "net/url"
Brad Fitzpatrickeb066e32016-01-26 18:31:02 +000051 "os"
52 "reflect"
Brad Fitzpatrick74bd44b2015-12-15 00:47:28 +000053 "runtime"
Brad Fitzpatrickd513e582016-01-31 06:24:40 +000054 "sort"
Brad Fitzpatrickb331b812014-11-13 11:51:54 -080055 "strconv"
56 "strings"
Brad Fitzpatrick729bd722014-11-13 14:09:36 -080057 "sync"
Brad Fitzpatrick95842032014-11-15 09:47:42 -080058 "time"
Brad Fitzpatrickb331b812014-11-13 11:51:54 -080059
Brad Fitzpatrickae54c552015-09-24 09:19:02 +020060 "golang.org/x/net/http2/hpack"
Brad Fitzpatrickb331b812014-11-13 11:51:54 -080061)
62
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -080063const (
Brad Fitzpatrick9581fe12014-11-28 13:51:46 -080064 prefaceTimeout = 10 * time.Second
Brad Fitzpatrick4e3c9222014-11-22 17:35:09 -080065 firstSettingsTimeout = 2 * time.Second // should be in-flight with preface anyway
66 handlerChunkWriteSize = 4 << 10
Brad Fitzpatrick068d35d2014-12-09 07:10:31 +110067 defaultMaxStreams = 250 // TODO: make this 100 as the GFE seems to?
Brad Fitzpatrick4e3c9222014-11-22 17:35:09 -080068)
69
70var (
71 errClientDisconnected = errors.New("client disconnected")
72 errClosedBody = errors.New("body closed by handler")
Brad Fitzpatrickb7f5d982015-10-26 13:59:20 -050073 errHandlerComplete = errors.New("http2: request body closed due to handler exiting")
Brad Fitzpatrick56401052015-10-20 22:27:39 +000074 errStreamClosed = errors.New("http2: stream closed")
Brad Fitzpatrick4e3c9222014-11-22 17:35:09 -080075)
76
77var responseWriterStatePool = sync.Pool{
78 New: func() interface{} {
79 rws := &responseWriterState{}
80 rws.bw = bufio.NewWriterSize(chunkWriter{rws}, handlerChunkWriteSize)
81 return rws
82 },
83}
84
85// Test hooks.
86var (
87 testHookOnConn func()
88 testHookGetServerConn func(*serverConn)
Brad Fitzpatrickf3a6d9a2014-12-08 07:53:36 -080089 testHookOnPanicMu *sync.Mutex // nil except in tests
Brad Fitzpatrick996adcb2014-12-08 01:08:19 -080090 testHookOnPanic func(sc *serverConn, panicVal interface{}) (rePanic bool)
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -080091)
92
Brad Fitzpatrickb331b812014-11-13 11:51:54 -080093// Server is an HTTP/2 server.
94type Server struct {
Brad Fitzpatrick6ec17312014-11-23 10:07:07 -080095 // MaxHandlers limits the number of http.Handler ServeHTTP goroutines
96 // which may run at a time over all connections.
97 // Negative or zero no limit.
98 // TODO: implement
99 MaxHandlers int
100
101 // MaxConcurrentStreams optionally specifies the number of
102 // concurrent streams that each client may have open at a
103 // time. This is unrelated to the number of http.Handler goroutines
104 // which may be active globally, which is MaxHandlers.
105 // If zero, MaxConcurrentStreams defaults to at least 100, per
106 // the HTTP/2 spec's recommendations.
107 MaxConcurrentStreams uint32
Brad Fitzpatrick21896bb2014-11-19 16:05:21 -0800108
109 // MaxReadFrameSize optionally specifies the largest frame
110 // this server is willing to read. A valid value is between
Brad Fitzpatrick6ec17312014-11-23 10:07:07 -0800111 // 16k and 16M, inclusive. If zero or otherwise invalid, a
112 // default value is used.
Brad Fitzpatrick21896bb2014-11-19 16:05:21 -0800113 MaxReadFrameSize uint32
Brad Fitzpatricke4cd9ad2015-01-17 18:03:57 -0800114
115 // PermitProhibitedCipherSuites, if true, permits the use of
116 // cipher suites prohibited by the HTTP/2 spec.
117 PermitProhibitedCipherSuites bool
Brad Fitzpatrick21896bb2014-11-19 16:05:21 -0800118}
119
120func (s *Server) maxReadFrameSize() uint32 {
121 if v := s.MaxReadFrameSize; v >= minMaxFrameSize && v <= maxFrameSize {
122 return v
123 }
124 return defaultMaxReadFrameSize
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800125}
126
Brad Fitzpatrick6ec17312014-11-23 10:07:07 -0800127func (s *Server) maxConcurrentStreams() uint32 {
128 if v := s.MaxConcurrentStreams; v > 0 {
129 return v
130 }
131 return defaultMaxStreams
132}
133
Brad Fitzpatrickb5469d22014-11-13 12:17:52 -0800134// ConfigureServer adds HTTP/2 support to a net/http Server.
135//
136// The configuration conf may be nil.
137//
138// ConfigureServer must be called before s begins serving.
Brad Fitzpatrick42ad5082015-10-15 01:02:25 +0000139func ConfigureServer(s *http.Server, conf *Server) error {
Brad Fitzpatrickb5469d22014-11-13 12:17:52 -0800140 if conf == nil {
141 conf = new(Server)
142 }
Brad Fitzpatrick42ad5082015-10-15 01:02:25 +0000143
Brad Fitzpatrickb5469d22014-11-13 12:17:52 -0800144 if s.TLSConfig == nil {
145 s.TLSConfig = new(tls.Config)
Brad Fitzpatrick42ad5082015-10-15 01:02:25 +0000146 } else if s.TLSConfig.CipherSuites != nil {
147 // If they already provided a CipherSuite list, return
148 // an error if it has a bad order or is missing
149 // ECDHE_RSA_WITH_AES_128_GCM_SHA256.
150 const requiredCipher = tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
151 haveRequired := false
152 sawBad := false
153 for i, cs := range s.TLSConfig.CipherSuites {
154 if cs == requiredCipher {
155 haveRequired = true
156 }
157 if isBadCipher(cs) {
158 sawBad = true
159 } else if sawBad {
160 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)
161 }
162 }
163 if !haveRequired {
164 return fmt.Errorf("http2: TLSConfig.CipherSuites is missing HTTP/2-required TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256")
165 }
Brad Fitzpatrickb5469d22014-11-13 12:17:52 -0800166 }
Brad Fitzpatrick5df015f2014-12-08 11:16:59 -0800167
168 // Note: not setting MinVersion to tls.VersionTLS12,
169 // as we don't want to interfere with HTTP/1.1 traffic
170 // on the user's server. We enforce TLS 1.2 later once
171 // we accept a connection. Ideally this should be done
172 // during next-proto selection, but using TLS <1.2 with
173 // HTTP/2 is still the client's bug.
174
Brad Fitzpatrick42ad5082015-10-15 01:02:25 +0000175 s.TLSConfig.PreferServerCipherSuites = true
Brad Fitzpatrick5df015f2014-12-08 11:16:59 -0800176
Brad Fitzpatrickb5469d22014-11-13 12:17:52 -0800177 haveNPN := false
178 for _, p := range s.TLSConfig.NextProtos {
Brad Fitzpatrick36d9a672014-11-26 07:40:15 -0800179 if p == NextProtoTLS {
Brad Fitzpatrickb5469d22014-11-13 12:17:52 -0800180 haveNPN = true
181 break
182 }
183 }
184 if !haveNPN {
Brad Fitzpatrick36d9a672014-11-26 07:40:15 -0800185 s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, NextProtoTLS)
Brad Fitzpatrickb5469d22014-11-13 12:17:52 -0800186 }
Brad Fitzpatrick13dfd892015-03-05 15:57:11 -0800187 // h2-14 is temporary (as of 2015-03-05) while we wait for all browsers
188 // to switch to "h2".
189 s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, "h2-14")
Brad Fitzpatrickb5469d22014-11-13 12:17:52 -0800190
191 if s.TLSNextProto == nil {
192 s.TLSNextProto = map[string]func(*http.Server, *tls.Conn, http.Handler){}
193 }
Brad Fitzpatrick13dfd892015-03-05 15:57:11 -0800194 protoHandler := func(hs *http.Server, c *tls.Conn, h http.Handler) {
Brad Fitzpatrickb5469d22014-11-13 12:17:52 -0800195 if testHookOnConn != nil {
196 testHookOnConn()
197 }
Brad Fitzpatrick6ccd6692016-02-02 14:37:19 -0800198 conf.ServeConn(c, &ServeConnOpts{
199 Handler: h,
200 BaseConfig: hs,
201 })
Brad Fitzpatrickb5469d22014-11-13 12:17:52 -0800202 }
Brad Fitzpatrick13dfd892015-03-05 15:57:11 -0800203 s.TLSNextProto[NextProtoTLS] = protoHandler
204 s.TLSNextProto["h2-14"] = protoHandler // temporary; see above.
Brad Fitzpatrick42ad5082015-10-15 01:02:25 +0000205 return nil
Brad Fitzpatrickb5469d22014-11-13 12:17:52 -0800206}
207
Brad Fitzpatrick6ccd6692016-02-02 14:37:19 -0800208// ServeConnOpts are options for the Server.ServeConn method.
209type ServeConnOpts struct {
210 // BaseConfig optionally sets the base configuration
211 // for values. If nil, defaults are used.
212 BaseConfig *http.Server
213
214 // Handler specifies which handler to use for processing
215 // requests. If nil, BaseConfig.Handler is used. If BaseConfig
216 // or BaseConfig.Handler is nil, http.DefaultServeMux is used.
217 Handler http.Handler
218}
219
220func (o *ServeConnOpts) baseConfig() *http.Server {
221 if o != nil && o.BaseConfig != nil {
222 return o.BaseConfig
223 }
224 return new(http.Server)
225}
226
227func (o *ServeConnOpts) handler() http.Handler {
228 if o != nil {
229 if o.Handler != nil {
230 return o.Handler
231 }
232 if o.BaseConfig != nil && o.BaseConfig.Handler != nil {
233 return o.BaseConfig.Handler
234 }
235 }
236 return http.DefaultServeMux
237}
238
239// ServeConn serves HTTP/2 requests on the provided connection and
240// blocks until the connection is no longer readable.
241//
242// ServeConn starts speaking HTTP/2 assuming that c has not had any
243// reads or writes. It writes its initial settings frame and expects
244// to be able to read the preface and settings frame from the
245// client. If c has a ConnectionState method like a *tls.Conn, the
246// ConnectionState is used to verify the TLS ciphersuite and to set
247// the Request.TLS field in Handlers.
248//
249// ServeConn does not support h2c by itself. Any h2c support must be
250// implemented in terms of providing a suitably-behaving net.Conn.
251//
252// The opts parameter is optional. If nil, default values are used.
253func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) {
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800254 sc := &serverConn{
Brad Fitzpatrick6ccd6692016-02-02 14:37:19 -0800255 srv: s,
256 hs: opts.baseConfig(),
Brad Fitzpatrick2b459472014-11-30 19:18:57 -0800257 conn: c,
Brad Fitzpatrickdf959c22014-12-09 07:20:20 +1100258 remoteAddrStr: c.RemoteAddr().String(),
Brad Fitzpatrick2b459472014-11-30 19:18:57 -0800259 bw: newBufferedWriter(c),
Brad Fitzpatrick6ccd6692016-02-02 14:37:19 -0800260 handler: opts.handler(),
Brad Fitzpatrick2b459472014-11-30 19:18:57 -0800261 streams: make(map[uint32]*stream),
Brad Fitzpatrick271cfc12015-10-12 23:49:56 +0000262 readFrameCh: make(chan readFrameResult),
Brad Fitzpatrick2b459472014-11-30 19:18:57 -0800263 wantWriteFrameCh: make(chan frameWriteMsg, 8),
Brad Fitzpatrick56401052015-10-20 22:27:39 +0000264 wroteFrameCh: make(chan frameWriteResult, 1), // buffered; one send in writeFrameAsync
265 bodyReadCh: make(chan bodyReadMsg), // buffering doesn't matter either way
Brad Fitzpatrick2b459472014-11-30 19:18:57 -0800266 doneServing: make(chan struct{}),
Brad Fitzpatrick6ccd6692016-02-02 14:37:19 -0800267 advMaxStreams: s.maxConcurrentStreams(),
Brad Fitzpatrick2b459472014-11-30 19:18:57 -0800268 writeSched: writeScheduler{
269 maxFrameSize: initialMaxFrameSize,
270 },
Brad Fitzpatrick6ec17312014-11-23 10:07:07 -0800271 initialWindowSize: initialWindowSize,
272 headerTableSize: initialHeaderTableSize,
273 serveG: newGoroutineLock(),
274 pushEnabled: true,
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800275 }
Brad Fitzpatrick98766182014-12-02 10:30:08 -0800276 sc.flow.add(initialWindowSize)
Brad Fitzpatrick068d35d2014-12-09 07:10:31 +1100277 sc.inflow.add(initialWindowSize)
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800278 sc.hpackEncoder = hpack.NewEncoder(&sc.headerWriteBuf)
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +0000279 sc.hpackDecoder = hpack.NewDecoder(initialHeaderTableSize, nil)
Brad Fitzpatrick59e870b2015-10-14 00:12:18 +0000280 sc.hpackDecoder.SetMaxStringLength(sc.maxHeaderStringLen())
Brad Fitzpatrick5e4e2dc2014-11-19 16:49:43 -0800281
282 fr := NewFramer(sc.bw, c)
Brad Fitzpatrick6ccd6692016-02-02 14:37:19 -0800283 fr.SetMaxReadFrameSize(s.maxReadFrameSize())
Brad Fitzpatrick5e4e2dc2014-11-19 16:49:43 -0800284 sc.framer = fr
285
Brad Fitzpatrick6ccd6692016-02-02 14:37:19 -0800286 if tc, ok := c.(connectionStater); ok {
Brad Fitzpatrick30b16812014-12-08 10:10:39 -0800287 sc.tlsState = new(tls.ConnectionState)
288 *sc.tlsState = tc.ConnectionState()
289 // 9.2 Use of TLS Features
290 // An implementation of HTTP/2 over TLS MUST use TLS
291 // 1.2 or higher with the restrictions on feature set
292 // and cipher suite described in this section. Due to
293 // implementation limitations, it might not be
294 // possible to fail TLS negotiation. An endpoint MUST
295 // immediately terminate an HTTP/2 connection that
296 // does not meet the TLS requirements described in
297 // this section with a connection error (Section
298 // 5.4.1) of type INADEQUATE_SECURITY.
299 if sc.tlsState.Version < tls.VersionTLS12 {
Brad Fitzpatrick842bf9f2014-12-08 10:31:57 -0800300 sc.rejectConn(ErrCodeInadequateSecurity, "TLS version too low")
Brad Fitzpatrick30b16812014-12-08 10:10:39 -0800301 return
302 }
Brad Fitzpatrick842bf9f2014-12-08 10:31:57 -0800303
Brad Fitzpatrick842bf9f2014-12-08 10:31:57 -0800304 if sc.tlsState.ServerName == "" {
Brad Fitzpatrickf0f78762015-01-17 12:25:12 -0800305 // Client must use SNI, but we don't enforce that anymore,
306 // since it was causing problems when connecting to bare IP
307 // addresses during development.
308 //
309 // TODO: optionally enforce? Or enforce at the time we receive
310 // a new request, and verify the the ServerName matches the :authority?
311 // But that precludes proxy situations, perhaps.
312 //
313 // So for now, do nothing here again.
Brad Fitzpatrick842bf9f2014-12-08 10:31:57 -0800314 }
315
Brad Fitzpatrick6ccd6692016-02-02 14:37:19 -0800316 if !s.PermitProhibitedCipherSuites && isBadCipher(sc.tlsState.CipherSuite) {
Brad Fitzpatrick5df015f2014-12-08 11:16:59 -0800317 // "Endpoints MAY choose to generate a connection error
318 // (Section 5.4.1) of type INADEQUATE_SECURITY if one of
319 // the prohibited cipher suites are negotiated."
320 //
321 // We choose that. In my opinion, the spec is weak
322 // here. It also says both parties must support at least
323 // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 so there's no
324 // excuses here. If we really must, we could allow an
325 // "AllowInsecureWeakCiphers" option on the server later.
326 // Let's see how it plays out first.
Brad Fitzpatrick36f79342015-01-17 12:24:34 -0800327 sc.rejectConn(ErrCodeInadequateSecurity, fmt.Sprintf("Prohibited TLS 1.2 Cipher Suite: %x", sc.tlsState.CipherSuite))
Brad Fitzpatrick5df015f2014-12-08 11:16:59 -0800328 return
329 }
Brad Fitzpatrick30b16812014-12-08 10:10:39 -0800330 }
331
Brad Fitzpatrick0db6d652014-11-15 15:49:19 -0800332 if hook := testHookGetServerConn; hook != nil {
333 hook(sc)
334 }
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800335 sc.serve()
336}
337
Brad Fitzpatrick5df015f2014-12-08 11:16:59 -0800338// isBadCipher reports whether the cipher is blacklisted by the HTTP/2 spec.
339func isBadCipher(cipher uint16) bool {
340 switch cipher {
341 case tls.TLS_RSA_WITH_RC4_128_SHA,
342 tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
343 tls.TLS_RSA_WITH_AES_128_CBC_SHA,
344 tls.TLS_RSA_WITH_AES_256_CBC_SHA,
345 tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
346 tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
347 tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
348 tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA,
349 tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
350 tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
351 tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
352 // Reject cipher suites from Appendix A.
353 // "This list includes those cipher suites that do not
354 // offer an ephemeral key exchange and those that are
355 // based on the TLS null, stream or block cipher type"
356 return true
357 default:
358 return false
359 }
360}
361
Brad Fitzpatrick842bf9f2014-12-08 10:31:57 -0800362func (sc *serverConn) rejectConn(err ErrCode, debug string) {
Brad Fitzpatrick415f1912015-12-16 20:28:38 +0000363 sc.vlogf("http2: server rejecting conn: %v, %s", err, debug)
Brad Fitzpatrick842bf9f2014-12-08 10:31:57 -0800364 // ignoring errors. hanging up anyway.
365 sc.framer.WriteGoAway(0, err, []byte(debug))
366 sc.bw.Flush()
367 sc.conn.Close()
368}
369
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800370type serverConn struct {
371 // Immutable:
Brad Fitzpatrick21896bb2014-11-19 16:05:21 -0800372 srv *Server
Brad Fitzpatrick520123b2014-11-14 15:57:37 -0800373 hs *http.Server
374 conn net.Conn
Brad Fitzpatrick5e4e2dc2014-11-19 16:49:43 -0800375 bw *bufferedWriter // writing to conn
Brad Fitzpatrick520123b2014-11-14 15:57:37 -0800376 handler http.Handler
377 framer *Framer
378 hpackDecoder *hpack.Decoder
Brad Fitzpatrick56401052015-10-20 22:27:39 +0000379 doneServing chan struct{} // closed when serverConn.serve ends
380 readFrameCh chan readFrameResult // written by serverConn.readFrames
381 wantWriteFrameCh chan frameWriteMsg // from handlers -> serve
382 wroteFrameCh chan frameWriteResult // from writeFrameAsync -> serve, tickles more frame writes
383 bodyReadCh chan bodyReadMsg // from handlers -> serve
384 testHookCh chan func(int) // code to run on the serve loop
385 flow flow // conn-wide (not stream-specific) outbound flow control
386 inflow flow // conn-wide inbound flow control
387 tlsState *tls.ConnectionState // shared by all handlers, like net/http
Brad Fitzpatrickdf959c22014-12-09 07:20:20 +1100388 remoteAddrStr string
Brad Fitzpatrick520123b2014-11-14 15:57:37 -0800389
390 // Everything following is owned by the serve loop; use serveG.check():
Brad Fitzpatrick165c0982014-11-26 08:53:01 -0800391 serveG goroutineLock // used to verify funcs are on serve()
Brad Fitzpatrickbc00c572014-11-17 12:28:01 -0800392 pushEnabled bool
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -0800393 sawFirstSettings bool // got the initial SETTINGS frame after the preface
394 needToSendSettingsAck bool
Brad Fitzpatrick6a9b77b2014-12-03 13:56:36 -0800395 unackedSettings int // how many SETTINGS have we sent without ACKs?
Brad Fitzpatrick6ec17312014-11-23 10:07:07 -0800396 clientMaxStreams uint32 // SETTINGS_MAX_CONCURRENT_STREAMS from client (our PUSH_PROMISE limit)
397 advMaxStreams uint32 // our SETTINGS_MAX_CONCURRENT_STREAMS advertised the client
398 curOpenStreams uint32 // client's number of open streams
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -0800399 maxStreamID uint32 // max ever seen
400 streams map[uint32]*stream
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -0800401 initialWindowSize int32
Brad Fitzpatrickbc00c572014-11-17 12:28:01 -0800402 headerTableSize uint32
Brad Fitzpatrick29704b82015-10-10 18:01:18 -0700403 peerMaxHeaderListSize uint32 // zero means unknown (default)
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -0800404 canonHeader map[string]string // http2-lower-case -> Go-Canonical-Case
Brad Fitzpatrick21896bb2014-11-19 16:05:21 -0800405 req requestParam // non-zero while reading request headers
Brad Fitzpatrickaa524f62014-11-25 10:31:37 -0800406 writingFrame bool // started write goroutine but haven't heard back on wroteFrameCh
407 needsFrameFlush bool // last frame write wasn't a flush
Brad Fitzpatricka13c4a42014-11-27 17:47:29 -0800408 writeSched writeScheduler
409 inGoAway bool // we've started to or sent GOAWAY
410 needToSendGoAway bool // we need to schedule a GOAWAY frame write
Brad Fitzpatrick21896bb2014-11-19 16:05:21 -0800411 goAwayCode ErrCode
Brad Fitzpatrick4e3c9222014-11-22 17:35:09 -0800412 shutdownTimerCh <-chan time.Time // nil until used
413 shutdownTimer *time.Timer // nil until used
Brad Fitzpatrick520123b2014-11-14 15:57:37 -0800414
Brad Fitzpatrick23564bf2014-11-27 19:40:04 -0800415 // Owned by the writeFrameAsync goroutine:
Brad Fitzpatrick520123b2014-11-14 15:57:37 -0800416 headerWriteBuf bytes.Buffer
417 hpackEncoder *hpack.Encoder
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800418}
419
Brad Fitzpatrick59e870b2015-10-14 00:12:18 +0000420func (sc *serverConn) maxHeaderStringLen() int {
421 v := sc.maxHeaderListSize()
422 if uint32(int(v)) == v {
423 return int(v)
424 }
425 // They had a crazy big number for MaxHeaderBytes anyway,
426 // so give them unlimited header lengths:
427 return 0
428}
429
Brad Fitzpatrick29704b82015-10-10 18:01:18 -0700430func (sc *serverConn) maxHeaderListSize() uint32 {
431 n := sc.hs.MaxHeaderBytes
Brad Fitzpatrickd8f3c682015-10-12 20:56:49 +0000432 if n <= 0 {
Brad Fitzpatrick29704b82015-10-10 18:01:18 -0700433 n = http.DefaultMaxHeaderBytes
434 }
435 // http2's count is in a slightly different unit and includes 32 bytes per pair.
436 // So, take the net/http.Server value and pad it up a bit, assuming 10 headers.
437 const perFieldOverhead = 32 // per http2 spec
438 const typicalHeaders = 10 // conservative
439 return uint32(n + typicalHeaders*perFieldOverhead)
440}
441
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800442// requestParam is the state of the next request, initialized over
443// potentially several frames HEADERS + zero or more CONTINUATION
444// frames.
445type requestParam struct {
446 // stream is non-nil if we're reading (HEADER or CONTINUATION)
447 // frames for a request (but not DATA).
448 stream *stream
449 header http.Header
450 method, path string
451 scheme, authority string
Brad Fitzpatrickd8f3c682015-10-12 20:56:49 +0000452 sawRegularHeader bool // saw a non-pseudo header already
453 invalidHeader bool // an invalid header was seen
454 headerListSize int64 // actually uint32, but easier math this way
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800455}
456
Gabriel Aszalos1aa5b312014-11-19 16:56:22 +0000457// stream represents a stream. This is the minimal metadata needed by
Brad Fitzpatrickbd391962014-11-17 18:58:58 -0800458// the serve goroutine. Most of the actual stream state is owned by
459// the http.Handler's goroutine in the responseWriter. Because the
460// responseWriter's responseWriterState is recycled at the end of a
461// handler, this struct intentionally has no pointer to the
462// *responseWriter{,State} itself, as the Handler ending nils out the
463// responseWriter's state field.
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800464type stream struct {
Brad Fitzpatrickbd391962014-11-17 18:58:58 -0800465 // immutable:
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +0000466 sc *serverConn
Brad Fitzpatrickbd391962014-11-17 18:58:58 -0800467 id uint32
Brad Fitzpatrickbd391962014-11-17 18:58:58 -0800468 body *pipe // non-nil if expecting DATA frames
469 cw closeWaiter // closed wait stream transitions to closed state
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800470
Brad Fitzpatrickbd391962014-11-17 18:58:58 -0800471 // owned by serverConn's serve loop:
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +0000472 bodyBytes int64 // body bytes seen so far
473 declBodyBytes int64 // or -1 if undeclared
474 flow flow // limits writing from Handler to client
475 inflow flow // what the client is allowed to POST/etc to us
476 parent *stream // or nil
477 numTrailerValues int64
478 weight uint8
479 state streamState
480 sentReset bool // only true once detached from streams map
481 gotReset bool // only true once detacted from streams map
482 gotTrailerHeader bool // HEADER frame for trailers was seen
483
484 trailer http.Header // accumulated trailers
485 reqTrailer http.Header // handler's Request.Trailer
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800486}
487
Brad Fitzpatrick23564bf2014-11-27 19:40:04 -0800488func (sc *serverConn) Framer() *Framer { return sc.framer }
489func (sc *serverConn) CloseConn() error { return sc.conn.Close() }
490func (sc *serverConn) Flush() error { return sc.bw.Flush() }
491func (sc *serverConn) HeaderEncoder() (*hpack.Encoder, *bytes.Buffer) {
492 return sc.hpackEncoder, &sc.headerWriteBuf
493}
494
Brad Fitzpatricka98415a2014-12-08 00:47:45 -0800495func (sc *serverConn) state(streamID uint32) (streamState, *stream) {
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800496 sc.serveG.check()
497 // http://http2.github.io/http2-spec/#rfc.section.5.1
498 if st, ok := sc.streams[streamID]; ok {
Brad Fitzpatricka98415a2014-12-08 00:47:45 -0800499 return st.state, st
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800500 }
501 // "The first use of a new stream identifier implicitly closes all
502 // streams in the "idle" state that might have been initiated by
503 // that peer with a lower-valued stream identifier. For example, if
504 // a client sends a HEADERS frame on stream 7 without ever sending a
505 // frame on stream 5, then stream 5 transitions to the "closed"
506 // state when the first frame for stream 7 is sent or received."
507 if streamID <= sc.maxStreamID {
Brad Fitzpatricka98415a2014-12-08 00:47:45 -0800508 return stateClosed, nil
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800509 }
Brad Fitzpatricka98415a2014-12-08 00:47:45 -0800510 return stateIdle, nil
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800511}
512
Brad Fitzpatrickcd8c2702015-10-15 20:01:14 +0000513// setConnState calls the net/http ConnState hook for this connection, if configured.
514// Note that the net/http package does StateNew and StateClosed for us.
515// There is currently no plan for StateHijacked or hijacking HTTP/2 connections.
516func (sc *serverConn) setConnState(state http.ConnState) {
517 if sc.hs.ConnState != nil {
518 sc.hs.ConnState(sc.conn, state)
519 }
520}
521
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800522func (sc *serverConn) vlogf(format string, args ...interface{}) {
523 if VerboseLogs {
524 sc.logf(format, args...)
525 }
526}
527
528func (sc *serverConn) logf(format string, args ...interface{}) {
529 if lg := sc.hs.ErrorLog; lg != nil {
530 lg.Printf(format, args...)
531 } else {
532 log.Printf(format, args...)
533 }
534}
535
Brad Fitzpatrickeb066e32016-01-26 18:31:02 +0000536// errno returns v's underlying uintptr, else 0.
537//
538// TODO: remove this helper function once http2 can use build
539// tags. See comment in isClosedConnError.
540func errno(v error) uintptr {
541 if rv := reflect.ValueOf(v); rv.Kind() == reflect.Uintptr {
542 return uintptr(rv.Uint())
543 }
544 return 0
545}
546
547// isClosedConnError reports whether err is an error from use of a closed
548// network connection.
549func isClosedConnError(err error) bool {
550 if err == nil {
551 return false
552 }
553
554 // TODO: remove this string search and be more like the Windows
555 // case below. That might involve modifying the standard library
556 // to return better error types.
557 str := err.Error()
558 if strings.Contains(str, "use of closed network connection") {
559 return true
560 }
561
562 // TODO(bradfitz): x/tools/cmd/bundle doesn't really support
563 // build tags, so I can't make an http2_windows.go file with
564 // Windows-specific stuff. Fix that and move this, once we
565 // have a way to bundle this into std's net/http somehow.
566 if runtime.GOOS == "windows" {
567 if oe, ok := err.(*net.OpError); ok && oe.Op == "read" {
568 if se, ok := oe.Err.(*os.SyscallError); ok && se.Syscall == "wsarecv" {
569 const WSAECONNABORTED = 10053
570 const WSAECONNRESET = 10054
571 if n := errno(se.Err); n == WSAECONNRESET || n == WSAECONNABORTED {
572 return true
573 }
574 }
575 }
576 }
577 return false
578}
579
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800580func (sc *serverConn) condlogf(err error, format string, args ...interface{}) {
581 if err == nil {
582 return
583 }
Brad Fitzpatrickeb066e32016-01-26 18:31:02 +0000584 if err == io.EOF || err == io.ErrUnexpectedEOF || isClosedConnError(err) {
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800585 // Boring, expected errors.
586 sc.vlogf(format, args...)
587 } else {
588 sc.logf(format, args...)
589 }
590}
591
592func (sc *serverConn) onNewHeaderField(f hpack.HeaderField) {
593 sc.serveG.check()
Brad Fitzpatrick415f1912015-12-16 20:28:38 +0000594 if VerboseLogs {
595 sc.vlogf("http2: server decoded %v", f)
596 }
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800597 switch {
Brad Fitzpatrickb2ed34f2016-01-20 20:16:54 +0000598 case !validHeaderFieldValue(f.Value): // f.Name checked _after_ pseudo check, since ':' is invalid
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800599 sc.req.invalidHeader = true
600 case strings.HasPrefix(f.Name, ":"):
601 if sc.req.sawRegularHeader {
602 sc.logf("pseudo-header after regular header")
603 sc.req.invalidHeader = true
604 return
605 }
606 var dst *string
607 switch f.Name {
608 case ":method":
609 dst = &sc.req.method
610 case ":path":
611 dst = &sc.req.path
612 case ":scheme":
613 dst = &sc.req.scheme
614 case ":authority":
615 dst = &sc.req.authority
616 default:
617 // 8.1.2.1 Pseudo-Header Fields
618 // "Endpoints MUST treat a request or response
619 // that contains undefined or invalid
620 // pseudo-header fields as malformed (Section
621 // 8.1.2.6)."
622 sc.logf("invalid pseudo-header %q", f.Name)
623 sc.req.invalidHeader = true
624 return
625 }
626 if *dst != "" {
627 sc.logf("duplicate pseudo-header %q sent", f.Name)
628 sc.req.invalidHeader = true
629 return
630 }
631 *dst = f.Value
Brad Fitzpatrickb2ed34f2016-01-20 20:16:54 +0000632 case !validHeaderFieldName(f.Name):
633 sc.req.invalidHeader = true
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800634 default:
635 sc.req.sawRegularHeader = true
636 sc.req.header.Add(sc.canonicalHeader(f.Name), f.Value)
Brad Fitzpatrickd8f3c682015-10-12 20:56:49 +0000637 const headerFieldOverhead = 32 // per spec
638 sc.req.headerListSize += int64(len(f.Name)) + int64(len(f.Value)) + headerFieldOverhead
639 if sc.req.headerListSize > int64(sc.maxHeaderListSize()) {
640 sc.hpackDecoder.SetEmitEnabled(false)
641 }
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800642 }
643}
644
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +0000645func (st *stream) onNewTrailerField(f hpack.HeaderField) {
646 sc := st.sc
647 sc.serveG.check()
Brad Fitzpatrick415f1912015-12-16 20:28:38 +0000648 if VerboseLogs {
649 sc.vlogf("http2: server decoded trailer %v", f)
650 }
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +0000651 switch {
Brad Fitzpatrickb2ed34f2016-01-20 20:16:54 +0000652 case strings.HasPrefix(f.Name, ":"):
Brad Fitzpatrickf530c4e2016-01-07 08:16:00 -0800653 sc.req.invalidHeader = true
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +0000654 return
Brad Fitzpatrickb2ed34f2016-01-20 20:16:54 +0000655 case !validHeaderFieldName(f.Name) || !validHeaderFieldValue(f.Value):
Brad Fitzpatrickf530c4e2016-01-07 08:16:00 -0800656 sc.req.invalidHeader = true
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +0000657 return
658 default:
659 key := sc.canonicalHeader(f.Name)
660 if st.trailer != nil {
661 vv := append(st.trailer[key], f.Value)
662 st.trailer[key] = vv
663
664 // arbitrary; TODO: read spec about header list size limits wrt trailers
665 const tooBig = 1000
666 if len(vv) >= tooBig {
667 sc.hpackDecoder.SetEmitEnabled(false)
668 }
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +0000669 }
670 }
671}
672
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800673func (sc *serverConn) canonicalHeader(v string) string {
674 sc.serveG.check()
Brad Fitzpatrick6520e262014-11-15 09:36:47 -0800675 cv, ok := commonCanonHeader[v]
676 if ok {
677 return cv
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800678 }
Brad Fitzpatrick6520e262014-11-15 09:36:47 -0800679 cv, ok = sc.canonHeader[v]
680 if ok {
681 return cv
682 }
683 if sc.canonHeader == nil {
684 sc.canonHeader = make(map[string]string)
685 }
686 cv = http.CanonicalHeaderKey(v)
687 sc.canonHeader[v] = cv
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800688 return cv
689}
690
Brad Fitzpatrick271cfc12015-10-12 23:49:56 +0000691type readFrameResult struct {
692 f Frame // valid until readMore is called
693 err error
694
695 // readMore should be called once the consumer no longer needs or
696 // retains f. After readMore, f is invalid and more frames can be
697 // read.
698 readMore func()
699}
700
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800701// readFrames is the loop that reads incoming frames.
Brad Fitzpatrick271cfc12015-10-12 23:49:56 +0000702// It takes care to only read one frame at a time, blocking until the
703// consumer is done with the frame.
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800704// It's run on its own goroutine.
705func (sc *serverConn) readFrames() {
Brad Fitzpatrick271cfc12015-10-12 23:49:56 +0000706 gate := make(gate)
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800707 for {
708 f, err := sc.framer.ReadFrame()
Brad Fitzpatrick271cfc12015-10-12 23:49:56 +0000709 select {
710 case sc.readFrameCh <- readFrameResult{f, err, gate.Done}:
711 case <-sc.doneServing:
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800712 return
713 }
Brad Fitzpatrick271cfc12015-10-12 23:49:56 +0000714 select {
715 case <-gate:
716 case <-sc.doneServing:
717 return
718 }
Brad Fitzpatrickea6dba82015-12-23 08:43:06 -0800719 if terminalReadFrameError(err) {
720 return
721 }
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800722 }
723}
724
Brad Fitzpatrick56401052015-10-20 22:27:39 +0000725// frameWriteResult is the message passed from writeFrameAsync to the serve goroutine.
726type frameWriteResult struct {
727 wm frameWriteMsg // what was written (or attempted)
728 err error // result of the writeFrame call
729}
730
Brad Fitzpatrickaa524f62014-11-25 10:31:37 -0800731// writeFrameAsync runs in its own goroutine and writes a single frame
732// and then reports when it's done.
733// At most one goroutine can be running writeFrameAsync at a time per
734// serverConn.
735func (sc *serverConn) writeFrameAsync(wm frameWriteMsg) {
Brad Fitzpatrickf16a0b32014-11-28 13:49:30 -0800736 err := wm.write.writeFrame(sc)
Brad Fitzpatrick56401052015-10-20 22:27:39 +0000737 sc.wroteFrameCh <- frameWriteResult{wm, err}
Brad Fitzpatrick520123b2014-11-14 15:57:37 -0800738}
739
Brad Fitzpatrick9b41faf2014-11-19 10:45:13 -0800740func (sc *serverConn) closeAllStreamsOnConnClose() {
Brad Fitzpatrick6d3aa4f2014-11-15 14:55:57 -0800741 sc.serveG.check()
Brad Fitzpatrickbd391962014-11-17 18:58:58 -0800742 for _, st := range sc.streams {
743 sc.closeStream(st, errClientDisconnected)
Brad Fitzpatrick6d3aa4f2014-11-15 14:55:57 -0800744 }
745}
746
Brad Fitzpatrick21896bb2014-11-19 16:05:21 -0800747func (sc *serverConn) stopShutdownTimer() {
748 sc.serveG.check()
749 if t := sc.shutdownTimer; t != nil {
750 t.Stop()
751 }
752}
753
Brad Fitzpatrick996adcb2014-12-08 01:08:19 -0800754func (sc *serverConn) notePanic() {
Brad Fitzpatrick74bd44b2015-12-15 00:47:28 +0000755 // Note: this is for serverConn.serve panicking, not http.Handler code.
Brad Fitzpatrickf3a6d9a2014-12-08 07:53:36 -0800756 if testHookOnPanicMu != nil {
757 testHookOnPanicMu.Lock()
758 defer testHookOnPanicMu.Unlock()
759 }
Brad Fitzpatrick996adcb2014-12-08 01:08:19 -0800760 if testHookOnPanic != nil {
761 if e := recover(); e != nil {
762 if testHookOnPanic(sc, e) {
763 panic(e)
764 }
765 }
766 }
767}
768
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800769func (sc *serverConn) serve() {
770 sc.serveG.check()
Brad Fitzpatrick996adcb2014-12-08 01:08:19 -0800771 defer sc.notePanic()
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800772 defer sc.conn.Close()
Brad Fitzpatrick9b41faf2014-11-19 10:45:13 -0800773 defer sc.closeAllStreamsOnConnClose()
Brad Fitzpatrick21896bb2014-11-19 16:05:21 -0800774 defer sc.stopShutdownTimer()
Brad Fitzpatrickaa524f62014-11-25 10:31:37 -0800775 defer close(sc.doneServing) // unblocks handlers trying to send
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800776
Brad Fitzpatrick415f1912015-12-16 20:28:38 +0000777 if VerboseLogs {
778 sc.vlogf("http2: server connection from %v on %p", sc.conn.RemoteAddr(), sc.hs)
779 }
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800780
Brad Fitzpatrick23564bf2014-11-27 19:40:04 -0800781 sc.writeFrame(frameWriteMsg{
Brad Fitzpatrickf16a0b32014-11-28 13:49:30 -0800782 write: writeSettings{
Brad Fitzpatrick23564bf2014-11-27 19:40:04 -0800783 {SettingMaxFrameSize, sc.srv.maxReadFrameSize()},
784 {SettingMaxConcurrentStreams, sc.advMaxStreams},
Brad Fitzpatrick29704b82015-10-10 18:01:18 -0700785 {SettingMaxHeaderListSize, sc.maxHeaderListSize()},
Brad Fitzpatrick953b5112014-12-06 17:59:01 -0800786
787 // TODO: more actual settings, notably
788 // SettingInitialWindowSize, but then we also
789 // want to bump up the conn window size the
790 // same amount here right after the settings
Brad Fitzpatrick23564bf2014-11-27 19:40:04 -0800791 },
792 })
Brad Fitzpatrick6a9b77b2014-12-03 13:56:36 -0800793 sc.unackedSettings++
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -0800794
795 if err := sc.readPreface(); err != nil {
Brad Fitzpatrick415f1912015-12-16 20:28:38 +0000796 sc.condlogf(err, "http2: server: error reading preface from client %v: %v", sc.conn.RemoteAddr(), err)
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800797 return
798 }
Brad Fitzpatrickcd8c2702015-10-15 20:01:14 +0000799 // Now that we've got the preface, get us out of the
800 // "StateNew" state. We can't go directly to idle, though.
801 // Active means we read some data and anticipate a request. We'll
802 // do another Active when we get a HEADERS frame.
803 sc.setConnState(http.StateActive)
804 sc.setConnState(http.StateIdle)
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800805
Brad Fitzpatrickaa524f62014-11-25 10:31:37 -0800806 go sc.readFrames() // closed by defer sc.conn.Close above
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800807
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -0800808 settingsTimer := time.NewTimer(firstSettingsTimeout)
Brad Fitzpatrickc94bffa2015-10-13 18:18:12 +0000809 loopNum := 0
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800810 for {
Brad Fitzpatrickc94bffa2015-10-13 18:18:12 +0000811 loopNum++
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800812 select {
Brad Fitzpatrick520123b2014-11-14 15:57:37 -0800813 case wm := <-sc.wantWriteFrameCh:
Brad Fitzpatrick4e3c9222014-11-22 17:35:09 -0800814 sc.writeFrame(wm)
Brad Fitzpatrick56401052015-10-20 22:27:39 +0000815 case res := <-sc.wroteFrameCh:
816 sc.wroteFrame(res)
Brad Fitzpatrick271cfc12015-10-12 23:49:56 +0000817 case res := <-sc.readFrameCh:
818 if !sc.processFrameFromReader(res) {
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800819 return
820 }
Brad Fitzpatrick271cfc12015-10-12 23:49:56 +0000821 res.readMore()
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -0800822 if settingsTimer.C != nil {
823 settingsTimer.Stop()
824 settingsTimer.C = nil
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800825 }
Brad Fitzpatrickc8bab6a2014-12-07 18:51:56 -0800826 case m := <-sc.bodyReadCh:
827 sc.noteBodyRead(m.st, m.n)
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -0800828 case <-settingsTimer.C:
829 sc.logf("timeout waiting for SETTINGS frames from %v", sc.conn.RemoteAddr())
830 return
Brad Fitzpatrick21896bb2014-11-19 16:05:21 -0800831 case <-sc.shutdownTimerCh:
832 sc.vlogf("GOAWAY close timer fired; closing conn from %v", sc.conn.RemoteAddr())
833 return
Brad Fitzpatrick0db6d652014-11-15 15:49:19 -0800834 case fn := <-sc.testHookCh:
Brad Fitzpatrickc94bffa2015-10-13 18:18:12 +0000835 fn(loopNum)
Brad Fitzpatrickb331b812014-11-13 11:51:54 -0800836 }
837 }
838}
839
Brad Fitzpatrick95842032014-11-15 09:47:42 -0800840// readPreface reads the ClientPreface greeting from the peer
841// or returns an error on timeout or an invalid greeting.
842func (sc *serverConn) readPreface() error {
843 errc := make(chan error, 1)
844 go func() {
845 // Read the client preface
846 buf := make([]byte, len(ClientPreface))
Brad Fitzpatrick95842032014-11-15 09:47:42 -0800847 if _, err := io.ReadFull(sc.conn, buf); err != nil {
848 errc <- err
849 } else if !bytes.Equal(buf, clientPreface) {
850 errc <- fmt.Errorf("bogus greeting %q", buf)
851 } else {
852 errc <- nil
853 }
854 }()
Brad Fitzpatrick068d35d2014-12-09 07:10:31 +1100855 timer := time.NewTimer(prefaceTimeout) // TODO: configurable on *Server?
Brad Fitzpatrick95842032014-11-15 09:47:42 -0800856 defer timer.Stop()
857 select {
858 case <-timer.C:
859 return errors.New("timeout waiting for client preface")
860 case err := <-errc:
861 if err == nil {
Brad Fitzpatrick415f1912015-12-16 20:28:38 +0000862 if VerboseLogs {
863 sc.vlogf("http2: server: client %v said hello", sc.conn.RemoteAddr())
864 }
Brad Fitzpatrick95842032014-11-15 09:47:42 -0800865 }
866 return err
867 }
868}
869
Brad Fitzpatrickc94bffa2015-10-13 18:18:12 +0000870var errChanPool = sync.Pool{
871 New: func() interface{} { return make(chan error, 1) },
872}
873
Brad Fitzpatrickc95266f2015-10-29 12:35:12 -0700874var writeDataPool = sync.Pool{
875 New: func() interface{} { return new(writeData) },
876}
877
878// writeDataFromHandler writes DATA response frames from a handler on
879// the given stream.
880func (sc *serverConn) writeDataFromHandler(stream *stream, data []byte, endStream bool) error {
Brad Fitzpatrickc94bffa2015-10-13 18:18:12 +0000881 ch := errChanPool.Get().(chan error)
Brad Fitzpatrickc95266f2015-10-29 12:35:12 -0700882 writeArg := writeDataPool.Get().(*writeData)
883 *writeArg = writeData{stream.id, data, endStream}
Brad Fitzpatrick56401052015-10-20 22:27:39 +0000884 err := sc.writeFrameFromHandler(frameWriteMsg{
Brad Fitzpatrickc95266f2015-10-29 12:35:12 -0700885 write: writeArg,
Brad Fitzpatrickf16a0b32014-11-28 13:49:30 -0800886 stream: stream,
887 done: ch,
Brad Fitzpatrickdc0c5c02014-11-20 14:15:26 -0800888 })
Brad Fitzpatrick56401052015-10-20 22:27:39 +0000889 if err != nil {
Brad Fitzpatrickdc0c5c02014-11-20 14:15:26 -0800890 return err
Brad Fitzpatrick56401052015-10-20 22:27:39 +0000891 }
Brad Fitzpatrickc95266f2015-10-29 12:35:12 -0700892 var frameWriteDone bool // the frame write is done (successfully or not)
Brad Fitzpatrick56401052015-10-20 22:27:39 +0000893 select {
894 case err = <-ch:
Brad Fitzpatrickc95266f2015-10-29 12:35:12 -0700895 frameWriteDone = true
Brad Fitzpatrickdc0c5c02014-11-20 14:15:26 -0800896 case <-sc.doneServing:
897 return errClientDisconnected
Brad Fitzpatrick2b459472014-11-30 19:18:57 -0800898 case <-stream.cw:
Brad Fitzpatrick56401052015-10-20 22:27:39 +0000899 // If both ch and stream.cw were ready (as might
900 // happen on the final Write after an http.Handler
901 // ends), prefer the write result. Otherwise this
902 // might just be us successfully closing the stream.
903 // The writeFrameAsync and serve goroutines guarantee
904 // that the ch send will happen before the stream.cw
905 // close.
906 select {
907 case err = <-ch:
Brad Fitzpatrickc95266f2015-10-29 12:35:12 -0700908 frameWriteDone = true
Brad Fitzpatrick56401052015-10-20 22:27:39 +0000909 default:
910 return errStreamClosed
911 }
Brad Fitzpatrickdc0c5c02014-11-20 14:15:26 -0800912 }
Brad Fitzpatrick56401052015-10-20 22:27:39 +0000913 errChanPool.Put(ch)
Brad Fitzpatrickc95266f2015-10-29 12:35:12 -0700914 if frameWriteDone {
915 writeDataPool.Put(writeArg)
916 }
Brad Fitzpatrick56401052015-10-20 22:27:39 +0000917 return err
Brad Fitzpatrickdc0c5c02014-11-20 14:15:26 -0800918}
919
Brad Fitzpatrick4e3c9222014-11-22 17:35:09 -0800920// writeFrameFromHandler sends wm to sc.wantWriteFrameCh, but aborts
921// if the connection has gone away.
Brad Fitzpatrickdc0c5c02014-11-20 14:15:26 -0800922//
923// This must not be run from the serve goroutine itself, else it might
924// deadlock writing to sc.wantWriteFrameCh (which is only mildly
925// buffered and is read by serve itself). If you're on the serve
Brad Fitzpatrick4e3c9222014-11-22 17:35:09 -0800926// goroutine, call writeFrame instead.
Brad Fitzpatrick56401052015-10-20 22:27:39 +0000927func (sc *serverConn) writeFrameFromHandler(wm frameWriteMsg) error {
Brad Fitzpatrick9b41faf2014-11-19 10:45:13 -0800928 sc.serveG.checkNotOn() // NOT
929 select {
930 case sc.wantWriteFrameCh <- wm:
Brad Fitzpatrick56401052015-10-20 22:27:39 +0000931 return nil
Brad Fitzpatrick9b41faf2014-11-19 10:45:13 -0800932 case <-sc.doneServing:
Brad Fitzpatrick56401052015-10-20 22:27:39 +0000933 // Serve loop is gone.
Brad Fitzpatrick9b41faf2014-11-19 10:45:13 -0800934 // Client has closed their connection to the server.
Brad Fitzpatrick56401052015-10-20 22:27:39 +0000935 return errClientDisconnected
Brad Fitzpatrick9b41faf2014-11-19 10:45:13 -0800936 }
Brad Fitzpatricka29a3232014-11-15 11:18:25 -0800937}
938
Brad Fitzpatricka92fa952014-12-02 10:31:34 -0800939// writeFrame schedules a frame to write and sends it if there's nothing
940// already being written.
Brad Fitzpatrickdc0c5c02014-11-20 14:15:26 -0800941//
Brad Fitzpatricka92fa952014-12-02 10:31:34 -0800942// There is no pushback here (the serve goroutine never blocks). It's
943// the http.Handlers that block, waiting for their previous frames to
944// make it onto the wire
945//
946// If you're not on the serve goroutine, use writeFrameFromHandler instead.
Brad Fitzpatrick4e3c9222014-11-22 17:35:09 -0800947func (sc *serverConn) writeFrame(wm frameWriteMsg) {
Brad Fitzpatrick520123b2014-11-14 15:57:37 -0800948 sc.serveG.check()
Brad Fitzpatricka13c4a42014-11-27 17:47:29 -0800949 sc.writeSched.add(wm)
Tatsuhiro Tsujikawacc1e1da2014-12-02 20:04:27 +0900950 sc.scheduleFrameWrite()
Brad Fitzpatrick520123b2014-11-14 15:57:37 -0800951}
952
Brad Fitzpatrick165c0982014-11-26 08:53:01 -0800953// startFrameWrite starts a goroutine to write wm (in a separate
954// goroutine since that might block on the network), and updates the
955// serve goroutine's state about the world, updated from info in wm.
956func (sc *serverConn) startFrameWrite(wm frameWriteMsg) {
Brad Fitzpatrick3d7a3ad2014-11-15 21:38:23 -0800957 sc.serveG.check()
958 if sc.writingFrame {
Brad Fitzpatrick165c0982014-11-26 08:53:01 -0800959 panic("internal error: can only be writing one frame at a time")
Brad Fitzpatrick3d7a3ad2014-11-15 21:38:23 -0800960 }
Brad Fitzpatrickbd391962014-11-17 18:58:58 -0800961
962 st := wm.stream
963 if st != nil {
964 switch st.state {
965 case stateHalfClosedLocal:
966 panic("internal error: attempt to send frame on half-closed-local stream")
967 case stateClosed:
968 if st.sentReset || st.gotReset {
Brad Fitzpatrick56401052015-10-20 22:27:39 +0000969 // Skip this frame.
970 sc.scheduleFrameWrite()
Brad Fitzpatrickbd391962014-11-17 18:58:58 -0800971 return
972 }
Brad Fitzpatricka92fa952014-12-02 10:31:34 -0800973 panic(fmt.Sprintf("internal error: attempt to send a write %v on a closed stream", wm))
Brad Fitzpatrickbd391962014-11-17 18:58:58 -0800974 }
975 }
976
Brad Fitzpatrick56401052015-10-20 22:27:39 +0000977 sc.writingFrame = true
Brad Fitzpatrick5e4e2dc2014-11-19 16:49:43 -0800978 sc.needsFrameFlush = true
Brad Fitzpatrick56401052015-10-20 22:27:39 +0000979 go sc.writeFrameAsync(wm)
980}
981
Brad Fitzpatrick74bd44b2015-12-15 00:47:28 +0000982// errHandlerPanicked is the error given to any callers blocked in a read from
983// Request.Body when the main goroutine panics. Since most handlers read in the
984// the main ServeHTTP goroutine, this will show up rarely.
985var errHandlerPanicked = errors.New("http2: handler panicked")
986
Brad Fitzpatrick56401052015-10-20 22:27:39 +0000987// wroteFrame is called on the serve goroutine with the result of
988// whatever happened on writeFrameAsync.
989func (sc *serverConn) wroteFrame(res frameWriteResult) {
990 sc.serveG.check()
991 if !sc.writingFrame {
992 panic("internal error: expected to be already writing a frame")
993 }
994 sc.writingFrame = false
995
996 wm := res.wm
997 st := wm.stream
998
999 closeStream := endsStream(wm.write)
1000
Brad Fitzpatrick74bd44b2015-12-15 00:47:28 +00001001 if _, ok := wm.write.(handlerPanicRST); ok {
1002 sc.closeStream(st, errHandlerPanicked)
1003 }
1004
Brad Fitzpatrick56401052015-10-20 22:27:39 +00001005 // Reply (if requested) to the blocked ServeHTTP goroutine.
1006 if ch := wm.done; ch != nil {
1007 select {
1008 case ch <- res.err:
1009 default:
1010 panic(fmt.Sprintf("unbuffered done channel passed in for type %T", wm.write))
1011 }
1012 }
1013 wm.write = nil // prevent use (assume it's tainted after wm.done send)
1014
1015 if closeStream {
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08001016 if st == nil {
Brad Fitzpatrickf16a0b32014-11-28 13:49:30 -08001017 panic("internal error: expecting non-nil stream")
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08001018 }
1019 switch st.state {
1020 case stateOpen:
Brad Fitzpatrickf3a6d9a2014-12-08 07:53:36 -08001021 // Here we would go to stateHalfClosedLocal in
1022 // theory, but since our handler is done and
1023 // the net/http package provides no mechanism
1024 // for finishing writing to a ResponseWriter
1025 // while still reading data (see possible TODO
1026 // at top of this file), we go into closed
1027 // state here anyway, after telling the peer
1028 // we're hanging up on them.
1029 st.state = stateHalfClosedLocal // won't last long, but necessary for closeStream via resetStream
1030 errCancel := StreamError{st.id, ErrCodeCancel}
1031 sc.resetStream(errCancel)
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08001032 case stateHalfClosedRemote:
Brad Fitzpatrickb7f5d982015-10-26 13:59:20 -05001033 sc.closeStream(st, errHandlerComplete)
Brad Fitzpatrick3d7a3ad2014-11-15 21:38:23 -08001034 }
1035 }
Brad Fitzpatrick56401052015-10-20 22:27:39 +00001036
1037 sc.scheduleFrameWrite()
Brad Fitzpatrick3d7a3ad2014-11-15 21:38:23 -08001038}
1039
Brad Fitzpatrick4e3c9222014-11-22 17:35:09 -08001040// scheduleFrameWrite tickles the frame writing scheduler.
1041//
1042// If a frame is already being written, nothing happens. This will be called again
1043// when the frame is done being written.
1044//
1045// If a frame isn't being written we need to send one, the best frame
1046// to send is selected, preferring first things that aren't
1047// stream-specific (e.g. ACKing settings), and then finding the
1048// highest priority stream.
1049//
1050// If a frame isn't being written and there's nothing else to send, we
1051// flush the write buffer.
Brad Fitzpatrick520123b2014-11-14 15:57:37 -08001052func (sc *serverConn) scheduleFrameWrite() {
1053 sc.serveG.check()
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -08001054 if sc.writingFrame {
Brad Fitzpatrick21896bb2014-11-19 16:05:21 -08001055 return
1056 }
1057 if sc.needToSendGoAway {
1058 sc.needToSendGoAway = false
Brad Fitzpatrick165c0982014-11-26 08:53:01 -08001059 sc.startFrameWrite(frameWriteMsg{
Brad Fitzpatrickf16a0b32014-11-28 13:49:30 -08001060 write: &writeGoAway{
Brad Fitzpatrick21896bb2014-11-19 16:05:21 -08001061 maxStreamID: sc.maxStreamID,
1062 code: sc.goAwayCode,
1063 },
1064 })
1065 return
1066 }
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -08001067 if sc.needToSendSettingsAck {
Brad Fitzpatrick4e3c9222014-11-22 17:35:09 -08001068 sc.needToSendSettingsAck = false
Brad Fitzpatrickf16a0b32014-11-28 13:49:30 -08001069 sc.startFrameWrite(frameWriteMsg{write: writeSettingsAck{}})
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -08001070 return
1071 }
Brad Fitzpatrick2b459472014-11-30 19:18:57 -08001072 if !sc.inGoAway {
1073 if wm, ok := sc.writeSched.take(); ok {
1074 sc.startFrameWrite(wm)
1075 return
1076 }
1077 }
1078 if sc.needsFrameFlush {
1079 sc.startFrameWrite(frameWriteMsg{write: flushFrameWriter{}})
1080 sc.needsFrameFlush = false // after startFrameWrite, since it sets this true
Brad Fitzpatrick520123b2014-11-14 15:57:37 -08001081 return
1082 }
Brad Fitzpatrick520123b2014-11-14 15:57:37 -08001083}
1084
Brad Fitzpatrick55815ec2014-11-15 13:29:57 -08001085func (sc *serverConn) goAway(code ErrCode) {
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001086 sc.serveG.check()
Brad Fitzpatrick21896bb2014-11-19 16:05:21 -08001087 if sc.inGoAway {
Brad Fitzpatrick55815ec2014-11-15 13:29:57 -08001088 return
1089 }
Brad Fitzpatrick21896bb2014-11-19 16:05:21 -08001090 if code != ErrCodeNo {
1091 sc.shutDownIn(250 * time.Millisecond)
1092 } else {
1093 // TODO: configurable
1094 sc.shutDownIn(1 * time.Second)
1095 }
1096 sc.inGoAway = true
1097 sc.needToSendGoAway = true
1098 sc.goAwayCode = code
1099 sc.scheduleFrameWrite()
1100}
1101
1102func (sc *serverConn) shutDownIn(d time.Duration) {
1103 sc.serveG.check()
1104 sc.shutdownTimer = time.NewTimer(d)
1105 sc.shutdownTimerCh = sc.shutdownTimer.C
Brad Fitzpatrick55815ec2014-11-15 13:29:57 -08001106}
1107
Brad Fitzpatrick6ec17312014-11-23 10:07:07 -08001108func (sc *serverConn) resetStream(se StreamError) {
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001109 sc.serveG.check()
Brad Fitzpatrickf16a0b32014-11-28 13:49:30 -08001110 sc.writeFrame(frameWriteMsg{write: se})
Brad Fitzpatrickf3a6d9a2014-12-08 07:53:36 -08001111 if st, ok := sc.streams[se.StreamID]; ok {
1112 st.sentReset = true
1113 sc.closeStream(st, se)
1114 }
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001115}
1116
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -08001117// processFrameFromReader processes the serve loop's read from readFrameCh from the
1118// frame-reading goroutine.
1119// processFrameFromReader returns whether the connection should be kept open.
Brad Fitzpatrick271cfc12015-10-12 23:49:56 +00001120func (sc *serverConn) processFrameFromReader(res readFrameResult) bool {
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -08001121 sc.serveG.check()
Brad Fitzpatrick271cfc12015-10-12 23:49:56 +00001122 err := res.err
1123 if err != nil {
Brad Fitzpatrick21896bb2014-11-19 16:05:21 -08001124 if err == ErrFrameTooLarge {
1125 sc.goAway(ErrCodeFrameSize)
1126 return true // goAway will close the loop
1127 }
Brad Fitzpatrickeb066e32016-01-26 18:31:02 +00001128 clientGone := err == io.EOF || err == io.ErrUnexpectedEOF || isClosedConnError(err)
Brad Fitzpatrick8ec321e2014-11-25 14:08:16 -08001129 if clientGone {
1130 // TODO: could we also get into this state if
1131 // the peer does a half close
1132 // (e.g. CloseWrite) because they're done
1133 // sending frames but they're still wanting
1134 // our open replies? Investigate.
Brad Fitzpatrickb2ca8da2014-12-08 00:41:28 -08001135 // TODO: add CloseWrite to crypto/tls.Conn first
1136 // so we have a way to test this? I suppose
1137 // just for testing we could have a non-TLS mode.
Brad Fitzpatrick8ec321e2014-11-25 14:08:16 -08001138 return false
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -08001139 }
Brad Fitzpatrick271cfc12015-10-12 23:49:56 +00001140 } else {
1141 f := res.f
Brad Fitzpatrick415f1912015-12-16 20:28:38 +00001142 if VerboseLogs {
1143 sc.vlogf("http2: server read frame %v", summarizeFrame(f))
1144 }
Brad Fitzpatrick8ec321e2014-11-25 14:08:16 -08001145 err = sc.processFrame(f)
Brad Fitzpatrick8ec321e2014-11-25 14:08:16 -08001146 if err == nil {
1147 return true
1148 }
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -08001149 }
1150
1151 switch ev := err.(type) {
1152 case StreamError:
Brad Fitzpatrick6ec17312014-11-23 10:07:07 -08001153 sc.resetStream(ev)
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -08001154 return true
1155 case goAwayFlowError:
Brad Fitzpatrick55815ec2014-11-15 13:29:57 -08001156 sc.goAway(ErrCodeFlowControl)
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -08001157 return true
1158 case ConnectionError:
Brad Fitzpatrick415f1912015-12-16 20:28:38 +00001159 sc.logf("http2: server connection error from %v: %v", sc.conn.RemoteAddr(), ev)
Brad Fitzpatrick21896bb2014-11-19 16:05:21 -08001160 sc.goAway(ErrCode(ev))
1161 return true // goAway will handle shutdown
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -08001162 default:
Brad Fitzpatrick271cfc12015-10-12 23:49:56 +00001163 if res.err != nil {
Brad Fitzpatrickeb066e32016-01-26 18:31:02 +00001164 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 -08001165 } else {
Brad Fitzpatrick415f1912015-12-16 20:28:38 +00001166 sc.logf("http2: server closing client connection: %v", err)
Brad Fitzpatrick8ec321e2014-11-25 14:08:16 -08001167 }
Brad Fitzpatrick271cfc12015-10-12 23:49:56 +00001168 return false
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -08001169 }
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -08001170}
1171
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001172func (sc *serverConn) processFrame(f Frame) error {
1173 sc.serveG.check()
1174
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -08001175 // First frame received must be SETTINGS.
1176 if !sc.sawFirstSettings {
1177 if _, ok := f.(*SettingsFrame); !ok {
1178 return ConnectionError(ErrCodeProtocol)
1179 }
1180 sc.sawFirstSettings = true
1181 }
1182
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001183 switch f := f.(type) {
1184 case *SettingsFrame:
1185 return sc.processSettings(f)
1186 case *HeadersFrame:
1187 return sc.processHeaders(f)
1188 case *ContinuationFrame:
1189 return sc.processContinuation(f)
1190 case *WindowUpdateFrame:
1191 return sc.processWindowUpdate(f)
1192 case *PingFrame:
1193 return sc.processPing(f)
1194 case *DataFrame:
1195 return sc.processData(f)
Brad Fitzpatrick6d3aa4f2014-11-15 14:55:57 -08001196 case *RSTStreamFrame:
1197 return sc.processResetStream(f)
Brad Fitzpatrick2ee3a492014-11-30 23:18:32 -08001198 case *PriorityFrame:
1199 return sc.processPriority(f)
Daniel Morsing9f251692014-12-05 18:17:30 +00001200 case *PushPromiseFrame:
1201 // A client cannot push. Thus, servers MUST treat the receipt of a PUSH_PROMISE
1202 // frame as a connection error (Section 5.4.1) of type PROTOCOL_ERROR.
1203 return ConnectionError(ErrCodeProtocol)
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001204 default:
Brad Fitzpatrick415f1912015-12-16 20:28:38 +00001205 sc.vlogf("http2: server ignoring frame: %v", f.Header())
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001206 return nil
1207 }
1208}
1209
1210func (sc *serverConn) processPing(f *PingFrame) error {
1211 sc.serveG.check()
Brad Fitzpatricka179abb2015-11-07 16:46:24 +01001212 if f.IsAck() {
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001213 // 6.7 PING: " An endpoint MUST NOT respond to PING frames
1214 // containing this flag."
1215 return nil
1216 }
1217 if f.StreamID != 0 {
1218 // "PING frames are not associated with any individual
1219 // stream. If a PING frame is received with a stream
1220 // identifier field value other than 0x0, the recipient MUST
1221 // respond with a connection error (Section 5.4.1) of type
1222 // PROTOCOL_ERROR."
1223 return ConnectionError(ErrCodeProtocol)
1224 }
Brad Fitzpatrickf16a0b32014-11-28 13:49:30 -08001225 sc.writeFrame(frameWriteMsg{write: writePingAck{f}})
Brad Fitzpatrick9e0eccc2014-11-15 09:14:49 -08001226 return nil
1227}
1228
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001229func (sc *serverConn) processWindowUpdate(f *WindowUpdateFrame) error {
1230 sc.serveG.check()
1231 switch {
1232 case f.StreamID != 0: // stream-level flow control
1233 st := sc.streams[f.StreamID]
1234 if st == nil {
1235 // "WINDOW_UPDATE can be sent by a peer that has sent a
1236 // frame bearing the END_STREAM flag. This means that a
1237 // receiver could receive a WINDOW_UPDATE frame on a "half
1238 // closed (remote)" or "closed" stream. A receiver MUST
1239 // NOT treat this as an error, see Section 5.1."
1240 return nil
1241 }
1242 if !st.flow.add(int32(f.Increment)) {
1243 return StreamError{f.StreamID, ErrCodeFlowControl}
1244 }
1245 default: // connection-level flow control
1246 if !sc.flow.add(int32(f.Increment)) {
1247 return goAwayFlowError{}
1248 }
1249 }
Brad Fitzpatrick2b459472014-11-30 19:18:57 -08001250 sc.scheduleFrameWrite()
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001251 return nil
1252}
1253
Brad Fitzpatrick6d3aa4f2014-11-15 14:55:57 -08001254func (sc *serverConn) processResetStream(f *RSTStreamFrame) error {
1255 sc.serveG.check()
Brad Fitzpatricka98415a2014-12-08 00:47:45 -08001256
1257 state, st := sc.state(f.StreamID)
1258 if state == stateIdle {
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08001259 // 6.4 "RST_STREAM frames MUST NOT be sent for a
1260 // stream in the "idle" state. If a RST_STREAM frame
1261 // identifying an idle stream is received, the
1262 // recipient MUST treat this as a connection error
1263 // (Section 5.4.1) of type PROTOCOL_ERROR.
1264 return ConnectionError(ErrCodeProtocol)
1265 }
Brad Fitzpatricka98415a2014-12-08 00:47:45 -08001266 if st != nil {
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08001267 st.gotReset = true
1268 sc.closeStream(st, StreamError{f.StreamID, f.ErrCode})
1269 }
Brad Fitzpatrick6d3aa4f2014-11-15 14:55:57 -08001270 return nil
1271}
1272
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08001273func (sc *serverConn) closeStream(st *stream, err error) {
Brad Fitzpatrick6d3aa4f2014-11-15 14:55:57 -08001274 sc.serveG.check()
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08001275 if st.state == stateIdle || st.state == stateClosed {
Brad Fitzpatrickf3a6d9a2014-12-08 07:53:36 -08001276 panic(fmt.Sprintf("invariant; can't close stream in state %v", st.state))
Brad Fitzpatrick6d3aa4f2014-11-15 14:55:57 -08001277 }
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08001278 st.state = stateClosed
Brad Fitzpatrick6ec17312014-11-23 10:07:07 -08001279 sc.curOpenStreams--
Brad Fitzpatrickcd8c2702015-10-15 20:01:14 +00001280 if sc.curOpenStreams == 0 {
1281 sc.setConnState(http.StateIdle)
1282 }
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08001283 delete(sc.streams, st.id)
Brad Fitzpatrick6d3aa4f2014-11-15 14:55:57 -08001284 if p := st.body; p != nil {
Brad Fitzpatrickb7f5d982015-10-26 13:59:20 -05001285 p.CloseWithError(err)
Brad Fitzpatrick6d3aa4f2014-11-15 14:55:57 -08001286 }
Brad Fitzpatrick2b459472014-11-30 19:18:57 -08001287 st.cw.Close() // signals Handler's CloseNotifier, unblocks writes, etc
Brad Fitzpatrick5b95eb32014-12-02 10:52:56 -08001288 sc.writeSched.forgetStream(st.id)
Brad Fitzpatrick6d3aa4f2014-11-15 14:55:57 -08001289}
1290
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001291func (sc *serverConn) processSettings(f *SettingsFrame) error {
1292 sc.serveG.check()
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -08001293 if f.IsAck() {
Brad Fitzpatrick6a9b77b2014-12-03 13:56:36 -08001294 sc.unackedSettings--
1295 if sc.unackedSettings < 0 {
1296 // Why is the peer ACKing settings we never sent?
1297 // The spec doesn't mention this case, but
1298 // hang up on them anyway.
1299 return ConnectionError(ErrCodeProtocol)
1300 }
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -08001301 return nil
1302 }
1303 if err := f.ForeachSetting(sc.processSetting); err != nil {
1304 return err
1305 }
Brad Fitzpatrick4e3c9222014-11-22 17:35:09 -08001306 sc.needToSendSettingsAck = true
1307 sc.scheduleFrameWrite()
Brad Fitzpatrickd07a0e42014-11-15 10:47:12 -08001308 return nil
1309}
1310
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001311func (sc *serverConn) processSetting(s Setting) error {
1312 sc.serveG.check()
Brad Fitzpatrickbc00c572014-11-17 12:28:01 -08001313 if err := s.Valid(); err != nil {
1314 return err
1315 }
Brad Fitzpatrick415f1912015-12-16 20:28:38 +00001316 if VerboseLogs {
1317 sc.vlogf("http2: server processing setting %v", s)
1318 }
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001319 switch s.ID {
Brad Fitzpatrickbc00c572014-11-17 12:28:01 -08001320 case SettingHeaderTableSize:
1321 sc.headerTableSize = s.Val
Tatsuhiro Tsujikawac7d67a52014-11-20 01:01:39 +09001322 sc.hpackEncoder.SetMaxDynamicTableSize(s.Val)
Brad Fitzpatrickbc00c572014-11-17 12:28:01 -08001323 case SettingEnablePush:
1324 sc.pushEnabled = s.Val != 0
Brad Fitzpatrickbc00c572014-11-17 12:28:01 -08001325 case SettingMaxConcurrentStreams:
Brad Fitzpatrick6ec17312014-11-23 10:07:07 -08001326 sc.clientMaxStreams = s.Val
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001327 case SettingInitialWindowSize:
1328 return sc.processSettingInitialWindowSize(s.Val)
Brad Fitzpatrickbc00c572014-11-17 12:28:01 -08001329 case SettingMaxFrameSize:
Brad Fitzpatrick2b459472014-11-30 19:18:57 -08001330 sc.writeSched.maxFrameSize = s.Val
Brad Fitzpatrickbc00c572014-11-17 12:28:01 -08001331 case SettingMaxHeaderListSize:
Brad Fitzpatrick29704b82015-10-10 18:01:18 -07001332 sc.peerMaxHeaderListSize = s.Val
gbbr0b3b5742014-11-23 00:44:48 +00001333 default:
1334 // Unknown setting: "An endpoint that receives a SETTINGS
1335 // frame with any unknown or unsupported identifier MUST
1336 // ignore that setting."
Brad Fitzpatrick415f1912015-12-16 20:28:38 +00001337 if VerboseLogs {
1338 sc.vlogf("http2: server ignoring unknown setting %v", s)
1339 }
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001340 }
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001341 return nil
1342}
1343
1344func (sc *serverConn) processSettingInitialWindowSize(val uint32) error {
1345 sc.serveG.check()
Brad Fitzpatrickbc00c572014-11-17 12:28:01 -08001346 // Note: val already validated to be within range by
1347 // processSetting's Valid call.
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001348
1349 // "A SETTINGS frame can alter the initial flow control window
1350 // size for all current streams. When the value of
1351 // SETTINGS_INITIAL_WINDOW_SIZE changes, a receiver MUST
1352 // adjust the size of all stream flow control windows that it
1353 // maintains by the difference between the new value and the
1354 // old value."
1355 old := sc.initialWindowSize
1356 sc.initialWindowSize = int32(val)
1357 growth := sc.initialWindowSize - old // may be negative
1358 for _, st := range sc.streams {
1359 if !st.flow.add(growth) {
1360 // 6.9.2 Initial Flow Control Window Size
1361 // "An endpoint MUST treat a change to
1362 // SETTINGS_INITIAL_WINDOW_SIZE that causes any flow
1363 // control window to exceed the maximum size as a
1364 // connection error (Section 5.4.1) of type
1365 // FLOW_CONTROL_ERROR."
1366 return ConnectionError(ErrCodeFlowControl)
1367 }
1368 }
1369 return nil
1370}
1371
1372func (sc *serverConn) processData(f *DataFrame) error {
1373 sc.serveG.check()
1374 // "If a DATA frame is received whose stream is not in "open"
1375 // or "half closed (local)" state, the recipient MUST respond
1376 // with a stream error (Section 5.4.2) of type STREAM_CLOSED."
1377 id := f.Header().StreamID
1378 st, ok := sc.streams[id]
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +00001379 if !ok || st.state != stateOpen || st.gotTrailerHeader {
Brad Fitzpatrickf3a6d9a2014-12-08 07:53:36 -08001380 // This includes sending a RST_STREAM if the stream is
1381 // in stateHalfClosedLocal (which currently means that
1382 // the http.Handler returned, so it's done reading &
1383 // done writing). Try to stop the client from sending
1384 // more DATA.
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001385 return StreamError{id, ErrCodeStreamClosed}
1386 }
1387 if st.body == nil {
Brad Fitzpatrickb0a06c82014-11-26 09:21:28 -08001388 panic("internal error: should have a body in this state")
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001389 }
1390 data := f.Data()
1391
1392 // Sender sending more than they'd declared?
1393 if st.declBodyBytes != -1 && st.bodyBytes+int64(len(data)) > st.declBodyBytes {
Brad Fitzpatrickb7f5d982015-10-26 13:59:20 -05001394 st.body.CloseWithError(fmt.Errorf("sender tried to send more than declared Content-Length of %d bytes", st.declBodyBytes))
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001395 return StreamError{id, ErrCodeStreamClosed}
1396 }
1397 if len(data) > 0 {
Brad Fitzpatrick068d35d2014-12-09 07:10:31 +11001398 // Check whether the client has flow control quota.
1399 if int(st.inflow.available()) < len(data) {
1400 return StreamError{id, ErrCodeFlowControl}
1401 }
1402 st.inflow.take(int32(len(data)))
Brad Fitzpatrick0218ba62014-11-26 09:36:05 -08001403 wrote, err := st.body.Write(data)
1404 if err != nil {
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001405 return StreamError{id, ErrCodeStreamClosed}
1406 }
Brad Fitzpatrick0218ba62014-11-26 09:36:05 -08001407 if wrote != len(data) {
1408 panic("internal error: bad Writer")
1409 }
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001410 st.bodyBytes += int64(len(data))
1411 }
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08001412 if f.StreamEnded() {
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +00001413 st.endStream()
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001414 }
1415 return nil
1416}
1417
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +00001418// endStream closes a Request.Body's pipe. It is called when a DATA
1419// frame says a request body is over (or after trailers).
1420func (st *stream) endStream() {
1421 sc := st.sc
1422 sc.serveG.check()
1423
1424 if st.declBodyBytes != -1 && st.declBodyBytes != st.bodyBytes {
1425 st.body.CloseWithError(fmt.Errorf("request declared a Content-Length of %d but only wrote %d bytes",
1426 st.declBodyBytes, st.bodyBytes))
1427 } else {
1428 st.body.closeWithErrorAndCode(io.EOF, st.copyTrailersToHandlerRequest)
1429 st.body.CloseWithError(io.EOF)
1430 }
1431 st.state = stateHalfClosedRemote
1432}
1433
1434// copyTrailersToHandlerRequest is run in the Handler's goroutine in
1435// its Request.Body.Read just before it gets io.EOF.
1436func (st *stream) copyTrailersToHandlerRequest() {
1437 for k, vv := range st.trailer {
1438 if _, ok := st.reqTrailer[k]; ok {
1439 // Only copy it over it was pre-declared.
1440 st.reqTrailer[k] = vv
1441 }
1442 }
1443}
1444
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001445func (sc *serverConn) processHeaders(f *HeadersFrame) error {
1446 sc.serveG.check()
1447 id := f.Header().StreamID
Brad Fitzpatrick21896bb2014-11-19 16:05:21 -08001448 if sc.inGoAway {
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001449 // Ignore.
1450 return nil
1451 }
1452 // http://http2.github.io/http2-spec/#rfc.section.5.1.1
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +00001453 // Streams initiated by a client MUST use odd-numbered stream
1454 // identifiers. [...] An endpoint that receives an unexpected
1455 // stream identifier MUST respond with a connection error
1456 // (Section 5.4.1) of type PROTOCOL_ERROR.
1457 if id%2 != 1 {
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001458 return ConnectionError(ErrCodeProtocol)
1459 }
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +00001460 // A HEADERS frame can be used to create a new stream or
1461 // send a trailer for an open one. If we already have a stream
1462 // open, let it process its own HEADERS frame (trailers at this
1463 // point, if it's valid).
1464 st := sc.streams[f.Header().StreamID]
1465 if st != nil {
1466 return st.processTrailerHeaders(f)
1467 }
1468
1469 // [...] The identifier of a newly established stream MUST be
1470 // numerically greater than all streams that the initiating
1471 // endpoint has opened or reserved. [...] An endpoint that
1472 // receives an unexpected stream identifier MUST respond with
1473 // a connection error (Section 5.4.1) of type PROTOCOL_ERROR.
1474 if id <= sc.maxStreamID || sc.req.stream != nil {
1475 return ConnectionError(ErrCodeProtocol)
1476 }
1477
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001478 if id > sc.maxStreamID {
1479 sc.maxStreamID = id
1480 }
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +00001481 st = &stream{
1482 sc: sc,
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001483 id: id,
1484 state: stateOpen,
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001485 }
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08001486 if f.StreamEnded() {
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001487 st.state = stateHalfClosedRemote
1488 }
Brad Fitzpatrick068d35d2014-12-09 07:10:31 +11001489 st.cw.Init()
1490
1491 st.flow.conn = &sc.flow // link to conn-level counter
1492 st.flow.add(sc.initialWindowSize)
1493 st.inflow.conn = &sc.inflow // link to conn-level counter
1494 st.inflow.add(initialWindowSize) // TODO: update this when we send a higher initial window size in the initial settings
1495
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001496 sc.streams[id] = st
Brad Fitzpatrick2ee3a492014-11-30 23:18:32 -08001497 if f.HasPriority() {
Daniel Morsinga5c55932014-12-14 13:34:18 +01001498 adjustStreamPriority(sc.streams, st.id, f.Priority)
Brad Fitzpatrick2ee3a492014-11-30 23:18:32 -08001499 }
Brad Fitzpatrickb3e0a872014-11-23 21:15:59 -08001500 sc.curOpenStreams++
Brad Fitzpatrickcd8c2702015-10-15 20:01:14 +00001501 if sc.curOpenStreams == 1 {
1502 sc.setConnState(http.StateActive)
1503 }
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001504 sc.req = requestParam{
1505 stream: st,
1506 header: make(http.Header),
1507 }
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +00001508 sc.hpackDecoder.SetEmitFunc(sc.onNewHeaderField)
Brad Fitzpatrickd8f3c682015-10-12 20:56:49 +00001509 sc.hpackDecoder.SetEmitEnabled(true)
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001510 return sc.processHeaderBlockFragment(st, f.HeaderBlockFragment(), f.HeadersEnded())
1511}
1512
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +00001513func (st *stream) processTrailerHeaders(f *HeadersFrame) error {
1514 sc := st.sc
1515 sc.serveG.check()
1516 if st.gotTrailerHeader {
1517 return ConnectionError(ErrCodeProtocol)
1518 }
1519 st.gotTrailerHeader = true
Brad Fitzpatrickf530c4e2016-01-07 08:16:00 -08001520 if !f.StreamEnded() {
1521 return StreamError{st.id, ErrCodeProtocol}
1522 }
1523 sc.resetPendingRequest() // we use invalidHeader from it for trailers
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +00001524 return st.processTrailerHeaderBlockFragment(f.HeaderBlockFragment(), f.HeadersEnded())
1525}
1526
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001527func (sc *serverConn) processContinuation(f *ContinuationFrame) error {
1528 sc.serveG.check()
1529 st := sc.streams[f.Header().StreamID]
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +00001530 if st.gotTrailerHeader {
1531 return st.processTrailerHeaderBlockFragment(f.HeaderBlockFragment(), f.HeadersEnded())
1532 }
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001533 return sc.processHeaderBlockFragment(st, f.HeaderBlockFragment(), f.HeadersEnded())
1534}
1535
1536func (sc *serverConn) processHeaderBlockFragment(st *stream, frag []byte, end bool) error {
1537 sc.serveG.check()
1538 if _, err := sc.hpackDecoder.Write(frag); err != nil {
Brad Fitzpatrick59e870b2015-10-14 00:12:18 +00001539 return ConnectionError(ErrCodeCompression)
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001540 }
1541 if !end {
1542 return nil
1543 }
1544 if err := sc.hpackDecoder.Close(); err != nil {
Brad Fitzpatrick59e870b2015-10-14 00:12:18 +00001545 return ConnectionError(ErrCodeCompression)
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001546 }
Brad Fitzpatrickb3e0a872014-11-23 21:15:59 -08001547 defer sc.resetPendingRequest()
1548 if sc.curOpenStreams > sc.advMaxStreams {
Brad Fitzpatrick6a9b77b2014-12-03 13:56:36 -08001549 // "Endpoints MUST NOT exceed the limit set by their
1550 // peer. An endpoint that receives a HEADERS frame
1551 // that causes their advertised concurrent stream
1552 // limit to be exceeded MUST treat this as a stream
1553 // error (Section 5.4.2) of type PROTOCOL_ERROR or
1554 // REFUSED_STREAM."
1555 if sc.unackedSettings == 0 {
1556 // They should know better.
1557 return StreamError{st.id, ErrCodeProtocol}
1558 }
1559 // Assume it's a network race, where they just haven't
1560 // received our last SETTINGS update. But actually
1561 // this can't happen yet, because we don't yet provide
1562 // a way for users to adjust server parameters at
1563 // runtime.
1564 return StreamError{st.id, ErrCodeRefusedStream}
Brad Fitzpatrickb3e0a872014-11-23 21:15:59 -08001565 }
1566
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001567 rw, req, err := sc.newWriterAndRequest()
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001568 if err != nil {
1569 return err
1570 }
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +00001571 st.reqTrailer = req.Trailer
1572 if st.reqTrailer != nil {
1573 st.trailer = make(http.Header)
1574 }
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001575 st.body = req.Body.(*requestBody).pipe // may be nil
1576 st.declBodyBytes = req.ContentLength
Brad Fitzpatrickd8f3c682015-10-12 20:56:49 +00001577
1578 handler := sc.handler.ServeHTTP
1579 if !sc.hpackDecoder.EmitEnabled() {
1580 // Their header list was too long. Send a 431 error.
1581 handler = handleHeaderListTooLong
1582 }
1583
1584 go sc.runHandler(rw, req, handler)
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001585 return nil
1586}
1587
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +00001588func (st *stream) processTrailerHeaderBlockFragment(frag []byte, end bool) error {
1589 sc := st.sc
1590 sc.serveG.check()
1591 sc.hpackDecoder.SetEmitFunc(st.onNewTrailerField)
1592 if _, err := sc.hpackDecoder.Write(frag); err != nil {
1593 return ConnectionError(ErrCodeCompression)
1594 }
1595 if !end {
1596 return nil
1597 }
Brad Fitzpatrickf530c4e2016-01-07 08:16:00 -08001598
1599 rp := &sc.req
1600 if rp.invalidHeader {
1601 return StreamError{rp.stream.id, ErrCodeProtocol}
1602 }
1603
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +00001604 err := sc.hpackDecoder.Close()
1605 st.endStream()
1606 if err != nil {
1607 return ConnectionError(ErrCodeCompression)
1608 }
1609 return nil
1610}
1611
Brad Fitzpatrick2ee3a492014-11-30 23:18:32 -08001612func (sc *serverConn) processPriority(f *PriorityFrame) error {
Daniel Morsinga5c55932014-12-14 13:34:18 +01001613 adjustStreamPriority(sc.streams, f.StreamID, f.PriorityParam)
Brad Fitzpatrick2ee3a492014-11-30 23:18:32 -08001614 return nil
1615}
1616
Daniel Morsinga5c55932014-12-14 13:34:18 +01001617func adjustStreamPriority(streams map[uint32]*stream, streamID uint32, priority PriorityParam) {
1618 st, ok := streams[streamID]
Brad Fitzpatrick2ee3a492014-11-30 23:18:32 -08001619 if !ok {
1620 // TODO: not quite correct (this streamID might
1621 // already exist in the dep tree, but be closed), but
1622 // close enough for now.
1623 return
1624 }
1625 st.weight = priority.Weight
Daniel Morsinga5c55932014-12-14 13:34:18 +01001626 parent := streams[priority.StreamDep] // might be nil
1627 if parent == st {
1628 // if client tries to set this stream to be the parent of itself
1629 // ignore and keep going
1630 return
1631 }
1632
1633 // section 5.3.3: If a stream is made dependent on one of its
1634 // own dependencies, the formerly dependent stream is first
1635 // moved to be dependent on the reprioritized stream's previous
1636 // parent. The moved dependency retains its weight.
1637 for piter := parent; piter != nil; piter = piter.parent {
1638 if piter == st {
1639 parent.parent = st.parent
1640 break
1641 }
1642 }
1643 st.parent = parent
1644 if priority.Exclusive && (st.parent != nil || priority.StreamDep == 0) {
1645 for _, openStream := range streams {
1646 if openStream != st && openStream.parent == st.parent {
Brad Fitzpatrick2ee3a492014-11-30 23:18:32 -08001647 openStream.parent = st
1648 }
1649 }
1650 }
1651}
1652
Brad Fitzpatrickb3e0a872014-11-23 21:15:59 -08001653// resetPendingRequest zeros out all state related to a HEADERS frame
1654// and its zero or more CONTINUATION frames sent to start a new
1655// request.
1656func (sc *serverConn) resetPendingRequest() {
1657 sc.serveG.check()
1658 sc.req = requestParam{}
1659}
1660
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001661func (sc *serverConn) newWriterAndRequest() (*responseWriter, *http.Request, error) {
1662 sc.serveG.check()
1663 rp := &sc.req
Brad Fitzpatrick961116a2016-01-05 14:53:21 -08001664
1665 if rp.invalidHeader {
1666 return nil, nil, StreamError{rp.stream.id, ErrCodeProtocol}
1667 }
1668
1669 isConnect := rp.method == "CONNECT"
1670 if isConnect {
1671 if rp.path != "" || rp.scheme != "" || rp.authority == "" {
1672 return nil, nil, StreamError{rp.stream.id, ErrCodeProtocol}
1673 }
1674 } else if rp.method == "" || rp.path == "" ||
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001675 (rp.scheme != "https" && rp.scheme != "http") {
1676 // See 8.1.2.6 Malformed Requests and Responses:
1677 //
1678 // Malformed requests or responses that are detected
1679 // MUST be treated as a stream error (Section 5.4.2)
1680 // of type PROTOCOL_ERROR."
1681 //
1682 // 8.1.2.3 Request Pseudo-Header Fields
1683 // "All HTTP/2 requests MUST include exactly one valid
1684 // value for the :method, :scheme, and :path
1685 // pseudo-header fields"
1686 return nil, nil, StreamError{rp.stream.id, ErrCodeProtocol}
1687 }
Brad Fitzpatrick961116a2016-01-05 14:53:21 -08001688
Brad Fitzpatrickc745c362015-11-24 17:14:16 -08001689 bodyOpen := rp.stream.state == stateOpen
1690 if rp.method == "HEAD" && bodyOpen {
1691 // HEAD requests can't have bodies
1692 return nil, nil, StreamError{rp.stream.id, ErrCodeProtocol}
1693 }
Brad Fitzpatrick30b16812014-12-08 10:10:39 -08001694 var tlsState *tls.ConnectionState // nil if not scheme https
Brad Fitzpatrick961116a2016-01-05 14:53:21 -08001695
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001696 if rp.scheme == "https" {
Brad Fitzpatrick30b16812014-12-08 10:10:39 -08001697 tlsState = sc.tlsState
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001698 }
1699 authority := rp.authority
1700 if authority == "" {
1701 authority = rp.header.Get("Host")
1702 }
Brad Fitzpatrick9d63ade2014-11-15 12:02:43 -08001703 needsContinue := rp.header.Get("Expect") == "100-continue"
1704 if needsContinue {
1705 rp.header.Del("Expect")
1706 }
Brad Fitzpatrickb8469202015-10-07 22:10:10 -07001707 // Merge Cookie headers into one "; "-delimited value.
1708 if cookies := rp.header["Cookie"]; len(cookies) > 1 {
1709 rp.header.Set("Cookie", strings.Join(cookies, "; "))
1710 }
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +00001711
1712 // Setup Trailers
1713 var trailer http.Header
1714 for _, v := range rp.header["Trailer"] {
1715 for _, key := range strings.Split(v, ",") {
1716 key = http.CanonicalHeaderKey(strings.TrimSpace(key))
1717 switch key {
1718 case "Transfer-Encoding", "Trailer", "Content-Length":
1719 // Bogus. (copy of http1 rules)
1720 // Ignore.
1721 default:
1722 if trailer == nil {
1723 trailer = make(http.Header)
1724 }
1725 trailer[key] = nil
1726 }
1727 }
1728 }
1729 delete(rp.header, "Trailer")
1730
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001731 body := &requestBody{
Brad Fitzpatrick914bad52014-11-30 21:05:26 -08001732 conn: sc,
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08001733 stream: rp.stream,
Brad Fitzpatrick9d63ade2014-11-15 12:02:43 -08001734 needsContinue: needsContinue,
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001735 }
Brad Fitzpatrick961116a2016-01-05 14:53:21 -08001736 var url_ *url.URL
1737 var requestURI string
1738 if isConnect {
1739 url_ = &url.URL{Host: rp.authority}
1740 requestURI = rp.authority // mimic HTTP/1 server behavior
1741 } else {
1742 var err error
Brad Fitzpatrick961116a2016-01-05 14:53:21 -08001743 url_, err = url.ParseRequestURI(rp.path)
1744 if err != nil {
1745 return nil, nil, StreamError{rp.stream.id, ErrCodeProtocol}
1746 }
1747 requestURI = rp.path
Brad Fitzpatrickff0471b2014-11-14 21:55:14 -08001748 }
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001749 req := &http.Request{
1750 Method: rp.method,
Brad Fitzpatrick961116a2016-01-05 14:53:21 -08001751 URL: url_,
Brad Fitzpatrickdf959c22014-12-09 07:20:20 +11001752 RemoteAddr: sc.remoteAddrStr,
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001753 Header: rp.header,
Brad Fitzpatrick961116a2016-01-05 14:53:21 -08001754 RequestURI: requestURI,
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001755 Proto: "HTTP/2.0",
1756 ProtoMajor: 2,
1757 ProtoMinor: 0,
1758 TLS: tlsState,
1759 Host: authority,
1760 Body: body,
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +00001761 Trailer: trailer,
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001762 }
1763 if bodyOpen {
1764 body.pipe = &pipe{
Brad Fitzpatrickc24de9d2015-12-16 17:29:56 +00001765 b: &fixedBuffer{buf: make([]byte, initialWindowSize)}, // TODO: garbage
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001766 }
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001767
1768 if vv, ok := rp.header["Content-Length"]; ok {
1769 req.ContentLength, _ = strconv.ParseInt(vv[0], 10, 64)
1770 } else {
1771 req.ContentLength = -1
1772 }
1773 }
Brad Fitzpatrick729bd722014-11-13 14:09:36 -08001774
1775 rws := responseWriterStatePool.Get().(*responseWriterState)
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08001776 bwSave := rws.bw
Brad Fitzpatrick520123b2014-11-14 15:57:37 -08001777 *rws = responseWriterState{} // zero all the fields
Brad Fitzpatrick914bad52014-11-30 21:05:26 -08001778 rws.conn = sc
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08001779 rws.bw = bwSave
1780 rws.bw.Reset(chunkWriter{rws})
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08001781 rws.stream = rp.stream
Brad Fitzpatrick729bd722014-11-13 14:09:36 -08001782 rws.req = req
1783 rws.body = body
Brad Fitzpatrick729bd722014-11-13 14:09:36 -08001784
1785 rw := &responseWriter{rws: rws}
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001786 return rw, req, nil
1787}
1788
1789// Run on its own goroutine.
Brad Fitzpatrickd8f3c682015-10-12 20:56:49 +00001790func (sc *serverConn) runHandler(rw *responseWriter, req *http.Request, handler func(http.ResponseWriter, *http.Request)) {
Brad Fitzpatrick74bd44b2015-12-15 00:47:28 +00001791 didPanic := true
1792 defer func() {
1793 if didPanic {
1794 e := recover()
1795 // Same as net/http:
1796 const size = 64 << 10
1797 buf := make([]byte, size)
1798 buf = buf[:runtime.Stack(buf, false)]
1799 sc.writeFrameFromHandler(frameWriteMsg{
1800 write: handlerPanicRST{rw.rws.stream.id},
1801 stream: rw.rws.stream,
1802 })
1803 sc.logf("http2: panic serving %v: %v\n%s", sc.conn.RemoteAddr(), e, buf)
1804 return
1805 }
1806 rw.handlerDone()
1807 }()
Brad Fitzpatrickd8f3c682015-10-12 20:56:49 +00001808 handler(rw, req)
Brad Fitzpatrick74bd44b2015-12-15 00:47:28 +00001809 didPanic = false
Brad Fitzpatrickd8f3c682015-10-12 20:56:49 +00001810}
1811
1812func handleHeaderListTooLong(w http.ResponseWriter, r *http.Request) {
1813 // 10.5.1 Limits on Header Block Size:
1814 // .. "A server that receives a larger header block than it is
1815 // willing to handle can send an HTTP 431 (Request Header Fields Too
1816 // Large) status code"
1817 const statusRequestHeaderFieldsTooLarge = 431 // only in Go 1.6+
1818 w.WriteHeader(statusRequestHeaderFieldsTooLarge)
1819 io.WriteString(w, "<h1>HTTP Error 431</h1><p>Request Header Field(s) Too Large</p>")
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001820}
1821
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001822// called from handler goroutines.
1823// h may be nil.
Brad Fitzpatrick56401052015-10-20 22:27:39 +00001824func (sc *serverConn) writeHeaders(st *stream, headerData *writeResHeaders) error {
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08001825 sc.serveG.checkNotOn() // NOT on
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08001826 var errc chan error
Brad Fitzpatrickf16a0b32014-11-28 13:49:30 -08001827 if headerData.h != nil {
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08001828 // If there's a header map (which we don't own), so we have to block on
1829 // waiting for this frame to be written, so an http.Flush mid-handler
1830 // writes out the correct value of keys, before a handler later potentially
1831 // mutates it.
Brad Fitzpatrickc94bffa2015-10-13 18:18:12 +00001832 errc = errChanPool.Get().(chan error)
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08001833 }
Brad Fitzpatrick56401052015-10-20 22:27:39 +00001834 if err := sc.writeFrameFromHandler(frameWriteMsg{
Brad Fitzpatrickf16a0b32014-11-28 13:49:30 -08001835 write: headerData,
1836 stream: st,
1837 done: errc,
Brad Fitzpatrick56401052015-10-20 22:27:39 +00001838 }); err != nil {
1839 return err
1840 }
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08001841 if errc != nil {
Brad Fitzpatrick9b41faf2014-11-19 10:45:13 -08001842 select {
Brad Fitzpatrick56401052015-10-20 22:27:39 +00001843 case err := <-errc:
Brad Fitzpatrickc94bffa2015-10-13 18:18:12 +00001844 errChanPool.Put(errc)
Brad Fitzpatrick56401052015-10-20 22:27:39 +00001845 return err
Brad Fitzpatrick9b41faf2014-11-19 10:45:13 -08001846 case <-sc.doneServing:
Brad Fitzpatrick56401052015-10-20 22:27:39 +00001847 return errClientDisconnected
Brad Fitzpatrickc94bffa2015-10-13 18:18:12 +00001848 case <-st.cw:
Brad Fitzpatrick56401052015-10-20 22:27:39 +00001849 return errStreamClosed
Brad Fitzpatrick9b41faf2014-11-19 10:45:13 -08001850 }
Brad Fitzpatrick520123b2014-11-14 15:57:37 -08001851 }
Brad Fitzpatrick56401052015-10-20 22:27:39 +00001852 return nil
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001853}
1854
Brad Fitzpatrick9d63ade2014-11-15 12:02:43 -08001855// called from handler goroutines.
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08001856func (sc *serverConn) write100ContinueHeaders(st *stream) {
Brad Fitzpatrick4e3c9222014-11-22 17:35:09 -08001857 sc.writeFrameFromHandler(frameWriteMsg{
Brad Fitzpatrickf16a0b32014-11-28 13:49:30 -08001858 write: write100ContinueHeadersFrame{st.id},
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08001859 stream: st,
Brad Fitzpatrick9d63ade2014-11-15 12:02:43 -08001860 })
1861}
1862
Brad Fitzpatrickc8bab6a2014-12-07 18:51:56 -08001863// A bodyReadMsg tells the server loop that the http.Handler read n
1864// bytes of the DATA from the client on the given stream.
1865type bodyReadMsg struct {
1866 st *stream
1867 n int
1868}
1869
1870// called from handler goroutines.
1871// Notes that the handler for the given stream ID read n bytes of its body
1872// and schedules flow control tokens to be sent.
1873func (sc *serverConn) noteBodyReadFromHandler(st *stream, n int) {
1874 sc.serveG.checkNotOn() // NOT on
Brad Fitzpatrick0a9f6502015-10-27 14:23:57 -07001875 select {
1876 case sc.bodyReadCh <- bodyReadMsg{st, n}:
1877 case <-sc.doneServing:
1878 }
Brad Fitzpatrickc8bab6a2014-12-07 18:51:56 -08001879}
1880
1881func (sc *serverConn) noteBodyRead(st *stream, n int) {
1882 sc.serveG.check()
1883 sc.sendWindowUpdate(nil, n) // conn-level
Brad Fitzpatrick0f1a8652014-12-07 20:49:33 -08001884 if st.state != stateHalfClosedRemote && st.state != stateClosed {
1885 // Don't send this WINDOW_UPDATE if the stream is closed
1886 // remotely.
1887 sc.sendWindowUpdate(st, n)
1888 }
Brad Fitzpatrickc8bab6a2014-12-07 18:51:56 -08001889}
1890
1891// st may be nil for conn-level
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08001892func (sc *serverConn) sendWindowUpdate(st *stream, n int) {
Brad Fitzpatrickc8bab6a2014-12-07 18:51:56 -08001893 sc.serveG.check()
1894 // "The legal range for the increment to the flow control
1895 // window is 1 to 2^31-1 (2,147,483,647) octets."
Brad Fitzpatrick068d35d2014-12-09 07:10:31 +11001896 // A Go Read call on 64-bit machines could in theory read
1897 // a larger Read than this. Very unlikely, but we handle it here
1898 // rather than elsewhere for now.
1899 const maxUint31 = 1<<31 - 1
1900 for n >= maxUint31 {
1901 sc.sendWindowUpdate32(st, maxUint31)
1902 n -= maxUint31
1903 }
1904 sc.sendWindowUpdate32(st, int32(n))
1905}
1906
1907// st may be nil for conn-level
1908func (sc *serverConn) sendWindowUpdate32(st *stream, n int32) {
1909 sc.serveG.check()
1910 if n == 0 {
1911 return
1912 }
1913 if n < 0 {
1914 panic("negative update")
1915 }
Brad Fitzpatrickc8bab6a2014-12-07 18:51:56 -08001916 var streamID uint32
1917 if st != nil {
1918 streamID = st.id
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08001919 }
Brad Fitzpatrick068d35d2014-12-09 07:10:31 +11001920 sc.writeFrame(frameWriteMsg{
1921 write: writeWindowUpdate{streamID: streamID, n: uint32(n)},
1922 stream: st,
1923 })
1924 var ok bool
1925 if st == nil {
1926 ok = sc.inflow.add(n)
1927 } else {
1928 ok = st.inflow.add(n)
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001929 }
Brad Fitzpatrick068d35d2014-12-09 07:10:31 +11001930 if !ok {
1931 panic("internal error; sent too many window updates without decrements?")
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001932 }
1933}
1934
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001935type requestBody struct {
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08001936 stream *stream
Brad Fitzpatrick914bad52014-11-30 21:05:26 -08001937 conn *serverConn
Brad Fitzpatrick9d63ade2014-11-15 12:02:43 -08001938 closed bool
1939 pipe *pipe // non-nil if we have a HTTP entity message body
1940 needsContinue bool // need to send a 100-continue
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001941}
1942
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001943func (b *requestBody) Close() error {
1944 if b.pipe != nil {
Brad Fitzpatrickb7f5d982015-10-26 13:59:20 -05001945 b.pipe.CloseWithError(errClosedBody)
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001946 }
1947 b.closed = true
1948 return nil
1949}
1950
1951func (b *requestBody) Read(p []byte) (n int, err error) {
Brad Fitzpatrick9d63ade2014-11-15 12:02:43 -08001952 if b.needsContinue {
1953 b.needsContinue = false
Brad Fitzpatrick914bad52014-11-30 21:05:26 -08001954 b.conn.write100ContinueHeaders(b.stream)
Brad Fitzpatrick9d63ade2014-11-15 12:02:43 -08001955 }
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001956 if b.pipe == nil {
1957 return 0, io.EOF
1958 }
1959 n, err = b.pipe.Read(p)
1960 if n > 0 {
Brad Fitzpatrickc8bab6a2014-12-07 18:51:56 -08001961 b.conn.noteBodyReadFromHandler(b.stream, n)
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001962 }
1963 return
1964}
1965
Brad Fitzpatrick729bd722014-11-13 14:09:36 -08001966// responseWriter is the http.ResponseWriter implementation. It's
1967// intentionally small (1 pointer wide) to minimize garbage. The
1968// responseWriterState pointer inside is zeroed at the end of a
1969// request (in handlerDone) and calls on the responseWriter thereafter
1970// simply crash (caller's mistake), but the much larger responseWriterState
1971// and buffers are reused between multiple requests.
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001972type responseWriter struct {
Brad Fitzpatrick729bd722014-11-13 14:09:36 -08001973 rws *responseWriterState
1974}
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08001975
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08001976// Optional http.ResponseWriter interfaces implemented.
1977var (
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08001978 _ http.CloseNotifier = (*responseWriter)(nil)
1979 _ http.Flusher = (*responseWriter)(nil)
1980 _ stringWriter = (*responseWriter)(nil)
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08001981)
1982
Brad Fitzpatrick729bd722014-11-13 14:09:36 -08001983type responseWriterState struct {
1984 // immutable within a request:
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08001985 stream *stream
1986 req *http.Request
1987 body *requestBody // to close at end of request, if DATA frames didn't
Brad Fitzpatrick914bad52014-11-30 21:05:26 -08001988 conn *serverConn
Brad Fitzpatrick729bd722014-11-13 14:09:36 -08001989
Brad Fitzpatrick520123b2014-11-14 15:57:37 -08001990 // TODO: adjust buffer writing sizes based on server config, frame size updates from peer, etc
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08001991 bw *bufio.Writer // writing to a chunkWriter{this *responseWriterState}
Brad Fitzpatrick729bd722014-11-13 14:09:36 -08001992
1993 // mutated by http.Handler goroutine:
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08001994 handlerHeader http.Header // nil until called
1995 snapHeader http.Header // snapshot of handlerHeader at WriteHeader time
Blake Mizeranyb4be4942015-12-15 17:33:14 -08001996 trailers []string // set in writeChunk
Brad Fitzpatrick520123b2014-11-14 15:57:37 -08001997 status int // status code passed to WriteHeader
Brad Fitzpatrick3c8c6132014-11-20 18:34:52 -08001998 wroteHeader bool // WriteHeader called (explicitly or implicitly). Not necessarily sent to user yet.
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08001999 sentHeader bool // have we sent the header frame?
2000 handlerDone bool // handler has finished
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08002001
Brad Fitzpatrickc745c362015-11-24 17:14:16 -08002002 sentContentLen int64 // non-zero if handler set a Content-Length header
2003 wroteBytes int64
2004
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08002005 closeNotifierMu sync.Mutex // guards closeNotifierCh
2006 closeNotifierCh chan bool // nil until first used
Brad Fitzpatrick729bd722014-11-13 14:09:36 -08002007}
2008
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002009type chunkWriter struct{ rws *responseWriterState }
2010
Brad Fitzpatrick3d7a3ad2014-11-15 21:38:23 -08002011func (cw chunkWriter) Write(p []byte) (n int, err error) { return cw.rws.writeChunk(p) }
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002012
Blake Mizeranyb4be4942015-12-15 17:33:14 -08002013func (rws *responseWriterState) hasTrailers() bool { return len(rws.trailers) != 0 }
2014
2015// declareTrailer is called for each Trailer header when the
2016// response header is written. It notes that a header will need to be
2017// written in the trailers at the end of the response.
2018func (rws *responseWriterState) declareTrailer(k string) {
2019 k = http.CanonicalHeaderKey(k)
2020 switch k {
2021 case "Transfer-Encoding", "Content-Length", "Trailer":
2022 // Forbidden by RFC 2616 14.40.
2023 return
2024 }
Brad Fitzpatrickd513e582016-01-31 06:24:40 +00002025 if !strSliceContains(rws.trailers, k) {
2026 rws.trailers = append(rws.trailers, k)
2027 }
Blake Mizeranyb4be4942015-12-15 17:33:14 -08002028}
2029
Brad Fitzpatrick3d7a3ad2014-11-15 21:38:23 -08002030// writeChunk writes chunks from the bufio.Writer. But because
2031// bufio.Writer may bypass its chunking, sometimes p may be
2032// arbitrarily large.
2033//
2034// writeChunk is also responsible (on the first chunk) for sending the
2035// HEADER response.
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002036func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
2037 if !rws.wroteHeader {
2038 rws.writeHeader(200)
2039 }
Blake Mizeranyb4be4942015-12-15 17:33:14 -08002040
Brad Fitzpatrickc745c362015-11-24 17:14:16 -08002041 isHeadResp := rws.req.Method == "HEAD"
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002042 if !rws.sentHeader {
2043 rws.sentHeader = true
Brad Fitzpatrickc745c362015-11-24 17:14:16 -08002044 var ctype, clen string
2045 if clen = rws.snapHeader.Get("Content-Length"); clen != "" {
2046 rws.snapHeader.Del("Content-Length")
2047 clen64, err := strconv.ParseInt(clen, 10, 64)
2048 if err == nil && clen64 >= 0 {
2049 rws.sentContentLen = clen64
2050 } else {
2051 clen = ""
2052 }
2053 }
Brad Fitzpatrick1796f9b2015-12-08 22:22:07 +00002054 if clen == "" && rws.handlerDone && bodyAllowedForStatus(rws.status) && (len(p) > 0 || !isHeadResp) {
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002055 clen = strconv.Itoa(len(p))
2056 }
Brad Fitzpatrick1796f9b2015-12-08 22:22:07 +00002057 _, hasContentType := rws.snapHeader["Content-Type"]
2058 if !hasContentType && bodyAllowedForStatus(rws.status) {
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002059 ctype = http.DetectContentType(p)
2060 }
Brad Fitzpatrickc745c362015-11-24 17:14:16 -08002061 var date string
2062 if _, ok := rws.snapHeader["Date"]; !ok {
2063 // TODO(bradfitz): be faster here, like net/http? measure.
2064 date = time.Now().UTC().Format(http.TimeFormat)
2065 }
Blake Mizeranyb4be4942015-12-15 17:33:14 -08002066
2067 for _, v := range rws.snapHeader["Trailer"] {
2068 foreachHeaderElement(v, rws.declareTrailer)
2069 }
2070
2071 endStream := (rws.handlerDone && !rws.hasTrailers() && len(p) == 0) || isHeadResp
Brad Fitzpatrick56401052015-10-20 22:27:39 +00002072 err = rws.conn.writeHeaders(rws.stream, &writeResHeaders{
Brad Fitzpatrickf16a0b32014-11-28 13:49:30 -08002073 streamID: rws.stream.id,
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002074 httpResCode: rws.status,
2075 h: rws.snapHeader,
Brad Fitzpatrick3d7a3ad2014-11-15 21:38:23 -08002076 endStream: endStream,
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002077 contentType: ctype,
2078 contentLength: clen,
Brad Fitzpatrickc745c362015-11-24 17:14:16 -08002079 date: date,
Brad Fitzpatrickc94bffa2015-10-13 18:18:12 +00002080 })
Brad Fitzpatrick56401052015-10-20 22:27:39 +00002081 if err != nil {
2082 return 0, err
2083 }
Brad Fitzpatrick3d7a3ad2014-11-15 21:38:23 -08002084 if endStream {
Brad Fitzpatrick2b459472014-11-30 19:18:57 -08002085 return 0, nil
Brad Fitzpatrick3d7a3ad2014-11-15 21:38:23 -08002086 }
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002087 }
Brad Fitzpatrickc745c362015-11-24 17:14:16 -08002088 if isHeadResp {
2089 return len(p), nil
2090 }
Brad Fitzpatrick2b459472014-11-30 19:18:57 -08002091 if len(p) == 0 && !rws.handlerDone {
2092 return 0, nil
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002093 }
Brad Fitzpatrick56401052015-10-20 22:27:39 +00002094
Brad Fitzpatrickd513e582016-01-31 06:24:40 +00002095 if rws.handlerDone {
2096 rws.promoteUndeclaredTrailers()
2097 }
2098
Blake Mizeranyb4be4942015-12-15 17:33:14 -08002099 endStream := rws.handlerDone && !rws.hasTrailers()
2100 if len(p) > 0 || endStream {
2101 // only send a 0 byte DATA frame if we're ending the stream.
2102 if err := rws.conn.writeDataFromHandler(rws.stream, p, endStream); err != nil {
2103 return 0, err
2104 }
2105 }
2106
2107 if rws.handlerDone && rws.hasTrailers() {
2108 err = rws.conn.writeHeaders(rws.stream, &writeResHeaders{
2109 streamID: rws.stream.id,
2110 h: rws.handlerHeader,
2111 trailers: rws.trailers,
2112 endStream: true,
2113 })
2114 return len(p), err
Brad Fitzpatrick3d7a3ad2014-11-15 21:38:23 -08002115 }
Brad Fitzpatrick2b459472014-11-30 19:18:57 -08002116 return len(p), nil
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002117}
Brad Fitzpatrick729bd722014-11-13 14:09:36 -08002118
Brad Fitzpatrickd513e582016-01-31 06:24:40 +00002119// TrailerPrefix is a magic prefix for ResponseWriter.Header map keys
2120// that, if present, signals that the map entry is actually for
2121// the response trailers, and not the response headers. The prefix
2122// is stripped after the ServeHTTP call finishes and the values are
2123// sent in the trailers.
2124//
2125// This mechanism is intended only for trailers that are not known
2126// prior to the headers being written. If the set of trailers is fixed
2127// or known before the header is written, the normal Go trailers mechanism
2128// is preferred:
2129// https://golang.org/pkg/net/http/#ResponseWriter
2130// https://golang.org/pkg/net/http/#example_ResponseWriter_trailers
2131const TrailerPrefix = "Trailer:"
2132
2133// promoteUndeclaredTrailers permits http.Handlers to set trailers
2134// after the header has already been flushed. Because the Go
2135// ResponseWriter interface has no way to set Trailers (only the
2136// Header), and because we didn't want to expand the ResponseWriter
2137// interface, and because nobody used trailers, and because RFC 2616
2138// says you SHOULD (but not must) predeclare any trailers in the
2139// header, the official ResponseWriter rules said trailers in Go must
2140// be predeclared, and then we reuse the same ResponseWriter.Header()
2141// map to mean both Headers and Trailers. When it's time to write the
2142// Trailers, we pick out the fields of Headers that were declared as
2143// trailers. That worked for a while, until we found the first major
2144// user of Trailers in the wild: gRPC (using them only over http2),
2145// and gRPC libraries permit setting trailers mid-stream without
2146// predeclarnig them. So: change of plans. We still permit the old
2147// way, but we also permit this hack: if a Header() key begins with
2148// "Trailer:", the suffix of that key is a Trailer. Because ':' is an
2149// invalid token byte anyway, there is no ambiguity. (And it's already
2150// filtered out) It's mildly hacky, but not terrible.
2151//
2152// This method runs after the Handler is done and promotes any Header
2153// fields to be trailers.
2154func (rws *responseWriterState) promoteUndeclaredTrailers() {
2155 for k, vv := range rws.handlerHeader {
2156 if !strings.HasPrefix(k, TrailerPrefix) {
2157 continue
2158 }
2159 trailerKey := strings.TrimPrefix(k, TrailerPrefix)
2160 rws.declareTrailer(trailerKey)
2161 rws.handlerHeader[http.CanonicalHeaderKey(trailerKey)] = vv
2162 }
2163 sort.Strings(rws.trailers)
2164}
2165
Brad Fitzpatrick729bd722014-11-13 14:09:36 -08002166func (w *responseWriter) Flush() {
Brad Fitzpatrick520123b2014-11-14 15:57:37 -08002167 rws := w.rws
2168 if rws == nil {
2169 panic("Header called after Handler finished")
2170 }
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002171 if rws.bw.Buffered() > 0 {
2172 if err := rws.bw.Flush(); err != nil {
2173 // Ignore the error. The frame writer already knows.
2174 return
Brad Fitzpatrick520123b2014-11-14 15:57:37 -08002175 }
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002176 } else {
2177 // The bufio.Writer won't call chunkWriter.Write
2178 // (writeChunk with zero bytes, so we have to do it
2179 // ourselves to force the HTTP response header and/or
2180 // final DATA frame (with END_STREAM) to be sent.
2181 rws.writeChunk(nil)
Brad Fitzpatrick520123b2014-11-14 15:57:37 -08002182 }
Brad Fitzpatrick520123b2014-11-14 15:57:37 -08002183}
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002184
Brad Fitzpatrickbd391962014-11-17 18:58:58 -08002185func (w *responseWriter) CloseNotify() <-chan bool {
2186 rws := w.rws
2187 if rws == nil {
2188 panic("CloseNotify called after Handler finished")
2189 }
2190 rws.closeNotifierMu.Lock()
2191 ch := rws.closeNotifierCh
2192 if ch == nil {
2193 ch = make(chan bool, 1)
2194 rws.closeNotifierCh = ch
2195 go func() {
2196 rws.stream.cw.Wait() // wait for close
2197 ch <- true
2198 }()
2199 }
2200 rws.closeNotifierMu.Unlock()
2201 return ch
2202}
2203
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002204func (w *responseWriter) Header() http.Header {
Brad Fitzpatrick729bd722014-11-13 14:09:36 -08002205 rws := w.rws
2206 if rws == nil {
2207 panic("Header called after Handler finished")
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002208 }
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002209 if rws.handlerHeader == nil {
2210 rws.handlerHeader = make(http.Header)
Brad Fitzpatrick729bd722014-11-13 14:09:36 -08002211 }
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002212 return rws.handlerHeader
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002213}
2214
2215func (w *responseWriter) WriteHeader(code int) {
Brad Fitzpatrick729bd722014-11-13 14:09:36 -08002216 rws := w.rws
2217 if rws == nil {
2218 panic("WriteHeader called after Handler finished")
2219 }
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002220 rws.writeHeader(code)
2221}
2222
2223func (rws *responseWriterState) writeHeader(code int) {
2224 if !rws.wroteHeader {
2225 rws.wroteHeader = true
2226 rws.status = code
2227 if len(rws.handlerHeader) > 0 {
2228 rws.snapHeader = cloneHeader(rws.handlerHeader)
2229 }
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002230 }
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002231}
2232
2233func cloneHeader(h http.Header) http.Header {
2234 h2 := make(http.Header, len(h))
2235 for k, vv := range h {
2236 vv2 := make([]string, len(vv))
2237 copy(vv2, vv)
2238 h2[k] = vv2
2239 }
2240 return h2
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002241}
2242
Brad Fitzpatrick15a4bf32014-11-14 10:56:12 -08002243// The Life Of A Write is like this:
2244//
Brad Fitzpatricked26b482014-11-26 09:16:43 -08002245// * Handler calls w.Write or w.WriteString ->
2246// * -> rws.bw (*bufio.Writer) ->
2247// * (Handler migth call Flush)
2248// * -> chunkWriter{rws}
2249// * -> responseWriterState.writeChunk(p []byte)
2250// * -> responseWriterState.writeChunk (most of the magic; see comment there)
Brad Fitzpatrick15a4bf32014-11-14 10:56:12 -08002251func (w *responseWriter) Write(p []byte) (n int, err error) {
2252 return w.write(len(p), p, "")
Brad Fitzpatrick729bd722014-11-13 14:09:36 -08002253}
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002254
Brad Fitzpatrick15a4bf32014-11-14 10:56:12 -08002255func (w *responseWriter) WriteString(s string) (n int, err error) {
2256 return w.write(len(s), nil, s)
2257}
2258
2259// either dataB or dataS is non-zero.
2260func (w *responseWriter) write(lenData int, dataB []byte, dataS string) (n int, err error) {
Brad Fitzpatrick729bd722014-11-13 14:09:36 -08002261 rws := w.rws
2262 if rws == nil {
2263 panic("Write called after Handler finished")
2264 }
Brad Fitzpatrick520123b2014-11-14 15:57:37 -08002265 if !rws.wroteHeader {
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002266 w.WriteHeader(200)
2267 }
Brad Fitzpatrickc745c362015-11-24 17:14:16 -08002268 if !bodyAllowedForStatus(rws.status) {
2269 return 0, http.ErrBodyNotAllowed
2270 }
2271 rws.wroteBytes += int64(len(dataB)) + int64(len(dataS)) // only one can be set
2272 if rws.sentContentLen != 0 && rws.wroteBytes > rws.sentContentLen {
2273 // TODO: send a RST_STREAM
2274 return 0, errors.New("http2: handler wrote more than declared Content-Length")
2275 }
2276
Brad Fitzpatrick15a4bf32014-11-14 10:56:12 -08002277 if dataB != nil {
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002278 return rws.bw.Write(dataB)
Brad Fitzpatrick15a4bf32014-11-14 10:56:12 -08002279 } else {
Brad Fitzpatrick390047e2014-11-14 20:37:08 -08002280 return rws.bw.WriteString(dataS)
Brad Fitzpatrick15a4bf32014-11-14 10:56:12 -08002281 }
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002282}
2283
2284func (w *responseWriter) handlerDone() {
Brad Fitzpatrick729bd722014-11-13 14:09:36 -08002285 rws := w.rws
Brad Fitzpatrick520123b2014-11-14 15:57:37 -08002286 rws.handlerDone = true
2287 w.Flush()
Brad Fitzpatrick729bd722014-11-13 14:09:36 -08002288 w.rws = nil
Brad Fitzpatrick520123b2014-11-14 15:57:37 -08002289 responseWriterStatePool.Put(rws)
Brad Fitzpatrickb331b812014-11-13 11:51:54 -08002290}
Blake Mizeranyb4be4942015-12-15 17:33:14 -08002291
2292// foreachHeaderElement splits v according to the "#rule" construction
2293// in RFC 2616 section 2.1 and calls fn for each non-empty element.
2294func foreachHeaderElement(v string, fn func(string)) {
2295 v = textproto.TrimString(v)
2296 if v == "" {
2297 return
2298 }
2299 if !strings.Contains(v, ",") {
2300 fn(v)
2301 return
2302 }
2303 for _, f := range strings.Split(v, ",") {
2304 if f = textproto.TrimString(f); f != "" {
2305 fn(f)
2306 }
2307 }
2308}