mirror of
https://github.com/golang/net.git
synced 2026-03-31 18:37:08 +09:00
http2: support SETTINGS_NO_RFC7540_PRIORITIES in SETTINGS frame
To make sure that clients do not unnecessarily send RFC 7540 priority signals when it would be treated as a no-op, this change makes it so that our server always sends SETTINGS_NO_RFC7540_PRIORITIES in our SETTINGS frame when our write scheduler is set to anything other than the RFC 7540 write scheduler. For golang/go#75500 Change-Id: I7a54251022087319999deda7efb663f8b251aa95 Reviewed-on: https://go-review.googlesource.com/c/net/+/729141 Reviewed-by: Damien Neil <dneil@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Nicholas Husin <husin@google.com>
This commit is contained in:
committed by
Nicholas Husin
parent
8a4d9c198f
commit
8f003b3712
@@ -169,6 +169,7 @@ const (
|
||||
SettingMaxFrameSize SettingID = 0x5
|
||||
SettingMaxHeaderListSize SettingID = 0x6
|
||||
SettingEnableConnectProtocol SettingID = 0x8
|
||||
SettingNoRFC7540Priorities SettingID = 0x9
|
||||
)
|
||||
|
||||
var settingName = map[SettingID]string{
|
||||
@@ -179,6 +180,7 @@ var settingName = map[SettingID]string{
|
||||
SettingMaxFrameSize: "MAX_FRAME_SIZE",
|
||||
SettingMaxHeaderListSize: "MAX_HEADER_LIST_SIZE",
|
||||
SettingEnableConnectProtocol: "ENABLE_CONNECT_PROTOCOL",
|
||||
SettingNoRFC7540Priorities: "NO_RFC7540_PRIORITIES",
|
||||
}
|
||||
|
||||
func (s SettingID) String() string {
|
||||
|
||||
@@ -955,6 +955,9 @@ func (sc *serverConn) serve(conf http2Config) {
|
||||
if !disableExtendedConnectProtocol {
|
||||
settings = append(settings, Setting{SettingEnableConnectProtocol, 1})
|
||||
}
|
||||
if sc.writeSchedIgnoresRFC7540() {
|
||||
settings = append(settings, Setting{SettingNoRFC7540Priorities, 1})
|
||||
}
|
||||
sc.writeFrame(FrameWriteRequest{
|
||||
write: settings,
|
||||
})
|
||||
@@ -1822,6 +1825,10 @@ func (sc *serverConn) processSetting(s Setting) error {
|
||||
case SettingEnableConnectProtocol:
|
||||
// Receipt of this parameter by a server does not
|
||||
// have any impact
|
||||
case SettingNoRFC7540Priorities:
|
||||
if s.Val > 1 {
|
||||
return ConnectionError(ErrCodeProtocol)
|
||||
}
|
||||
default:
|
||||
// Unknown setting: "An endpoint that receives a SETTINGS
|
||||
// frame with any unknown or unsupported identifier MUST
|
||||
|
||||
@@ -5152,6 +5152,68 @@ func testServerSendDataAfterRequestBodyClose(t testing.TB) {
|
||||
st.wantIdle()
|
||||
}
|
||||
|
||||
func TestServerSettingNoRFC7540Priorities(t *testing.T) {
|
||||
synctestTest(t, testServerSettingNoRFC7540Priorities)
|
||||
}
|
||||
func testServerSettingNoRFC7540Priorities(t testing.TB) {
|
||||
tests := []struct {
|
||||
ws func() WriteScheduler
|
||||
wantNoRFC7540Setting bool
|
||||
}{
|
||||
{
|
||||
ws: func() WriteScheduler {
|
||||
return newPriorityWriteSchedulerRFC7540(nil)
|
||||
},
|
||||
wantNoRFC7540Setting: false,
|
||||
},
|
||||
{
|
||||
ws: newPriorityWriteSchedulerRFC9218,
|
||||
wantNoRFC7540Setting: true,
|
||||
},
|
||||
{
|
||||
ws: NewRandomWriteScheduler,
|
||||
wantNoRFC7540Setting: true,
|
||||
},
|
||||
{
|
||||
ws: newRoundRobinWriteScheduler,
|
||||
wantNoRFC7540Setting: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
st := newServerTester(t, nil, func(s *Server) {
|
||||
s.NewWriteScheduler = tt.ws
|
||||
})
|
||||
defer st.Close()
|
||||
|
||||
var gotNoRFC7540Setting bool
|
||||
st.greetAndCheckSettings(func(s Setting) error {
|
||||
if s.ID != SettingNoRFC7540Priorities {
|
||||
return nil
|
||||
}
|
||||
gotNoRFC7540Setting = s.Val == 1
|
||||
return nil
|
||||
})
|
||||
if tt.wantNoRFC7540Setting != gotNoRFC7540Setting {
|
||||
t.Errorf("want SETTINGS_NO_RFC7540_PRIORITIES to be %v, got %v", tt.wantNoRFC7540Setting, gotNoRFC7540Setting)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestServerSettingNoRFC7540PrioritiesInvalid(t *testing.T) {
|
||||
synctestTest(t, testServerSettingNoRFC7540PrioritiesInvalid)
|
||||
}
|
||||
func testServerSettingNoRFC7540PrioritiesInvalid(t testing.TB) {
|
||||
st := newServerTester(t, nil)
|
||||
defer st.Close()
|
||||
|
||||
st.writePreface()
|
||||
st.writeSettings(Setting{ID: SettingNoRFC7540Priorities, Val: 2})
|
||||
synctest.Wait()
|
||||
st.readFrame() // SETTINGS frame
|
||||
st.readFrame() // WINDOW_UPDATE frame
|
||||
st.wantGoAway(0, ErrCodeProtocol)
|
||||
}
|
||||
|
||||
// This test documents current behavior, rather than ideal behavior that we
|
||||
// would necessarily like to see. Refer to go.dev/issues/75936 for details.
|
||||
func TestServerRFC7540PrioritySmallPayload(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user