From 828af96d4226442eeb69a807c03c909e565c99f7 Mon Sep 17 00:00:00 2001 From: iamqizhao <toqizhao@gmail.com> Date: Tue, 31 Mar 2015 19:05:09 -0700 Subject: [PATCH] send settingsAck when receiving a settings frame following http2 spec --- transport/control.go | 4 ++-- transport/http2_client.go | 10 +++++++++- transport/http2_server.go | 10 +++++++++- 3 files changed, 20 insertions(+), 4 deletions(-) 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: