]> Cypherpunks repositories - gostls13.git/commitdiff
net/http: don't do a background read if we've already done one
authorIan Lance Taylor <iant@golang.org>
Sat, 7 Jan 2017 04:41:14 +0000 (20:41 -0800)
committerBrad Fitzpatrick <bradfitz@golang.org>
Sat, 7 Jan 2017 06:37:46 +0000 (06:37 +0000)
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>
src/net/http/serve_test.go
src/net/http/server.go

index c2be58108b02b4175813db00701d781409106d98..072da2552bc5d06d8e109657d0ddfd9c19ad1fec 100644 (file)
@@ -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()
+}
index bf1014134c9bc6a7924c76767744645fa6d6e18c..96236489bd9faf0e404a01aed92bafcab19ee33f 100644 (file)
@@ -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()