Nicholas Husin would like Damien Neil to review this change.
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
diff --git a/http2/http2.go b/http2/http2.go
index 105fe12..6320f4e 100644
--- a/http2/http2.go
+++ b/http2/http2.go
@@ -169,6 +169,7 @@
SettingMaxFrameSize SettingID = 0x5
SettingMaxHeaderListSize SettingID = 0x6
SettingEnableConnectProtocol SettingID = 0x8
+ SettingNoRFC7540Priorities SettingID = 0x9
)
var settingName = map[SettingID]string{
@@ -179,6 +180,7 @@
SettingMaxFrameSize: "MAX_FRAME_SIZE",
SettingMaxHeaderListSize: "MAX_HEADER_LIST_SIZE",
SettingEnableConnectProtocol: "ENABLE_CONNECT_PROTOCOL",
+ SettingNoRFC7540Priorities: "NO_RFC7540_PRIORITIES",
}
func (s SettingID) String() string {
diff --git a/http2/server.go b/http2/server.go
index d1fa038..25331bf 100644
--- a/http2/server.go
+++ b/http2/server.go
@@ -942,6 +942,9 @@
if !disableExtendedConnectProtocol {
settings = append(settings, Setting{SettingEnableConnectProtocol, 1})
}
+ if _, ok := sc.writeSched.(*priorityWriteSchedulerRFC7540); !ok {
+ settings = append(settings, Setting{SettingNoRFC7540Priorities, 1})
+ }
sc.writeFrame(FrameWriteRequest{
write: settings,
})
@@ -1809,6 +1812,10 @@
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
diff --git a/http2/server_test.go b/http2/server_test.go
index 5e1848f..e21f721 100644
--- a/http2/server_test.go
+++ b/http2/server_test.go
@@ -5152,6 +5152,68 @@
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) {
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
settings = append(settings, Setting{SettingNoRFC7540Priorities, 1})User-provided write schedulers might handle RFC 7540 priorities.
I think this should be flipped: Send SettingNoRFC7540Priorities only if the write scheduler is one we know doesn't use that priority scheme.
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |