mirror of
https://github.com/golang/go
synced 2024-11-19 15:54:46 -07:00
net/http: update bundled http2
Updates http2 to x/net/http2 git rev 5f9ae10 for: http2: terminate await request cancel goroutine on conn close https://golang.org/cl/108415 http2: don't sniff Content-type in Server when X-Content-Type-Options:nosniff https://golang.org/cl/107295 http2, http/httpguts: move ValidTrailerHeader to new common package http/httpguts https://golang.org/cl/104042 all: remove "the" duplications https://golang.org/cl/94975 http2: use RFC 723x as normative reference in docs https://golang.org/cl/94555 all: use HTTPS for iana.org links https://golang.org/cl/89415 Fixes #24795 Fixes #24776 Updates #23908 Fixes #21974 Change-Id: I7985617a7dde56cc5ed8670d73b26f8307be83d6 Reviewed-on: https://go-review.googlesource.com/111655 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
4ebc67d334
commit
260ae19c89
@ -44,13 +44,14 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"golang_org/x/net/http/httpguts"
|
||||||
"golang_org/x/net/http2/hpack"
|
"golang_org/x/net/http2/hpack"
|
||||||
"golang_org/x/net/idna"
|
"golang_org/x/net/idna"
|
||||||
"golang_org/x/net/lex/httplex"
|
"golang_org/x/net/lex/httplex"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A list of the possible cipher suite ids. Taken from
|
// A list of the possible cipher suite ids. Taken from
|
||||||
// http://www.iana.org/assignments/tls-parameters/tls-parameters.txt
|
// https://www.iana.org/assignments/tls-parameters/tls-parameters.txt
|
||||||
|
|
||||||
const (
|
const (
|
||||||
http2cipher_TLS_NULL_WITH_NULL_NULL uint16 = 0x0000
|
http2cipher_TLS_NULL_WITH_NULL_NULL uint16 = 0x0000
|
||||||
@ -3505,7 +3506,7 @@ func http2mustUint31(v int32) uint32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// bodyAllowedForStatus reports whether a given response status code
|
// bodyAllowedForStatus reports whether a given response status code
|
||||||
// permits a body. See RFC 2616, section 4.4.
|
// permits a body. See RFC 7230, section 3.3.
|
||||||
func http2bodyAllowedForStatus(status int) bool {
|
func http2bodyAllowedForStatus(status int) bool {
|
||||||
switch {
|
switch {
|
||||||
case status >= 100 && status <= 199:
|
case status >= 100 && status <= 199:
|
||||||
@ -4096,7 +4097,7 @@ func (s *http2Server) ServeConn(c net.Conn, opts *http2ServeConnOpts) {
|
|||||||
// addresses during development.
|
// addresses during development.
|
||||||
//
|
//
|
||||||
// TODO: optionally enforce? Or enforce at the time we receive
|
// TODO: optionally enforce? Or enforce at the time we receive
|
||||||
// a new request, and verify the the ServerName matches the :authority?
|
// a new request, and verify the ServerName matches the :authority?
|
||||||
// But that precludes proxy situations, perhaps.
|
// But that precludes proxy situations, perhaps.
|
||||||
//
|
//
|
||||||
// So for now, do nothing here again.
|
// So for now, do nothing here again.
|
||||||
@ -5512,7 +5513,7 @@ func (st *http2stream) processTrailerHeaders(f *http2MetaHeadersFrame) error {
|
|||||||
if st.trailer != nil {
|
if st.trailer != nil {
|
||||||
for _, hf := range f.RegularFields() {
|
for _, hf := range f.RegularFields() {
|
||||||
key := sc.canonicalHeader(hf.Name)
|
key := sc.canonicalHeader(hf.Name)
|
||||||
if !http2ValidTrailerHeader(key) {
|
if !httpguts.ValidTrailerHeader(key) {
|
||||||
// TODO: send more details to the peer somehow. But http2 has
|
// TODO: send more details to the peer somehow. But http2 has
|
||||||
// no way to send debug data at a stream level. Discuss with
|
// no way to send debug data at a stream level. Discuss with
|
||||||
// HTTP folk.
|
// HTTP folk.
|
||||||
@ -5979,8 +5980,8 @@ func (rws *http2responseWriterState) hasTrailers() bool { return len(rws.trailer
|
|||||||
// written in the trailers at the end of the response.
|
// written in the trailers at the end of the response.
|
||||||
func (rws *http2responseWriterState) declareTrailer(k string) {
|
func (rws *http2responseWriterState) declareTrailer(k string) {
|
||||||
k = CanonicalHeaderKey(k)
|
k = CanonicalHeaderKey(k)
|
||||||
if !http2ValidTrailerHeader(k) {
|
if !httpguts.ValidTrailerHeader(k) {
|
||||||
// Forbidden by RFC 2616 14.40.
|
// Forbidden by RFC 7230, section 4.1.2.
|
||||||
rws.conn.logf("ignoring invalid trailer %q", k)
|
rws.conn.logf("ignoring invalid trailer %q", k)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -6018,7 +6019,15 @@ func (rws *http2responseWriterState) writeChunk(p []byte) (n int, err error) {
|
|||||||
}
|
}
|
||||||
_, hasContentType := rws.snapHeader["Content-Type"]
|
_, hasContentType := rws.snapHeader["Content-Type"]
|
||||||
if !hasContentType && http2bodyAllowedForStatus(rws.status) && len(p) > 0 {
|
if !hasContentType && http2bodyAllowedForStatus(rws.status) && len(p) > 0 {
|
||||||
ctype = DetectContentType(p)
|
if cto := rws.snapHeader.Get("X-Content-Type-Options"); strings.EqualFold("nosniff", cto) {
|
||||||
|
// nosniff is an explicit directive not to guess a content-type.
|
||||||
|
// Content-sniffing is no less susceptible to polyglot attacks via
|
||||||
|
// hosted content when done on the server.
|
||||||
|
ctype = "application/octet-stream"
|
||||||
|
rws.conn.logf("http2: WriteHeader called with X-Content-Type-Options:nosniff but no Content-Type")
|
||||||
|
} else {
|
||||||
|
ctype = DetectContentType(p)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var date string
|
var date string
|
||||||
if _, ok := rws.snapHeader["Date"]; !ok {
|
if _, ok := rws.snapHeader["Date"]; !ok {
|
||||||
@ -6101,7 +6110,7 @@ const http2TrailerPrefix = "Trailer:"
|
|||||||
// after the header has already been flushed. Because the Go
|
// after the header has already been flushed. Because the Go
|
||||||
// ResponseWriter interface has no way to set Trailers (only the
|
// ResponseWriter interface has no way to set Trailers (only the
|
||||||
// Header), and because we didn't want to expand the ResponseWriter
|
// Header), and because we didn't want to expand the ResponseWriter
|
||||||
// interface, and because nobody used trailers, and because RFC 2616
|
// interface, and because nobody used trailers, and because RFC 7230
|
||||||
// says you SHOULD (but not must) predeclare any trailers in the
|
// says you SHOULD (but not must) predeclare any trailers in the
|
||||||
// header, the official ResponseWriter rules said trailers in Go must
|
// header, the official ResponseWriter rules said trailers in Go must
|
||||||
// be predeclared, and then we reuse the same ResponseWriter.Header()
|
// be predeclared, and then we reuse the same ResponseWriter.Header()
|
||||||
@ -6485,7 +6494,7 @@ func (sc *http2serverConn) startPush(msg *http2startPushRequest) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// foreachHeaderElement splits v according to the "#rule" construction
|
// foreachHeaderElement splits v according to the "#rule" construction
|
||||||
// in RFC 2616 section 2.1 and calls fn for each non-empty element.
|
// in RFC 7230 section 7 and calls fn for each non-empty element.
|
||||||
func http2foreachHeaderElement(v string, fn func(string)) {
|
func http2foreachHeaderElement(v string, fn func(string)) {
|
||||||
v = textproto.TrimString(v)
|
v = textproto.TrimString(v)
|
||||||
if v == "" {
|
if v == "" {
|
||||||
@ -6533,41 +6542,6 @@ func http2new400Handler(err error) HandlerFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidTrailerHeader reports whether name is a valid header field name to appear
|
|
||||||
// in trailers.
|
|
||||||
// See: http://tools.ietf.org/html/rfc7230#section-4.1.2
|
|
||||||
func http2ValidTrailerHeader(name string) bool {
|
|
||||||
name = CanonicalHeaderKey(name)
|
|
||||||
if strings.HasPrefix(name, "If-") || http2badTrailer[name] {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
var http2badTrailer = map[string]bool{
|
|
||||||
"Authorization": true,
|
|
||||||
"Cache-Control": true,
|
|
||||||
"Connection": true,
|
|
||||||
"Content-Encoding": true,
|
|
||||||
"Content-Length": true,
|
|
||||||
"Content-Range": true,
|
|
||||||
"Content-Type": true,
|
|
||||||
"Expect": true,
|
|
||||||
"Host": true,
|
|
||||||
"Keep-Alive": true,
|
|
||||||
"Max-Forwards": true,
|
|
||||||
"Pragma": true,
|
|
||||||
"Proxy-Authenticate": true,
|
|
||||||
"Proxy-Authorization": true,
|
|
||||||
"Proxy-Connection": true,
|
|
||||||
"Range": true,
|
|
||||||
"Realm": true,
|
|
||||||
"Te": true,
|
|
||||||
"Trailer": true,
|
|
||||||
"Transfer-Encoding": true,
|
|
||||||
"Www-Authenticate": true,
|
|
||||||
}
|
|
||||||
|
|
||||||
// h1ServerKeepAlivesDisabled reports whether hs has its keep-alives
|
// h1ServerKeepAlivesDisabled reports whether hs has its keep-alives
|
||||||
// disabled. See comments on h1ServerShutdownChan above for why
|
// disabled. See comments on h1ServerShutdownChan above for why
|
||||||
// the code is written this way.
|
// the code is written this way.
|
||||||
@ -6856,10 +6830,12 @@ func (sew http2stickyErrWriter) Write(p []byte) (n int, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// noCachedConnError is the concrete type of ErrNoCachedConn, needs to be detected
|
// noCachedConnError is the concrete type of ErrNoCachedConn, which
|
||||||
// by net/http regardless of whether it's its bundled version (in h2_bundle.go with a rewritten type name)
|
// needs to be detected by net/http regardless of whether it's its
|
||||||
// or from a user's x/net/http2. As such, as it has a unique method name (IsHTTP2NoCachedConnError) that
|
// bundled version (in h2_bundle.go with a rewritten type name) or
|
||||||
// net/http sniffs for via func isNoCachedConnError.
|
// from a user's x/net/http2. As such, as it has a unique method name
|
||||||
|
// (IsHTTP2NoCachedConnError) that net/http sniffs for via func
|
||||||
|
// isNoCachedConnError.
|
||||||
type http2noCachedConnError struct{}
|
type http2noCachedConnError struct{}
|
||||||
|
|
||||||
func (http2noCachedConnError) IsHTTP2NoCachedConnError() {}
|
func (http2noCachedConnError) IsHTTP2NoCachedConnError() {}
|
||||||
@ -6870,9 +6846,7 @@ func (http2noCachedConnError) Error() string { return "http2: no cached connecti
|
|||||||
// or its equivalent renamed type in net/http2's h2_bundle.go. Both types
|
// or its equivalent renamed type in net/http2's h2_bundle.go. Both types
|
||||||
// may coexist in the same running program.
|
// may coexist in the same running program.
|
||||||
func http2isNoCachedConnError(err error) bool {
|
func http2isNoCachedConnError(err error) bool {
|
||||||
_, ok := err.(interface {
|
_, ok := err.(interface{ IsHTTP2NoCachedConnError() })
|
||||||
IsHTTP2NoCachedConnError()
|
|
||||||
})
|
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user