aboutsummaryrefslogtreecommitdiff
path: root/src/net/http/h2_bundle.go
diff options
context:
space:
mode:
authorTom Bergan <tombergan@google.com>2016-05-27 16:53:13 -0700
committerAndrew Gerrand <adg@golang.org>2016-06-01 23:15:34 +0000
commitf6c0241999bffe0fe52e8b7f5bbcc8f9e02edbdf (patch)
tree682673dc51e9bdd047e5a92b3286c74da476b408 /src/net/http/h2_bundle.go
parentd0c1888739ac0d5d0c9f82a4b86945c0351caef6 (diff)
downloadgo-f6c0241999bffe0fe52e8b7f5bbcc8f9e02edbdf.tar.xz
net/http: update bundled http2
Updates x/net/http2 to git rev 6bdd4be4 for CL 23526: http2: GotFirstResponseByte hook should only fire once Also updated the trace hooks test to verify that all trace hooks are called exactly once except ConnectStart/End, which may be called multiple times (due to happy-eyeballs). Fixes #15777 Change-Id: Iea5c64eb322b58be27f9ff863b3a6f90e996fa9b Reviewed-on: https://go-review.googlesource.com/23527 Reviewed-by: Andrew Gerrand <adg@golang.org>
Diffstat (limited to 'src/net/http/h2_bundle.go')
-rw-r--r--src/net/http/h2_bundle.go35
1 files changed, 24 insertions, 11 deletions
diff --git a/src/net/http/h2_bundle.go b/src/net/http/h2_bundle.go
index 9cedcaa73d..597eb7de47 100644
--- a/src/net/http/h2_bundle.go
+++ b/src/net/http/h2_bundle.go
@@ -25,8 +25,6 @@ import (
"encoding/binary"
"errors"
"fmt"
- "golang.org/x/net/http2/hpack"
- "golang.org/x/net/lex/httplex"
"io"
"io/ioutil"
"log"
@@ -42,6 +40,9 @@ import (
"strings"
"sync"
"time"
+
+ "golang.org/x/net/http2/hpack"
+ "golang.org/x/net/lex/httplex"
)
// ClientConnPool manages a pool of HTTP/2 client connections.
@@ -291,7 +292,7 @@ func http2configureTransport(t1 *Transport) (*http2Transport, error) {
t1.TLSClientConfig.NextProtos = append(t1.TLSClientConfig.NextProtos, "http/1.1")
}
upgradeFn := func(authority string, c *tls.Conn) RoundTripper {
- addr := http2authorityAddr(authority)
+ addr := http2authorityAddr("https", authority)
if used, err := connPool.addConnIfNeeded(addr, t2, c); err != nil {
go c.Close()
return http2erringRoundTripper{err}
@@ -4848,6 +4849,10 @@ type http2Transport struct {
// uncompressed.
DisableCompression bool
+ // AllowHTTP, if true, permits HTTP/2 requests using the insecure,
+ // plain-text "http" scheme. Note that this does not enable h2c support.
+ AllowHTTP bool
+
// MaxHeaderListSize is the http2 SETTINGS_MAX_HEADER_LIST_SIZE to
// send in the initial settings frame. It is how many bytes
// of response headers are allow. Unlike the http2 spec, zero here
@@ -4963,6 +4968,7 @@ type http2clientStream struct {
done chan struct{} // closed when stream remove from cc.streams map; close calls guarded by cc.mu
// owned by clientConnReadLoop:
+ firstByte bool // got the first response byte
pastHeaders bool // got first MetaHeadersFrame (actual headers)
pastTrailers bool // got optional second MetaHeadersFrame (trailers)
@@ -5046,20 +5052,24 @@ func (t *http2Transport) RoundTrip(req *Request) (*Response, error) {
// authorityAddr returns a given authority (a host/IP, or host:port / ip:port)
// and returns a host:port. The port 443 is added if needed.
-func http2authorityAddr(authority string) (addr string) {
+func http2authorityAddr(scheme string, authority string) (addr string) {
if _, _, err := net.SplitHostPort(authority); err == nil {
return authority
}
- return net.JoinHostPort(authority, "443")
+ port := "443"
+ if scheme == "http" {
+ port = "80"
+ }
+ return net.JoinHostPort(authority, port)
}
// RoundTripOpt is like RoundTrip, but takes options.
func (t *http2Transport) RoundTripOpt(req *Request, opt http2RoundTripOpt) (*Response, error) {
- if req.URL.Scheme != "https" {
+ if !(req.URL.Scheme == "https" || (req.URL.Scheme == "http" && t.AllowHTTP)) {
return nil, errors.New("http2: unsupported scheme")
}
- addr := http2authorityAddr(req.URL.Host)
+ addr := http2authorityAddr(req.URL.Scheme, req.URL.Host)
for {
cc, err := t.connPool().GetClientConn(req, addr)
if err != nil {
@@ -5944,15 +5954,18 @@ func (rl *http2clientConnReadLoop) processHeaders(f *http2MetaHeadersFrame) erro
return nil
}
+ if !cs.firstByte {
+ if cs.trace != nil {
+
+ http2traceFirstResponseByte(cs.trace)
+ }
+ cs.firstByte = true
+ }
if !cs.pastHeaders {
cs.pastHeaders = true
} else {
return rl.processTrailers(cs, f)
}
- if cs.trace != nil {
-
- http2traceFirstResponseByte(cs.trace)
- }
res, err := rl.handleResponse(cs, f)
if err != nil {