mirror of
https://github.com/golang/go
synced 2024-11-22 03:34:40 -07:00
Fix blocking finishAsyncByteRead.Read method
Chunked http requests that do not provide the first byte within 200ms utilize finishAsyncByteRead. The Read method never returns io.EOF and will block upon second call because the channel is empty. This PR follows the same pattern as used by byteReader to return io.EOF in the first call if err is nil and for all subsequent calls.
This commit is contained in:
parent
0e67ce3d28
commit
a149748bde
@ -235,7 +235,7 @@ func (t *transferWriter) probeRequestBody() {
|
||||
// assuming that this is ContentLength == -1
|
||||
// (unknown), which means we'll send a
|
||||
// "Transfer-Encoding: chunked" header.
|
||||
t.Body = io.MultiReader(finishAsyncByteRead{t}, t.Body)
|
||||
t.Body = io.MultiReader(&finishAsyncByteRead{tw: t}, t.Body)
|
||||
// Request that Request.Write flush the headers to the
|
||||
// network before writing the body, since our body may not
|
||||
// become readable until it's seen the response headers.
|
||||
@ -1060,18 +1060,26 @@ func parseContentLength(cl string) (int64, error) {
|
||||
// finishAsyncByteRead finishes reading the 1-byte sniff
|
||||
// from the ContentLength==0, Body!=nil case.
|
||||
type finishAsyncByteRead struct {
|
||||
tw *transferWriter
|
||||
tw *transferWriter
|
||||
done bool
|
||||
}
|
||||
|
||||
func (fr finishAsyncByteRead) Read(p []byte) (n int, err error) {
|
||||
func (fr *finishAsyncByteRead) Read(p []byte) (n int, err error) {
|
||||
if fr.done {
|
||||
return 0, io.EOF
|
||||
}
|
||||
if len(p) == 0 {
|
||||
return
|
||||
}
|
||||
fr.done = true
|
||||
rres := <-fr.tw.ByteReadCh
|
||||
n, err = rres.n, rres.err
|
||||
if n == 1 {
|
||||
p[0] = rres.b
|
||||
}
|
||||
if err == nil {
|
||||
err = io.EOF
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user