From 2005e80d72dcc6a4447b6352d2498fa82b87ca29 Mon Sep 17 00:00:00 2001 From: Yuxuan Li Date: Wed, 18 Apr 2018 15:41:47 -0700 Subject: [PATCH 1/4] init --- transport/controlbuf.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/transport/controlbuf.go b/transport/controlbuf.go index e147cd51bf19..f7b7991f1da3 100644 --- a/transport/controlbuf.go +++ b/transport/controlbuf.go @@ -664,6 +664,8 @@ func (l *loopyWriter) applySettings(ss []http2.Setting) error { } } } + case http2.SettingHeaderTableSize: + l.hEnc.SetMaxDynamicTableSizeLimit(s.Val) } } return nil From ba122d58e2797e84e3100a02bef9f87ed46ee8c1 Mon Sep 17 00:00:00 2001 From: Yuxuan Li Date: Wed, 2 May 2018 15:18:07 -0700 Subject: [PATCH 2/4] added test --- transport/controlbuf.go | 6 ++- transport/transport_test.go | 83 +++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 1 deletion(-) diff --git a/transport/controlbuf.go b/transport/controlbuf.go index f7b7991f1da3..6b15f3c294e6 100644 --- a/transport/controlbuf.go +++ b/transport/controlbuf.go @@ -28,6 +28,10 @@ import ( "golang.org/x/net/http2/hpack" ) +var updateHeaderTblSize = func(e *hpack.Encoder, v uint32) { + e.SetMaxDynamicTableSizeLimit(v) +} + type itemNode struct { it interface{} next *itemNode @@ -665,7 +669,7 @@ func (l *loopyWriter) applySettings(ss []http2.Setting) error { } } case http2.SettingHeaderTableSize: - l.hEnc.SetMaxDynamicTableSizeLimit(s.Val) + updateHeaderTblSize(l.hEnc, s.Val) } } return nil diff --git a/transport/transport_test.go b/transport/transport_test.go index 07a81fde2271..94004da99fc3 100644 --- a/transport/transport_test.go +++ b/transport/transport_test.go @@ -2086,3 +2086,86 @@ func runPingPongTest(t *testing.T, msgSize int) { } } } + +func TestHeaderTblSize(t *testing.T) { + var limits []uint32 + updateHeaderTblSize = func(e *hpack.Encoder, v uint32) { + e.SetMaxDynamicTableSizeLimit(v) + limits = append(limits, v) + } + defer func() { + updateHeaderTblSize = func(e *hpack.Encoder, v uint32) { + e.SetMaxDynamicTableSizeLimit(v) + } + }() + + server, ct := setUp(t, 0, math.MaxUint32, normal) + defer ct.Close() + defer server.stop() + _, err := ct.NewStream(context.Background(), &CallHdr{}) + if err != nil { + t.Fatalf("failed to open stream: %v", err) + } + + var svrTransport ServerTransport + var i int + for i := 0; i < 1000; i++ { + if len(server.conns) == 0 { + time.Sleep(10 * time.Millisecond) + continue + } + } + if i == 1000 { + t.Fatalf("unable to create any server transport after 10s") + } + + for st := range server.conns { + svrTransport = st + break + } + svrTransport.(*http2Server).controlBuf.put(&outgoingSettings{ + ss: []http2.Setting{ + { + ID: http2.SettingHeaderTableSize, + Val: uint32(100), + }, + }, + }) + + for i := 0; i < 1000; i++ { + if len(limits) != 1 { + time.Sleep(10 * time.Millisecond) + continue + } + if limits[0] != uint32(100) { + t.Fatalf("expected limits[0] = 100, got %d", limits[0]) + } + break + } + if i == 1000 { + t.Fatalf("expected len(limits) = 1, got %d", len(limits)) + } + + ct.(*http2Client).controlBuf.put(&outgoingSettings{ + ss: []http2.Setting{ + { + ID: http2.SettingHeaderTableSize, + Val: uint32(200), + }, + }, + }) + + for i := 0; i < 1000; i++ { + if len(limits) != 2 { + time.Sleep(10 * time.Millisecond) + continue + } + if limits[1] != uint32(200) { + t.Fatalf("expected limits[1] = 200, got %d", limits[1]) + } + break + } + if i == 1000 { + t.Fatalf("expected len(limits) = 2, got %d", len(limits)) + } +} From 1c74265d1410d5b14f7f9adb31dc983383640cd9 Mon Sep 17 00:00:00 2001 From: Yuxuan Li Date: Wed, 2 May 2018 16:08:00 -0700 Subject: [PATCH 3/4] fix race --- transport/transport_test.go | 53 ++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/transport/transport_test.go b/transport/transport_test.go index 94004da99fc3..9dbd3bc2e7d3 100644 --- a/transport/transport_test.go +++ b/transport/transport_test.go @@ -2087,11 +2087,34 @@ func runPingPongTest(t *testing.T, msgSize int) { } } +type tableSizeLimit struct { + mu sync.Mutex + limits []uint32 +} + +func (t *tableSizeLimit) add(limit uint32) { + t.mu.Lock() + t.limits = append(t.limits, limit) + t.mu.Unlock() +} + +func (t *tableSizeLimit) getLen() int { + t.mu.Lock() + defer t.mu.Unlock() + return len(t.limits) +} + +func (t *tableSizeLimit) getIndex(i int) uint32 { + t.mu.Lock() + defer t.mu.Unlock() + return t.limits[i] +} + func TestHeaderTblSize(t *testing.T) { - var limits []uint32 + limits := &tableSizeLimit{} updateHeaderTblSize = func(e *hpack.Encoder, v uint32) { e.SetMaxDynamicTableSizeLimit(v) - limits = append(limits, v) + limits.add(v) } defer func() { updateHeaderTblSize = func(e *hpack.Encoder, v uint32) { @@ -2110,10 +2133,14 @@ func TestHeaderTblSize(t *testing.T) { var svrTransport ServerTransport var i int for i := 0; i < 1000; i++ { - if len(server.conns) == 0 { - time.Sleep(10 * time.Millisecond) - continue + server.mu.Lock() + if len(server.conns) != 0 { + server.mu.Unlock() + break } + server.mu.Unlock() + time.Sleep(10 * time.Millisecond) + continue } if i == 1000 { t.Fatalf("unable to create any server transport after 10s") @@ -2133,17 +2160,17 @@ func TestHeaderTblSize(t *testing.T) { }) for i := 0; i < 1000; i++ { - if len(limits) != 1 { + if limits.getLen() != 1 { time.Sleep(10 * time.Millisecond) continue } - if limits[0] != uint32(100) { - t.Fatalf("expected limits[0] = 100, got %d", limits[0]) + if val := limits.getIndex(0); val != uint32(100) { + t.Fatalf("expected limits[0] = 100, got %d", val) } break } if i == 1000 { - t.Fatalf("expected len(limits) = 1, got %d", len(limits)) + t.Fatalf("expected len(limits) = 1 within 10s, got != 1") } ct.(*http2Client).controlBuf.put(&outgoingSettings{ @@ -2156,16 +2183,16 @@ func TestHeaderTblSize(t *testing.T) { }) for i := 0; i < 1000; i++ { - if len(limits) != 2 { + if limits.getLen() != 2 { time.Sleep(10 * time.Millisecond) continue } - if limits[1] != uint32(200) { - t.Fatalf("expected limits[1] = 200, got %d", limits[1]) + if val := limits.getIndex(1); val != uint32(200) { + t.Fatalf("expected limits[1] = 200, got %d", val) } break } if i == 1000 { - t.Fatalf("expected len(limits) = 2, got %d", len(limits)) + t.Fatalf("expected len(limits) = 2 within 10s, got != 2") } } From 11a21f2db46790b38a829a73e9db7daf5d4df3ac Mon Sep 17 00:00:00 2001 From: Yuxuan Li Date: Fri, 11 May 2018 14:25:00 -0700 Subject: [PATCH 4/4] update --- transport/transport_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/transport/transport_test.go b/transport/transport_test.go index 9dbd3bc2e7d3..408b36a2994e 100644 --- a/transport/transport_test.go +++ b/transport/transport_test.go @@ -2132,7 +2132,7 @@ func TestHeaderTblSize(t *testing.T) { var svrTransport ServerTransport var i int - for i := 0; i < 1000; i++ { + for i = 0; i < 1000; i++ { server.mu.Lock() if len(server.conns) != 0 { server.mu.Unlock() @@ -2159,7 +2159,7 @@ func TestHeaderTblSize(t *testing.T) { }, }) - for i := 0; i < 1000; i++ { + for i = 0; i < 1000; i++ { if limits.getLen() != 1 { time.Sleep(10 * time.Millisecond) continue