Commit 8fa2344e authored by Ian Lance Taylor's avatar Ian Lance Taylor Committed by Brad Fitzpatrick

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: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 1fbdae5c
......@@ -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()
}
......@@ -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()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment