1
0
mirror of https://github.com/golang/go synced 2024-11-23 19:30:05 -07:00

net/http: update bundled http2

Updates http2 to x/net git rev 0e6d34ef942 for https://golang.org/cl/18472
which means we'll get to delete a ton of grpc-go code and just use the
standard library's HTTP client instead.

Also, the comments in this CL aren't entirely accurate it turns out.
RFC 2616 says:

"The Trailer header field can be used to indicate which header fields
are included in a trailer (see section 14.40)."

And 14.40:

"  An HTTP/1.1 message SHOULD include a Trailer header field in a
   message using chunked transfer-coding with a non-empty trailer. Doing
   so allows the recipient to know which header fields to expect in the
   trailer.

   If no Trailer header field is present, the trailer SHOULD NOT include
   any header fields. See section 3.6.1 for restrictions on the use of
   trailer fields in a "chunked" transfer-coding."

So it's really a SHOULD more than a MUST.

And gRPC (at least Google's server) doesn't predeclare "grpc-status"
ahead of time in a Trailer Header, so we'll be lenient. We were too
strict anyway. It's also not a concern for the Go client we have a
different place to populate the Trailers, and it won't confuse clients
which aren't looking for them. The ResponseWriter server side is more
complicated (and strict), though, since we don't want to widen the
ResponseWriter interface. So the Go server still requires that you
predeclare Trailers.

Change-Id: Ia2defc11a2469fb8570ecfabb8453537121084eb
Reviewed-on: https://go-review.googlesource.com/18473
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
Brad Fitzpatrick 2016-01-09 15:34:56 -08:00
parent 2747ca351e
commit 9ee72f424c

View File

@ -24,6 +24,7 @@ import (
"encoding/binary"
"errors"
"fmt"
"golang.org/x/net/http2/hpack"
"io"
"io/ioutil"
"log"
@ -37,8 +38,6 @@ import (
"strings"
"sync"
"time"
"golang.org/x/net/http2/hpack"
)
// ClientConnPool manages a pool of HTTP/2 client connections.
@ -4348,8 +4347,8 @@ type http2clientStream struct {
pastHeaders bool // got HEADERS w/ END_HEADERS
pastTrailers bool // got second HEADERS frame w/ END_HEADERS
trailer Header // accumulated trailers
resTrailer Header // client's Response.Trailer
trailer Header // accumulated trailers
resTrailer *Header // client's Response.Trailer
}
// awaitRequestCancel runs in its own goroutine and waits for the user
@ -5255,7 +5254,7 @@ func (rl *http2clientConnReadLoop) processHeaderBlockFragment(frag []byte, strea
}
}
cs.resTrailer = res.Trailer
cs.resTrailer = &res.Trailer
rl.activeRes[cs.ID] = cs
cs.resc <- http2resAndError{res: res}
rl.nextRes = nil
@ -5383,7 +5382,11 @@ func (rl *http2clientConnReadLoop) endStream(cs *http2clientStream) {
func (cs *http2clientStream) copyTrailers() {
for k, vv := range cs.trailer {
cs.resTrailer[k] = vv
t := cs.resTrailer
if *t == nil {
*t = make(Header)
}
(*t)[k] = vv
}
}
@ -5583,7 +5586,12 @@ func (rl *http2clientConnReadLoop) onNewTrailerField(cs *http2clientStream, f hp
}
key := CanonicalHeaderKey(f.Name)
if _, ok := cs.resTrailer[key]; ok {
// The spec says one must predeclare their trailers but in practice
// popular users (which is to say the only user we found) do not so we
// violate the spec and accept all of them.
const acceptAllTrailers = true
if _, ok := (*cs.resTrailer)[key]; ok || acceptAllTrailers {
if cs.trailer == nil {
cs.trailer = make(Header)
}