Skip to content

Commit f238a07

Browse files
committed
http2: server advertises SETTINGS_ENABLE_CONNECT_PROTOCOL support
1 parent f88258d commit f238a07

File tree

3 files changed

+49
-26
lines changed

3 files changed

+49
-26
lines changed

http2/frame.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1490,7 +1490,7 @@ func (mh *MetaHeadersFrame) checkPseudos() error {
14901490
pf := mh.PseudoFields()
14911491
for i, hf := range pf {
14921492
switch hf.Name {
1493-
case ":method", ":path", ":scheme", ":authority":
1493+
case ":method", ":path", ":scheme", ":authority", ":protocol":
14941494
isRequest = true
14951495
case ":status":
14961496
isResponse = true

http2/http2.go

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,11 @@ import (
3434
)
3535

3636
var (
37-
VerboseLogs bool
38-
logFrameWrites bool
39-
logFrameReads bool
40-
inTests bool
37+
VerboseLogs bool
38+
logFrameWrites bool
39+
logFrameReads bool
40+
inTests bool
41+
disableExtendedConnectProtocol bool
4142
)
4243

4344
func init() {
@@ -50,6 +51,9 @@ func init() {
5051
logFrameWrites = true
5152
logFrameReads = true
5253
}
54+
if strings.Contains(e, "http2xconnect=0") {
55+
disableExtendedConnectProtocol = true
56+
}
5357
}
5458

5559
const (
@@ -150,21 +154,23 @@ func (s Setting) Valid() error {
150154
type SettingID uint16
151155

152156
const (
153-
SettingHeaderTableSize SettingID = 0x1
154-
SettingEnablePush SettingID = 0x2
155-
SettingMaxConcurrentStreams SettingID = 0x3
156-
SettingInitialWindowSize SettingID = 0x4
157-
SettingMaxFrameSize SettingID = 0x5
158-
SettingMaxHeaderListSize SettingID = 0x6
157+
SettingHeaderTableSize SettingID = 0x1
158+
SettingEnablePush SettingID = 0x2
159+
SettingMaxConcurrentStreams SettingID = 0x3
160+
SettingInitialWindowSize SettingID = 0x4
161+
SettingMaxFrameSize SettingID = 0x5
162+
SettingMaxHeaderListSize SettingID = 0x6
163+
SettingEnableConnectProtocol SettingID = 0x8
159164
)
160165

161166
var settingName = map[SettingID]string{
162-
SettingHeaderTableSize: "HEADER_TABLE_SIZE",
163-
SettingEnablePush: "ENABLE_PUSH",
164-
SettingMaxConcurrentStreams: "MAX_CONCURRENT_STREAMS",
165-
SettingInitialWindowSize: "INITIAL_WINDOW_SIZE",
166-
SettingMaxFrameSize: "MAX_FRAME_SIZE",
167-
SettingMaxHeaderListSize: "MAX_HEADER_LIST_SIZE",
167+
SettingHeaderTableSize: "HEADER_TABLE_SIZE",
168+
SettingEnablePush: "ENABLE_PUSH",
169+
SettingMaxConcurrentStreams: "MAX_CONCURRENT_STREAMS",
170+
SettingInitialWindowSize: "INITIAL_WINDOW_SIZE",
171+
SettingMaxFrameSize: "MAX_FRAME_SIZE",
172+
SettingMaxHeaderListSize: "MAX_HEADER_LIST_SIZE",
173+
SettingEnableConnectProtocol: "ENABLE_CONNECT_PROTOCOL",
168174
}
169175

170176
func (s SettingID) String() string {

http2/server.go

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -913,14 +913,18 @@ func (sc *serverConn) serve(conf http2Config) {
913913
sc.vlogf("http2: server connection from %v on %p", sc.conn.RemoteAddr(), sc.hs)
914914
}
915915

916+
settings := writeSettings{
917+
{SettingMaxFrameSize, conf.MaxReadFrameSize},
918+
{SettingMaxConcurrentStreams, sc.advMaxStreams},
919+
{SettingMaxHeaderListSize, sc.maxHeaderListSize()},
920+
{SettingHeaderTableSize, conf.MaxDecoderHeaderTableSize},
921+
{SettingInitialWindowSize, uint32(sc.initialStreamRecvWindowSize)},
922+
}
923+
if !disableExtendedConnectProtocol {
924+
settings = append(settings, Setting{SettingEnableConnectProtocol, 1})
925+
}
916926
sc.writeFrame(FrameWriteRequest{
917-
write: writeSettings{
918-
{SettingMaxFrameSize, conf.MaxReadFrameSize},
919-
{SettingMaxConcurrentStreams, sc.advMaxStreams},
920-
{SettingMaxHeaderListSize, sc.maxHeaderListSize()},
921-
{SettingHeaderTableSize, conf.MaxDecoderHeaderTableSize},
922-
{SettingInitialWindowSize, uint32(sc.initialStreamRecvWindowSize)},
923-
},
927+
write: settings,
924928
})
925929
sc.unackedSettings++
926930

@@ -1782,6 +1786,9 @@ func (sc *serverConn) processSetting(s Setting) error {
17821786
sc.maxFrameSize = int32(s.Val) // the maximum valid s.Val is < 2^31
17831787
case SettingMaxHeaderListSize:
17841788
sc.peerMaxHeaderListSize = s.Val
1789+
case SettingEnableConnectProtocol:
1790+
// Receipt of this parameter by a server does not
1791+
// have any impact
17851792
default:
17861793
// Unknown setting: "An endpoint that receives a SETTINGS
17871794
// frame with any unknown or unsupported identifier MUST
@@ -2212,11 +2219,17 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res
22122219
scheme: f.PseudoValue("scheme"),
22132220
authority: f.PseudoValue("authority"),
22142221
path: f.PseudoValue("path"),
2222+
protocol: f.PseudoValue("protocol"),
2223+
}
2224+
2225+
// extended connect is disabled, so we should not see :protocol
2226+
if disableExtendedConnectProtocol && rp.protocol != "" {
2227+
return nil, nil, sc.countError("bad_connect", streamError(f.StreamID, ErrCodeProtocol))
22152228
}
22162229

22172230
isConnect := rp.method == "CONNECT"
22182231
if isConnect {
2219-
if rp.path != "" || rp.scheme != "" || rp.authority == "" {
2232+
if rp.protocol == "" && (rp.path != "" || rp.scheme != "" || rp.authority == "") {
22202233
return nil, nil, sc.countError("bad_connect", streamError(f.StreamID, ErrCodeProtocol))
22212234
}
22222235
} else if rp.method == "" || rp.path == "" || (rp.scheme != "https" && rp.scheme != "http") {
@@ -2240,6 +2253,9 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res
22402253
if rp.authority == "" {
22412254
rp.authority = rp.header.Get("Host")
22422255
}
2256+
if rp.protocol != "" {
2257+
rp.header.Set(":protocol", rp.protocol)
2258+
}
22432259

22442260
rw, req, err := sc.newWriterAndRequestNoBody(st, rp)
22452261
if err != nil {
@@ -2266,6 +2282,7 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res
22662282
type requestParam struct {
22672283
method string
22682284
scheme, authority, path string
2285+
protocol string
22692286
header http.Header
22702287
}
22712288

@@ -2307,7 +2324,7 @@ func (sc *serverConn) newWriterAndRequestNoBody(st *stream, rp requestParam) (*r
23072324

23082325
var url_ *url.URL
23092326
var requestURI string
2310-
if rp.method == "CONNECT" {
2327+
if rp.method == "CONNECT" && rp.protocol == "" {
23112328
url_ = &url.URL{Host: rp.authority}
23122329
requestURI = rp.authority // mimic HTTP/1 server behavior
23132330
} else {

0 commit comments

Comments
 (0)