Skip to content

net/http: Transport leaks goroutines when request.ContentLength is explicitly short #4531

Closed
@gopherbot

Description

@gopherbot

by zarcardfly:

Before filing a bug, please check whether it has been fixed since the
latest release. Search the issue tracker and check that you're running the
latest version of Go:

Run "go version" and compare against
http://golang.org/doc/devel/release.html  If a newer version of Go exists,
install it and retry what you did to reproduce the problem.

Thanks.

What steps will reproduce the problem?
If possible, include a link to a program on play.golang.org.
  1. sample code: http://play.golang.org/p/IKPtSqNs53
  2. I call http.Client.Do with a http.Request whose ContentLength is unequal to the posted body's length.
  3. http.Client.Do failed as assume, but the readLoop() goruntine is still running, it hang up at : 558            rc := <-pc.reqch
  4. I check the net/http/transport.go code:
   669      pc.lk.Lock()
   670      pc.numExpectedResponses++
   671      pc.lk.Unlock()
   672  
   673      err = req.Request.write(pc.bw, pc.isProxy, req.extra)
   674      if err != nil {
   675          pc.close()
   676          return
   677      }
   678      pc.bw.Flush()
   679  
   680      ch := make(chan responseAndError, 1)
   681      pc.reqch <- requestAndChan{req.Request, ch, requestedGzip}
   682      re := <-ch
   683      pc.lk.Lock()
   684      pc.numExpectedResponses--
   685      pc.lk.Unlock() 
  when 673 failed, the function returned without dec numExpectedResponses.
   544          pb, err := pc.br.Peek(1)
   545  
   546          pc.lk.Lock()
   547          if pc.numExpectedResponses == 0 {
   548              pc.closeLocked()
   549              pc.lk.Unlock()
   550              if len(pb) > 0 {
   551                  log.Printf("Unsolicited response received on idle HTTP channel starting with %q; err=%v",
   552                      string(pb), err)
   553              }
   554              return
   555          }
   556          pc.lk.Unlock()
   557  
   558          rc := <-pc.reqch
  And the result of line 547 is false, and then the goroutine block in 558.

What is the expected output?
  the number of goroutine is a small number, such as 5.

What do you see instead?
  the number of goroutine is more than 20.

Which compiler are you using (5g, 6g, 8g, gccgo)?
  6g

Which operating system are you using?
  mac os x 10.8

Which version are you using?  (run 'go version')
  I found it in an old version go, but I check the 'http://golang.org/src/pkg/net/http/transport.go', it still being there.

Please provide any additional information below.
 Tell me if I miss something, thank you, and sorry for my poor english.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions