diff options
author | Ian Lance Taylor <iant@golang.org> | 2017-01-06 20:41:14 -0800 |
---|---|---|
committer | Brad Fitzpatrick <bradfitz@golang.org> | 2017-01-07 06:37:46 +0000 |
commit | 8fa2344e98aa0eb2ef5a401847a4b760e9d19418 (patch) | |
tree | 39cde9368cfbcad619f29687dda0ff0e02083f45 | |
parent | 1fbdae5c3ad9aaaf827bed14a5e1e4cbd547a37c (diff) | |
download | go-8fa2344e98aa0eb2ef5a401847a4b760e9d19418.tar.gz go-8fa2344e98aa0eb2ef5a401847a4b760e9d19418.zip |
net/http: don't do a background read if we've already done one
Fixes #18535
Change-Id: I9e49d33ce357a534529a6b0fcdbc09ff4fa98622
Reviewed-on: https://go-review.googlesource.com/34920
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
-rw-r--r-- | src/net/http/serve_test.go | 47 | ||||
-rw-r--r-- | src/net/http/server.go | 3 |
2 files changed, 50 insertions, 0 deletions
diff --git a/src/net/http/serve_test.go b/src/net/http/serve_test.go index c2be58108b..072da2552b 100644 --- a/src/net/http/serve_test.go +++ b/src/net/http/serve_test.go @@ -5126,3 +5126,50 @@ func TestServerCancelsReadTimeoutWhenIdle(t *testing.T) { t.Fatalf("Got: %q, want ok", slurp) } } + +// Issue 18535: test that the Server doesn't try to do a background +// read if it's already done one. +func TestServerDuplicateBackgroundRead(t *testing.T) { + setParallel(t) + defer afterTest(t) + + const goroutines = 5 + const requests = 2000 + + hts := httptest.NewServer(HandlerFunc(NotFound)) + defer hts.Close() + + reqBytes := []byte("GET / HTTP/1.1\r\nHost: e.com\r\n\r\n") + + var wg sync.WaitGroup + for i := 0; i < goroutines; i++ { + wg.Add(1) + go func() { + defer wg.Done() + cn, err := net.Dial("tcp", hts.Listener.Addr().String()) + if err != nil { + t.Error(err) + return + } + defer cn.Close() + + wg.Add(1) + go func() { + defer wg.Done() + io.Copy(ioutil.Discard, cn) + }() + + for j := 0; j < requests; j++ { + if t.Failed() { + return + } + _, err := cn.Write(reqBytes) + if err != nil { + t.Error(err) + return + } + } + }() + } + wg.Wait() +} diff --git a/src/net/http/server.go b/src/net/http/server.go index bf1014134c..96236489bd 100644 --- a/src/net/http/server.go +++ b/src/net/http/server.go @@ -636,6 +636,9 @@ func (cr *connReader) startBackgroundRead() { if cr.inRead { panic("invalid concurrent Body.Read call") } + if cr.hasByte { + return + } cr.inRead = true cr.conn.rwc.SetReadDeadline(time.Time{}) go cr.backgroundRead() |