aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/golang.org/x/net/http2/server.go
diff options
context:
space:
mode:
authorNathan Dench <ndenc2@gmail.com>2019-05-24 15:16:44 +1000
committerNathan Dench <ndenc2@gmail.com>2019-05-24 15:16:44 +1000
commit107c1cdb09c575aa2f61d97f48d8587eb6bada4c (patch)
treeca7d008643efc555c388baeaf1d986e0b6b3e28c /vendor/golang.org/x/net/http2/server.go
parent844b5a68d8af4791755b8f0ad293cc99f5959183 (diff)
downloadterraform-provider-statuscake-107c1cdb09c575aa2f61d97f48d8587eb6bada4c.tar.gz
terraform-provider-statuscake-107c1cdb09c575aa2f61d97f48d8587eb6bada4c.tar.zst
terraform-provider-statuscake-107c1cdb09c575aa2f61d97f48d8587eb6bada4c.zip
Upgrade to 0.12
Diffstat (limited to 'vendor/golang.org/x/net/http2/server.go')
-rw-r--r--vendor/golang.org/x/net/http2/server.go230
1 files changed, 140 insertions, 90 deletions
diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go
index eae143d..d4abeb2 100644
--- a/vendor/golang.org/x/net/http2/server.go
+++ b/vendor/golang.org/x/net/http2/server.go
@@ -28,6 +28,7 @@ package http2
28import ( 28import (
29 "bufio" 29 "bufio"
30 "bytes" 30 "bytes"
31 "context"
31 "crypto/tls" 32 "crypto/tls"
32 "errors" 33 "errors"
33 "fmt" 34 "fmt"
@@ -46,6 +47,7 @@ import (
46 "sync" 47 "sync"
47 "time" 48 "time"
48 49
50 "golang.org/x/net/http/httpguts"
49 "golang.org/x/net/http2/hpack" 51 "golang.org/x/net/http2/hpack"
50) 52)
51 53
@@ -208,24 +210,29 @@ func ConfigureServer(s *http.Server, conf *Server) error {
208 conf = new(Server) 210 conf = new(Server)
209 } 211 }
210 conf.state = &serverInternalState{activeConns: make(map[*serverConn]struct{})} 212 conf.state = &serverInternalState{activeConns: make(map[*serverConn]struct{})}
211 if err := configureServer18(s, conf); err != nil { 213 if h1, h2 := s, conf; h2.IdleTimeout == 0 {
212 return err 214 if h1.IdleTimeout != 0 {
213 } 215 h2.IdleTimeout = h1.IdleTimeout
214 if err := configureServer19(s, conf); err != nil { 216 } else {
215 return err 217 h2.IdleTimeout = h1.ReadTimeout
218 }
216 } 219 }
220 s.RegisterOnShutdown(conf.state.startGracefulShutdown)
217 221
218 if s.TLSConfig == nil { 222 if s.TLSConfig == nil {
219 s.TLSConfig = new(tls.Config) 223 s.TLSConfig = new(tls.Config)
220 } else if s.TLSConfig.CipherSuites != nil { 224 } else if s.TLSConfig.CipherSuites != nil {
221 // If they already provided a CipherSuite list, return 225 // If they already provided a CipherSuite list, return
222 // an error if it has a bad order or is missing 226 // an error if it has a bad order or is missing
223 // ECDHE_RSA_WITH_AES_128_GCM_SHA256. 227 // ECDHE_RSA_WITH_AES_128_GCM_SHA256 or ECDHE_ECDSA_WITH_AES_128_GCM_SHA256.
224 const requiredCipher = tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
225 haveRequired := false 228 haveRequired := false
226 sawBad := false 229 sawBad := false
227 for i, cs := range s.TLSConfig.CipherSuites { 230 for i, cs := range s.TLSConfig.CipherSuites {
228 if cs == requiredCipher { 231 switch cs {
232 case tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
233 // Alternative MTI cipher to not discourage ECDSA-only servers.
234 // See http://golang.org/cl/30721 for further information.
235 tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
229 haveRequired = true 236 haveRequired = true
230 } 237 }
231 if isBadCipher(cs) { 238 if isBadCipher(cs) {
@@ -235,7 +242,7 @@ func ConfigureServer(s *http.Server, conf *Server) error {
235 } 242 }
236 } 243 }
237 if !haveRequired { 244 if !haveRequired {
238 return fmt.Errorf("http2: TLSConfig.CipherSuites is missing HTTP/2-required TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256") 245 return fmt.Errorf("http2: TLSConfig.CipherSuites is missing an HTTP/2-required AES_128_GCM_SHA256 cipher.")
239 } 246 }
240 } 247 }
241 248
@@ -403,7 +410,7 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) {
403 // addresses during development. 410 // addresses during development.
404 // 411 //
405 // TODO: optionally enforce? Or enforce at the time we receive 412 // TODO: optionally enforce? Or enforce at the time we receive
406 // a new request, and verify the the ServerName matches the :authority? 413 // a new request, and verify the ServerName matches the :authority?
407 // But that precludes proxy situations, perhaps. 414 // But that precludes proxy situations, perhaps.
408 // 415 //
409 // So for now, do nothing here again. 416 // So for now, do nothing here again.
@@ -431,6 +438,15 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) {
431 sc.serve() 438 sc.serve()
432} 439}
433 440
441func serverConnBaseContext(c net.Conn, opts *ServeConnOpts) (ctx context.Context, cancel func()) {
442 ctx, cancel = context.WithCancel(context.Background())
443 ctx = context.WithValue(ctx, http.LocalAddrContextKey, c.LocalAddr())
444 if hs := opts.baseConfig(); hs != nil {
445 ctx = context.WithValue(ctx, http.ServerContextKey, hs)
446 }
447 return
448}
449
434func (sc *serverConn) rejectConn(err ErrCode, debug string) { 450func (sc *serverConn) rejectConn(err ErrCode, debug string) {
435 sc.vlogf("http2: server rejecting conn: %v, %s", err, debug) 451 sc.vlogf("http2: server rejecting conn: %v, %s", err, debug)
436 // ignoring errors. hanging up anyway. 452 // ignoring errors. hanging up anyway.
@@ -446,7 +462,7 @@ type serverConn struct {
446 conn net.Conn 462 conn net.Conn
447 bw *bufferedWriter // writing to conn 463 bw *bufferedWriter // writing to conn
448 handler http.Handler 464 handler http.Handler
449 baseCtx contextContext 465 baseCtx context.Context
450 framer *Framer 466 framer *Framer
451 doneServing chan struct{} // closed when serverConn.serve ends 467 doneServing chan struct{} // closed when serverConn.serve ends
452 readFrameCh chan readFrameResult // written by serverConn.readFrames 468 readFrameCh chan readFrameResult // written by serverConn.readFrames
@@ -526,7 +542,7 @@ type stream struct {
526 id uint32 542 id uint32
527 body *pipe // non-nil if expecting DATA frames 543 body *pipe // non-nil if expecting DATA frames
528 cw closeWaiter // closed wait stream transitions to closed state 544 cw closeWaiter // closed wait stream transitions to closed state
529 ctx contextContext 545 ctx context.Context
530 cancelCtx func() 546 cancelCtx func()
531 547
532 // owned by serverConn's serve loop: 548 // owned by serverConn's serve loop:
@@ -649,7 +665,7 @@ func (sc *serverConn) condlogf(err error, format string, args ...interface{}) {
649 if err == nil { 665 if err == nil {
650 return 666 return
651 } 667 }
652 if err == io.EOF || err == io.ErrUnexpectedEOF || isClosedConnError(err) { 668 if err == io.EOF || err == io.ErrUnexpectedEOF || isClosedConnError(err) || err == errPrefaceTimeout {
653 // Boring, expected errors. 669 // Boring, expected errors.
654 sc.vlogf(format, args...) 670 sc.vlogf(format, args...)
655 } else { 671 } else {
@@ -659,6 +675,7 @@ func (sc *serverConn) condlogf(err error, format string, args ...interface{}) {
659 675
660func (sc *serverConn) canonicalHeader(v string) string { 676func (sc *serverConn) canonicalHeader(v string) string {
661 sc.serveG.check() 677 sc.serveG.check()
678 buildCommonHeaderMapsOnce()
662 cv, ok := commonCanonHeader[v] 679 cv, ok := commonCanonHeader[v]
663 if ok { 680 if ok {
664 return cv 681 return cv
@@ -853,8 +870,13 @@ func (sc *serverConn) serve() {
853 } 870 }
854 } 871 }
855 872
856 if sc.inGoAway && sc.curOpenStreams() == 0 && !sc.needToSendGoAway && !sc.writingFrame { 873 // Start the shutdown timer after sending a GOAWAY. When sending GOAWAY
857 return 874 // with no error code (graceful shutdown), don't start the timer until
875 // all open streams have been completed.
876 sentGoAway := sc.inGoAway && !sc.needToSendGoAway && !sc.writingFrame
877 gracefulShutdownComplete := sc.goAwayCode == ErrCodeNo && sc.curOpenStreams() == 0
878 if sentGoAway && sc.shutdownTimer == nil && (sc.goAwayCode != ErrCodeNo || gracefulShutdownComplete) {
879 sc.shutDownIn(goAwayTimeout)
858 } 880 }
859 } 881 }
860} 882}
@@ -889,8 +911,11 @@ func (sc *serverConn) sendServeMsg(msg interface{}) {
889 } 911 }
890} 912}
891 913
892// readPreface reads the ClientPreface greeting from the peer 914var errPrefaceTimeout = errors.New("timeout waiting for client preface")
893// or returns an error on timeout or an invalid greeting. 915
916// readPreface reads the ClientPreface greeting from the peer or
917// returns errPrefaceTimeout on timeout, or an error if the greeting
918// is invalid.
894func (sc *serverConn) readPreface() error { 919func (sc *serverConn) readPreface() error {
895 errc := make(chan error, 1) 920 errc := make(chan error, 1)
896 go func() { 921 go func() {
@@ -908,7 +933,7 @@ func (sc *serverConn) readPreface() error {
908 defer timer.Stop() 933 defer timer.Stop()
909 select { 934 select {
910 case <-timer.C: 935 case <-timer.C:
911 return errors.New("timeout waiting for client preface") 936 return errPrefaceTimeout
912 case err := <-errc: 937 case err := <-errc:
913 if err == nil { 938 if err == nil {
914 if VerboseLogs { 939 if VerboseLogs {
@@ -1097,7 +1122,7 @@ func (sc *serverConn) startFrameWrite(wr FrameWriteRequest) {
1097 1122
1098// errHandlerPanicked is the error given to any callers blocked in a read from 1123// errHandlerPanicked is the error given to any callers blocked in a read from
1099// Request.Body when the main goroutine panics. Since most handlers read in the 1124// Request.Body when the main goroutine panics. Since most handlers read in the
1100// the main ServeHTTP goroutine, this will show up rarely. 1125// main ServeHTTP goroutine, this will show up rarely.
1101var errHandlerPanicked = errors.New("http2: handler panicked") 1126var errHandlerPanicked = errors.New("http2: handler panicked")
1102 1127
1103// wroteFrame is called on the serve goroutine with the result of 1128// wroteFrame is called on the serve goroutine with the result of
@@ -1218,30 +1243,31 @@ func (sc *serverConn) startGracefulShutdown() {
1218 sc.shutdownOnce.Do(func() { sc.sendServeMsg(gracefulShutdownMsg) }) 1243 sc.shutdownOnce.Do(func() { sc.sendServeMsg(gracefulShutdownMsg) })
1219} 1244}
1220 1245
1246// After sending GOAWAY, the connection will close after goAwayTimeout.
1247// If we close the connection immediately after sending GOAWAY, there may
1248// be unsent data in our kernel receive buffer, which will cause the kernel
1249// to send a TCP RST on close() instead of a FIN. This RST will abort the
1250// connection immediately, whether or not the client had received the GOAWAY.
1251//
1252// Ideally we should delay for at least 1 RTT + epsilon so the client has
1253// a chance to read the GOAWAY and stop sending messages. Measuring RTT
1254// is hard, so we approximate with 1 second. See golang.org/issue/18701.
1255//
1256// This is a var so it can be shorter in tests, where all requests uses the
1257// loopback interface making the expected RTT very small.
1258//
1259// TODO: configurable?
1260var goAwayTimeout = 1 * time.Second
1261
1221func (sc *serverConn) startGracefulShutdownInternal() { 1262func (sc *serverConn) startGracefulShutdownInternal() {
1222 sc.goAwayIn(ErrCodeNo, 0) 1263 sc.goAway(ErrCodeNo)
1223} 1264}
1224 1265
1225func (sc *serverConn) goAway(code ErrCode) { 1266func (sc *serverConn) goAway(code ErrCode) {
1226 sc.serveG.check() 1267 sc.serveG.check()
1227 var forceCloseIn time.Duration
1228 if code != ErrCodeNo {
1229 forceCloseIn = 250 * time.Millisecond
1230 } else {
1231 // TODO: configurable
1232 forceCloseIn = 1 * time.Second
1233 }
1234 sc.goAwayIn(code, forceCloseIn)
1235}
1236
1237func (sc *serverConn) goAwayIn(code ErrCode, forceCloseIn time.Duration) {
1238 sc.serveG.check()
1239 if sc.inGoAway { 1268 if sc.inGoAway {
1240 return 1269 return
1241 } 1270 }
1242 if forceCloseIn != 0 {
1243 sc.shutDownIn(forceCloseIn)
1244 }
1245 sc.inGoAway = true 1271 sc.inGoAway = true
1246 sc.needToSendGoAway = true 1272 sc.needToSendGoAway = true
1247 sc.goAwayCode = code 1273 sc.goAwayCode = code
@@ -1474,6 +1500,12 @@ func (sc *serverConn) processSettings(f *SettingsFrame) error {
1474 } 1500 }
1475 return nil 1501 return nil
1476 } 1502 }
1503 if f.NumSettings() > 100 || f.HasDuplicates() {
1504 // This isn't actually in the spec, but hang up on
1505 // suspiciously large settings frames or those with
1506 // duplicate entries.
1507 return ConnectionError(ErrCodeProtocol)
1508 }
1477 if err := f.ForeachSetting(sc.processSetting); err != nil { 1509 if err := f.ForeachSetting(sc.processSetting); err != nil {
1478 return err 1510 return err
1479 } 1511 }
@@ -1595,7 +1627,10 @@ func (sc *serverConn) processData(f *DataFrame) error {
1595 // Sender sending more than they'd declared? 1627 // Sender sending more than they'd declared?
1596 if st.declBodyBytes != -1 && st.bodyBytes+int64(len(data)) > st.declBodyBytes { 1628 if st.declBodyBytes != -1 && st.bodyBytes+int64(len(data)) > st.declBodyBytes {
1597 st.body.CloseWithError(fmt.Errorf("sender tried to send more than declared Content-Length of %d bytes", st.declBodyBytes)) 1629 st.body.CloseWithError(fmt.Errorf("sender tried to send more than declared Content-Length of %d bytes", st.declBodyBytes))
1598 return streamError(id, ErrCodeStreamClosed) 1630 // RFC 7540, sec 8.1.2.6: A request or response is also malformed if the
1631 // value of a content-length header field does not equal the sum of the
1632 // DATA frame payload lengths that form the body.
1633 return streamError(id, ErrCodeProtocol)
1599 } 1634 }
1600 if f.Length > 0 { 1635 if f.Length > 0 {
1601 // Check whether the client has flow control quota. 1636 // Check whether the client has flow control quota.
@@ -1705,6 +1740,13 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error {
1705 // processing this frame. 1740 // processing this frame.
1706 return nil 1741 return nil
1707 } 1742 }
1743 // RFC 7540, sec 5.1: If an endpoint receives additional frames, other than
1744 // WINDOW_UPDATE, PRIORITY, or RST_STREAM, for a stream that is in
1745 // this state, it MUST respond with a stream error (Section 5.4.2) of
1746 // type STREAM_CLOSED.
1747 if st.state == stateHalfClosedRemote {
1748 return streamError(id, ErrCodeStreamClosed)
1749 }
1708 return st.processTrailerHeaders(f) 1750 return st.processTrailerHeaders(f)
1709 } 1751 }
1710 1752
@@ -1805,7 +1847,7 @@ func (st *stream) processTrailerHeaders(f *MetaHeadersFrame) error {
1805 if st.trailer != nil { 1847 if st.trailer != nil {
1806 for _, hf := range f.RegularFields() { 1848 for _, hf := range f.RegularFields() {
1807 key := sc.canonicalHeader(hf.Name) 1849 key := sc.canonicalHeader(hf.Name)
1808 if !ValidTrailerHeader(key) { 1850 if !httpguts.ValidTrailerHeader(key) {
1809 // TODO: send more details to the peer somehow. But http2 has 1851 // TODO: send more details to the peer somehow. But http2 has
1810 // no way to send debug data at a stream level. Discuss with 1852 // no way to send debug data at a stream level. Discuss with
1811 // HTTP folk. 1853 // HTTP folk.
@@ -1846,7 +1888,7 @@ func (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream
1846 panic("internal error: cannot create stream with id 0") 1888 panic("internal error: cannot create stream with id 0")
1847 } 1889 }
1848 1890
1849 ctx, cancelCtx := contextWithCancel(sc.baseCtx) 1891 ctx, cancelCtx := context.WithCancel(sc.baseCtx)
1850 st := &stream{ 1892 st := &stream{
1851 sc: sc, 1893 sc: sc,
1852 id: id, 1894 id: id,
@@ -2012,7 +2054,7 @@ func (sc *serverConn) newWriterAndRequestNoBody(st *stream, rp requestParam) (*r
2012 Body: body, 2054 Body: body,
2013 Trailer: trailer, 2055 Trailer: trailer,
2014 } 2056 }
2015 req = requestWithContext(req, st.ctx) 2057 req = req.WithContext(st.ctx)
2016 2058
2017 rws := responseWriterStatePool.Get().(*responseWriterState) 2059 rws := responseWriterStatePool.Get().(*responseWriterState)
2018 bwSave := rws.bw 2060 bwSave := rws.bw
@@ -2040,7 +2082,7 @@ func (sc *serverConn) runHandler(rw *responseWriter, req *http.Request, handler
2040 stream: rw.rws.stream, 2082 stream: rw.rws.stream,
2041 }) 2083 })
2042 // Same as net/http: 2084 // Same as net/http:
2043 if shouldLogPanic(e) { 2085 if e != nil && e != http.ErrAbortHandler {
2044 const size = 64 << 10 2086 const size = 64 << 10
2045 buf := make([]byte, size) 2087 buf := make([]byte, size)
2046 buf = buf[:runtime.Stack(buf, false)] 2088 buf = buf[:runtime.Stack(buf, false)]
@@ -2265,15 +2307,24 @@ type chunkWriter struct{ rws *responseWriterState }
2265 2307
2266func (cw chunkWriter) Write(p []byte) (n int, err error) { return cw.rws.writeChunk(p) } 2308func (cw chunkWriter) Write(p []byte) (n int, err error) { return cw.rws.writeChunk(p) }
2267 2309
2268func (rws *responseWriterState) hasTrailers() bool { return len(rws.trailers) != 0 } 2310func (rws *responseWriterState) hasTrailers() bool { return len(rws.trailers) > 0 }
2311
2312func (rws *responseWriterState) hasNonemptyTrailers() bool {
2313 for _, trailer := range rws.trailers {
2314 if _, ok := rws.handlerHeader[trailer]; ok {
2315 return true
2316 }
2317 }
2318 return false
2319}
2269 2320
2270// declareTrailer is called for each Trailer header when the 2321// declareTrailer is called for each Trailer header when the
2271// response header is written. It notes that a header will need to be 2322// response header is written. It notes that a header will need to be
2272// written in the trailers at the end of the response. 2323// written in the trailers at the end of the response.
2273func (rws *responseWriterState) declareTrailer(k string) { 2324func (rws *responseWriterState) declareTrailer(k string) {
2274 k = http.CanonicalHeaderKey(k) 2325 k = http.CanonicalHeaderKey(k)
2275 if !ValidTrailerHeader(k) { 2326 if !httpguts.ValidTrailerHeader(k) {
2276 // Forbidden by RFC 2616 14.40. 2327 // Forbidden by RFC 7230, section 4.1.2.
2277 rws.conn.logf("ignoring invalid trailer %q", k) 2328 rws.conn.logf("ignoring invalid trailer %q", k)
2278 return 2329 return
2279 } 2330 }
@@ -2310,7 +2361,7 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
2310 clen = strconv.Itoa(len(p)) 2361 clen = strconv.Itoa(len(p))
2311 } 2362 }
2312 _, hasContentType := rws.snapHeader["Content-Type"] 2363 _, hasContentType := rws.snapHeader["Content-Type"]
2313 if !hasContentType && bodyAllowedForStatus(rws.status) { 2364 if !hasContentType && bodyAllowedForStatus(rws.status) && len(p) > 0 {
2314 ctype = http.DetectContentType(p) 2365 ctype = http.DetectContentType(p)
2315 } 2366 }
2316 var date string 2367 var date string
@@ -2323,6 +2374,19 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
2323 foreachHeaderElement(v, rws.declareTrailer) 2374 foreachHeaderElement(v, rws.declareTrailer)
2324 } 2375 }
2325 2376
2377 // "Connection" headers aren't allowed in HTTP/2 (RFC 7540, 8.1.2.2),
2378 // but respect "Connection" == "close" to mean sending a GOAWAY and tearing
2379 // down the TCP connection when idle, like we do for HTTP/1.
2380 // TODO: remove more Connection-specific header fields here, in addition
2381 // to "Connection".
2382 if _, ok := rws.snapHeader["Connection"]; ok {
2383 v := rws.snapHeader.Get("Connection")
2384 delete(rws.snapHeader, "Connection")
2385 if v == "close" {
2386 rws.conn.startGracefulShutdown()
2387 }
2388 }
2389
2326 endStream := (rws.handlerDone && !rws.hasTrailers() && len(p) == 0) || isHeadResp 2390 endStream := (rws.handlerDone && !rws.hasTrailers() && len(p) == 0) || isHeadResp
2327 err = rws.conn.writeHeaders(rws.stream, &writeResHeaders{ 2391 err = rws.conn.writeHeaders(rws.stream, &writeResHeaders{
2328 streamID: rws.stream.id, 2392 streamID: rws.stream.id,
@@ -2352,7 +2416,10 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
2352 rws.promoteUndeclaredTrailers() 2416 rws.promoteUndeclaredTrailers()
2353 } 2417 }
2354 2418
2355 endStream := rws.handlerDone && !rws.hasTrailers() 2419 // only send trailers if they have actually been defined by the
2420 // server handler.
2421 hasNonemptyTrailers := rws.hasNonemptyTrailers()
2422 endStream := rws.handlerDone && !hasNonemptyTrailers
2356 if len(p) > 0 || endStream { 2423 if len(p) > 0 || endStream {
2357 // only send a 0 byte DATA frame if we're ending the stream. 2424 // only send a 0 byte DATA frame if we're ending the stream.
2358 if err := rws.conn.writeDataFromHandler(rws.stream, p, endStream); err != nil { 2425 if err := rws.conn.writeDataFromHandler(rws.stream, p, endStream); err != nil {
@@ -2361,7 +2428,7 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
2361 } 2428 }
2362 } 2429 }
2363 2430
2364 if rws.handlerDone && rws.hasTrailers() { 2431 if rws.handlerDone && hasNonemptyTrailers {
2365 err = rws.conn.writeHeaders(rws.stream, &writeResHeaders{ 2432 err = rws.conn.writeHeaders(rws.stream, &writeResHeaders{
2366 streamID: rws.stream.id, 2433 streamID: rws.stream.id,
2367 h: rws.handlerHeader, 2434 h: rws.handlerHeader,
@@ -2394,7 +2461,7 @@ const TrailerPrefix = "Trailer:"
2394// after the header has already been flushed. Because the Go 2461// after the header has already been flushed. Because the Go
2395// ResponseWriter interface has no way to set Trailers (only the 2462// ResponseWriter interface has no way to set Trailers (only the
2396// Header), and because we didn't want to expand the ResponseWriter 2463// Header), and because we didn't want to expand the ResponseWriter
2397// interface, and because nobody used trailers, and because RFC 2616 2464// interface, and because nobody used trailers, and because RFC 7230
2398// says you SHOULD (but not must) predeclare any trailers in the 2465// says you SHOULD (but not must) predeclare any trailers in the
2399// header, the official ResponseWriter rules said trailers in Go must 2466// header, the official ResponseWriter rules said trailers in Go must
2400// be predeclared, and then we reuse the same ResponseWriter.Header() 2467// be predeclared, and then we reuse the same ResponseWriter.Header()
@@ -2478,6 +2545,24 @@ func (w *responseWriter) Header() http.Header {
2478 return rws.handlerHeader 2545 return rws.handlerHeader
2479} 2546}
2480 2547
2548// checkWriteHeaderCode is a copy of net/http's checkWriteHeaderCode.
2549func checkWriteHeaderCode(code int) {
2550 // Issue 22880: require valid WriteHeader status codes.
2551 // For now we only enforce that it's three digits.
2552 // In the future we might block things over 599 (600 and above aren't defined
2553 // at http://httpwg.org/specs/rfc7231.html#status.codes)
2554 // and we might block under 200 (once we have more mature 1xx support).
2555 // But for now any three digits.
2556 //
2557 // We used to send "HTTP/1.1 000 0" on the wire in responses but there's
2558 // no equivalent bogus thing we can realistically send in HTTP/2,
2559 // so we'll consistently panic instead and help people find their bugs
2560 // early. (We can't return an error from WriteHeader even if we wanted to.)
2561 if code < 100 || code > 999 {
2562 panic(fmt.Sprintf("invalid WriteHeader code %v", code))
2563 }
2564}
2565
2481func (w *responseWriter) WriteHeader(code int) { 2566func (w *responseWriter) WriteHeader(code int) {
2482 rws := w.rws 2567 rws := w.rws
2483 if rws == nil { 2568 if rws == nil {
@@ -2488,6 +2573,7 @@ func (w *responseWriter) WriteHeader(code int) {
2488 2573
2489func (rws *responseWriterState) writeHeader(code int) { 2574func (rws *responseWriterState) writeHeader(code int) {
2490 if !rws.wroteHeader { 2575 if !rws.wroteHeader {
2576 checkWriteHeaderCode(code)
2491 rws.wroteHeader = true 2577 rws.wroteHeader = true
2492 rws.status = code 2578 rws.status = code
2493 if len(rws.handlerHeader) > 0 { 2579 if len(rws.handlerHeader) > 0 {
@@ -2570,14 +2656,9 @@ var (
2570 ErrPushLimitReached = errors.New("http2: push would exceed peer's SETTINGS_MAX_CONCURRENT_STREAMS") 2656 ErrPushLimitReached = errors.New("http2: push would exceed peer's SETTINGS_MAX_CONCURRENT_STREAMS")
2571) 2657)
2572 2658
2573// pushOptions is the internal version of http.PushOptions, which we 2659var _ http.Pusher = (*responseWriter)(nil)
2574// cannot include here because it's only defined in Go 1.8 and later.
2575type pushOptions struct {
2576 Method string
2577 Header http.Header
2578}
2579 2660
2580func (w *responseWriter) push(target string, opts pushOptions) error { 2661func (w *responseWriter) Push(target string, opts *http.PushOptions) error {
2581 st := w.rws.stream 2662 st := w.rws.stream
2582 sc := st.sc 2663 sc := st.sc
2583 sc.serveG.checkNotOn() 2664 sc.serveG.checkNotOn()
@@ -2588,6 +2669,10 @@ func (w *responseWriter) push(target string, opts pushOptions) error {
2588 return ErrRecursivePush 2669 return ErrRecursivePush
2589 } 2670 }
2590 2671
2672 if opts == nil {
2673 opts = new(http.PushOptions)
2674 }
2675
2591 // Default options. 2676 // Default options.
2592 if opts.Method == "" { 2677 if opts.Method == "" {
2593 opts.Method = "GET" 2678 opts.Method = "GET"
@@ -2759,7 +2844,7 @@ func (sc *serverConn) startPush(msg *startPushRequest) {
2759} 2844}
2760 2845
2761// foreachHeaderElement splits v according to the "#rule" construction 2846// foreachHeaderElement splits v according to the "#rule" construction
2762// in RFC 2616 section 2.1 and calls fn for each non-empty element. 2847// in RFC 7230 section 7 and calls fn for each non-empty element.
2763func foreachHeaderElement(v string, fn func(string)) { 2848func foreachHeaderElement(v string, fn func(string)) {
2764 v = textproto.TrimString(v) 2849 v = textproto.TrimString(v)
2765 if v == "" { 2850 if v == "" {
@@ -2807,41 +2892,6 @@ func new400Handler(err error) http.HandlerFunc {
2807 } 2892 }
2808} 2893}
2809 2894
2810// ValidTrailerHeader reports whether name is a valid header field name to appear
2811// in trailers.
2812// See: http://tools.ietf.org/html/rfc7230#section-4.1.2
2813func ValidTrailerHeader(name string) bool {
2814 name = http.CanonicalHeaderKey(name)
2815 if strings.HasPrefix(name, "If-") || badTrailer[name] {
2816 return false
2817 }
2818 return true
2819}
2820
2821var badTrailer = map[string]bool{
2822 "Authorization": true,
2823 "Cache-Control": true,
2824 "Connection": true,
2825 "Content-Encoding": true,
2826 "Content-Length": true,
2827 "Content-Range": true,
2828 "Content-Type": true,
2829 "Expect": true,
2830 "Host": true,
2831 "Keep-Alive": true,
2832 "Max-Forwards": true,
2833 "Pragma": true,
2834 "Proxy-Authenticate": true,
2835 "Proxy-Authorization": true,
2836 "Proxy-Connection": true,
2837 "Range": true,
2838 "Realm": true,
2839 "Te": true,
2840 "Trailer": true,
2841 "Transfer-Encoding": true,
2842 "Www-Authenticate": true,
2843}
2844
2845// h1ServerKeepAlivesDisabled reports whether hs has its keep-alives 2895// h1ServerKeepAlivesDisabled reports whether hs has its keep-alives
2846// disabled. See comments on h1ServerShutdownChan above for why 2896// disabled. See comments on h1ServerShutdownChan above for why
2847// the code is written this way. 2897// the code is written this way.