Skip to content

Commit a2b6a2e

Browse files
WeiminShangneild
authored andcommitted
http2/h2c: propagate HTTP/1 server configuration to HTTP/2
Fixes golang/go#37089 Change-Id: I793bf8b420fd7b5a47b45ad1521c5b5f9e0321b2 GitHub-Last-Rev: 805b90e36a9a9986a57de86eb8f6725359f7abfe GitHub-Pull-Request: golang/net#139 Reviewed-on: https://go-review.googlesource.com/c/net/+/419181 Reviewed-by: Michael Knyszek <[email protected]> Reviewed-by: Damien Neil <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Run-TryBot: Damien Neil <[email protected]>
1 parent b0b28d5 commit a2b6a2e

File tree

2 files changed

+71
-0
lines changed

2 files changed

+71
-0
lines changed

http2/h2c/h2c.go

+11
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,15 @@ func NewHandler(h http.Handler, s *http2.Server) http.Handler {
7070
}
7171
}
7272

73+
// extractServer extracts existing http.Server instance from http.Request or create an empty http.Server
74+
func extractServer(r *http.Request) *http.Server {
75+
server, ok := r.Context().Value(http.ServerContextKey).(*http.Server)
76+
if ok {
77+
return server
78+
}
79+
return new(http.Server)
80+
}
81+
7382
// ServeHTTP implement the h2c support that is enabled by h2c.GetH2CHandler.
7483
func (s h2cHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
7584
// Handle h2c with prior knowledge (RFC 7540 Section 3.4)
@@ -87,6 +96,7 @@ func (s h2cHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
8796
defer conn.Close()
8897
s.s.ServeConn(conn, &http2.ServeConnOpts{
8998
Context: r.Context(),
99+
BaseConfig: extractServer(r),
90100
Handler: s.Handler,
91101
SawClientPreface: true,
92102
})
@@ -104,6 +114,7 @@ func (s h2cHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
104114
defer conn.Close()
105115
s.s.ServeConn(conn, &http2.ServeConnOpts{
106116
Context: r.Context(),
117+
BaseConfig: extractServer(r),
107118
Handler: s.Handler,
108119
UpgradeRequest: r,
109120
Settings: settings,

http2/h2c/h2c_test.go

+60
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"net"
1414
"net/http"
1515
"net/http/httptest"
16+
"strings"
1617
"testing"
1718

1819
"golang.org/x/net/http2"
@@ -74,3 +75,62 @@ func TestContext(t *testing.T) {
7475
t.Fatal(err)
7576
}
7677
}
78+
79+
func TestPropagation(t *testing.T) {
80+
var (
81+
server *http.Server
82+
// double the limit because http2 will compress header
83+
headerSize = 1 << 11
84+
headerLimit = 1 << 10
85+
)
86+
87+
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
88+
if r.ProtoMajor != 2 {
89+
t.Errorf("Request wasn't handled by h2c. Got ProtoMajor=%v", r.ProtoMajor)
90+
}
91+
if r.Context().Value(http.ServerContextKey).(*http.Server) != server {
92+
t.Errorf("Request doesn't have expected http server: %v", r.Context())
93+
}
94+
if len(r.Header.Get("Long-Header")) != headerSize {
95+
t.Errorf("Request doesn't have expected http header length: %v", len(r.Header.Get("Long-Header")))
96+
}
97+
fmt.Fprint(w, "Hello world")
98+
})
99+
100+
h2s := &http2.Server{}
101+
h1s := httptest.NewUnstartedServer(NewHandler(handler, h2s))
102+
103+
server = h1s.Config
104+
server.MaxHeaderBytes = headerLimit
105+
server.ConnState = func(conn net.Conn, state http.ConnState) {
106+
t.Logf("server conn state: conn %s -> %s, status changed to %s", conn.RemoteAddr(), conn.LocalAddr(), state)
107+
}
108+
109+
h1s.Start()
110+
defer h1s.Close()
111+
112+
client := &http.Client{
113+
Transport: &http2.Transport{
114+
AllowHTTP: true,
115+
DialTLS: func(network, addr string, _ *tls.Config) (net.Conn, error) {
116+
conn, err := net.Dial(network, addr)
117+
if conn != nil {
118+
t.Logf("client dial tls: %s -> %s", conn.RemoteAddr(), conn.LocalAddr())
119+
}
120+
return conn, err
121+
},
122+
},
123+
}
124+
125+
req, err := http.NewRequest("GET", h1s.URL, nil)
126+
if err != nil {
127+
t.Fatal(err)
128+
}
129+
130+
req.Header.Set("Long-Header", strings.Repeat("A", headerSize))
131+
132+
_, err = client.Do(req)
133+
if err == nil {
134+
t.Fatal("expected server err, got nil")
135+
}
136+
}

0 commit comments

Comments
 (0)