diff options
author | Nathan Dench <ndenc2@gmail.com> | 2019-05-24 15:16:44 +1000 |
---|---|---|
committer | Nathan Dench <ndenc2@gmail.com> | 2019-05-24 15:16:44 +1000 |
commit | 107c1cdb09c575aa2f61d97f48d8587eb6bada4c (patch) | |
tree | ca7d008643efc555c388baeaf1d986e0b6b3e28c /vendor/golang.org/x/net/http2/server.go | |
parent | 844b5a68d8af4791755b8f0ad293cc99f5959183 (diff) | |
download | terraform-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.go | 230 |
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 | |||
28 | import ( | 28 | import ( |
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 | ||
441 | func 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 | |||
434 | func (sc *serverConn) rejectConn(err ErrCode, debug string) { | 450 | func (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 | ||
660 | func (sc *serverConn) canonicalHeader(v string) string { | 676 | func (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 | 914 | var 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. | ||
894 | func (sc *serverConn) readPreface() error { | 919 | func (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. |
1101 | var errHandlerPanicked = errors.New("http2: handler panicked") | 1126 | var 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? | ||
1260 | var goAwayTimeout = 1 * time.Second | ||
1261 | |||
1221 | func (sc *serverConn) startGracefulShutdownInternal() { | 1262 | func (sc *serverConn) startGracefulShutdownInternal() { |
1222 | sc.goAwayIn(ErrCodeNo, 0) | 1263 | sc.goAway(ErrCodeNo) |
1223 | } | 1264 | } |
1224 | 1265 | ||
1225 | func (sc *serverConn) goAway(code ErrCode) { | 1266 | func (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 | |||
1237 | func (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 | ||
2266 | func (cw chunkWriter) Write(p []byte) (n int, err error) { return cw.rws.writeChunk(p) } | 2308 | func (cw chunkWriter) Write(p []byte) (n int, err error) { return cw.rws.writeChunk(p) } |
2267 | 2309 | ||
2268 | func (rws *responseWriterState) hasTrailers() bool { return len(rws.trailers) != 0 } | 2310 | func (rws *responseWriterState) hasTrailers() bool { return len(rws.trailers) > 0 } |
2311 | |||
2312 | func (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. |
2273 | func (rws *responseWriterState) declareTrailer(k string) { | 2324 | func (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. | ||
2549 | func 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 | |||
2481 | func (w *responseWriter) WriteHeader(code int) { | 2566 | func (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 | ||
2489 | func (rws *responseWriterState) writeHeader(code int) { | 2574 | func (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 | 2659 | var _ http.Pusher = (*responseWriter)(nil) |
2574 | // cannot include here because it's only defined in Go 1.8 and later. | ||
2575 | type pushOptions struct { | ||
2576 | Method string | ||
2577 | Header http.Header | ||
2578 | } | ||
2579 | 2660 | ||
2580 | func (w *responseWriter) push(target string, opts pushOptions) error { | 2661 | func (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. |
2763 | func foreachHeaderElement(v string, fn func(string)) { | 2848 | func 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 | ||
2813 | func 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 | |||
2821 | var 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. |