aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2017-01-06 20:41:14 -0800
committerBrad Fitzpatrick <bradfitz@golang.org>2017-01-07 06:37:46 +0000
commit8fa2344e98aa0eb2ef5a401847a4b760e9d19418 (patch)
tree39cde9368cfbcad619f29687dda0ff0e02083f45
parent1fbdae5c3ad9aaaf827bed14a5e1e4cbd547a37c (diff)
downloadgo-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.go47
-rw-r--r--src/net/http/server.go3
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()