diff --git a/transport/control.go b/transport/control.go index 056d8ac9..6baa634e 100644 --- a/transport/control.go +++ b/transport/control.go @@ -60,8 +60,8 @@ func (windowUpdate) isItem() bool { } type settings struct { - id http2.SettingID - val uint32 + ack bool + setting []http2.Setting } func (settings) isItem() bool { diff --git a/transport/http2_client.go b/transport/http2_client.go index 28caf6c4..3c1044be 100644 --- a/transport/http2_client.go +++ b/transport/http2_client.go @@ -524,6 +524,9 @@ func (t *http2Client) handleRSTStream(f *http2.RSTStreamFrame) { } func (t *http2Client) handleSettings(f *http2.SettingsFrame) { + if f.IsAck() { + return + } f.ForeachSetting(func(s http2.Setting) error { if v, ok := f.Value(s.ID); ok { t.mu.Lock() @@ -541,6 +544,7 @@ func (t *http2Client) handleSettings(f *http2.SettingsFrame) { } return nil }) + t.controlBuf.put(&settings{ack: true}) } func (t *http2Client) handlePing(f *http2.PingFrame) { @@ -680,7 +684,11 @@ func (t *http2Client) controller() { case *windowUpdate: t.framer.writeWindowUpdate(true, i.streamID, i.increment) case *settings: - t.framer.writeSettings(true, http2.Setting{i.id, i.val}) + if i.ack { + t.framer.writeSettingsAck(true) + } else { + t.framer.writeSettings(true, i.setting...) + } case *resetStream: t.framer.writeRSTStream(true, i.streamID, i.code) case *flushIO: diff --git a/transport/http2_server.go b/transport/http2_server.go index 1609ac83..b43aef88 100644 --- a/transport/http2_server.go +++ b/transport/http2_server.go @@ -360,6 +360,9 @@ func (t *http2Server) handleRSTStream(f *http2.RSTStreamFrame) { } func (t *http2Server) handleSettings(f *http2.SettingsFrame) { + if f.IsAck() { + return + } f.ForeachSetting(func(s http2.Setting) error { if v, ok := f.Value(http2.SettingInitialWindowSize); ok { t.mu.Lock() @@ -371,6 +374,7 @@ func (t *http2Server) handleSettings(f *http2.SettingsFrame) { } return nil }) + t.controlBuf.put(&settings{ack: true}) } func (t *http2Server) handlePing(f *http2.PingFrame) { @@ -588,7 +592,11 @@ func (t *http2Server) controller() { case *windowUpdate: t.framer.writeWindowUpdate(true, i.streamID, i.increment) case *settings: - t.framer.writeSettings(true, http2.Setting{i.id, i.val}) + if i.ack { + t.framer.writeSettingsAck(true) + } else { + t.framer.writeSettings(true, i.setting...) + } case *resetStream: t.framer.writeRSTStream(true, i.streamID, i.code) case *flushIO: