|
|
Descriptionnet/http: non-keepalive connections close successfully
Connections did not close if Request.Close or Response.Close was true. This meant that if the user wanted the connection to close, or if the server requested it via "Connection: close", the connection would not be closed.
Fixes issue 1967.
Patch Set 1 : diff -r a951a803c909 https://code.google.com/p/go #Patch Set 2 : diff -r 9233f811c522 https://code.google.com/p/go #
Total comments: 6
Patch Set 3 : diff -r d4f7f7438d1f https://code.google.com/p/go #
MessagesTotal messages: 13
Hello golang-dev@googlegroups.com (cc: bradfitz@golang.org), I'd like you to review this change to https://code.google.com/p/go
Sign in to reply to this message.
Can you test this without SetFinalizer, please? There is no guarantee that the GC will collect a particular block on a particular collection.
Sign in to reply to this message.
On 2012/05/04 13:30:59, rsc wrote: > Can you test this without SetFinalizer, please? There is no guarantee > that the GC will collect a particular block on a particular > collection. Ah, ok. Here's an alternative, but it involves a few global vars. It seems fitting to reuse it in a couple of the tests that are specifically testing for connections closing.
Sign in to reply to this message.
Sorry for the slow review. I lost this. http://codereview.appspot.com/6201044/diff/3003/src/pkg/net/http/transport_te... File src/pkg/net/http/transport_test.go (right): http://codereview.appspot.com/6201044/diff/3003/src/pkg/net/http/transport_te... src/pkg/net/http/transport_test.go:41: var connTestListMutex *sync.Mutex = &sync.Mutex{} you don't need to list the type (*sync.Mutex) and sync.Mutex is generally declared just as a value. do this: var ( connTestMutex sync.Mutex // protects connTestList connTestList []*net.TCPConn ) http://codereview.appspot.com/6201044/diff/3003/src/pkg/net/http/transport_te... src/pkg/net/http/transport_test.go:48: if connTestList == nil { these three lines are unnecessary. append does this for you. http://codereview.appspot.com/6201044/diff/3003/src/pkg/net/http/transport_te... src/pkg/net/http/transport_test.go:51: connTestList = append(connTestList, c.(*net.TCPConn)) might as well just make the list be on type []net.Conn, no? http://codereview.appspot.com/6201044/diff/3003/src/pkg/net/http/transport_te... src/pkg/net/http/transport_test.go:64: if c.Close() == nil { I'm not sure you can rely on this property? I'd recommend instead making testDial return a different implementation of net.Conn which wraps a net.Conn and removes the net.Conn from a map of outstanding conns (so change the protected datastructure from a slice to a map[net.Conn]bool) http://codereview.appspot.com/6201044/diff/3003/src/pkg/net/http/transport_te... src/pkg/net/http/transport_test.go:72: t.Errorf("%v out of %v tcp connections were not closed", unclosed, len(connTestList)) %d instead of %d when you know it's an integer. (minor nit) http://codereview.appspot.com/6201044/diff/3003/src/pkg/net/http/transport_te... src/pkg/net/http/transport_test.go:116: tr.Dial = testDial just put this in the {}. tr := &Transport{ Dial: testDial, }
Sign in to reply to this message.
OK, I've implemented all of your suggestions. In addition, I've replaced the global state with a closure in makeTestDial. On 2012/05/07 10:18:46, bradfitz wrote: > Sorry for the slow review. I lost this. > > http://codereview.appspot.com/6201044/diff/3003/src/pkg/net/http/transport_te... > File src/pkg/net/http/transport_test.go (right): > > http://codereview.appspot.com/6201044/diff/3003/src/pkg/net/http/transport_te... > src/pkg/net/http/transport_test.go:41: var connTestListMutex *sync.Mutex = > &sync.Mutex{} > you don't need to list the type (*sync.Mutex) and sync.Mutex is generally > declared just as a value. do this: > > var ( > connTestMutex sync.Mutex // protects connTestList > connTestList []*net.TCPConn > ) > > http://codereview.appspot.com/6201044/diff/3003/src/pkg/net/http/transport_te... > src/pkg/net/http/transport_test.go:48: if connTestList == nil { > these three lines are unnecessary. append does this for you. > > http://codereview.appspot.com/6201044/diff/3003/src/pkg/net/http/transport_te... > src/pkg/net/http/transport_test.go:51: connTestList = append(connTestList, > c.(*net.TCPConn)) > might as well just make the list be on type []net.Conn, no? > > http://codereview.appspot.com/6201044/diff/3003/src/pkg/net/http/transport_te... > src/pkg/net/http/transport_test.go:64: if c.Close() == nil { > I'm not sure you can rely on this property? > > I'd recommend instead making testDial return a different implementation of > net.Conn which wraps a net.Conn and removes the net.Conn from a map of > outstanding conns (so change the protected datastructure from a slice to a > map[net.Conn]bool) > > http://codereview.appspot.com/6201044/diff/3003/src/pkg/net/http/transport_te... > src/pkg/net/http/transport_test.go:72: t.Errorf("%v out of %v tcp connections > were not closed", unclosed, len(connTestList)) > %d instead of %d when you know it's an integer. (minor nit) > > http://codereview.appspot.com/6201044/diff/3003/src/pkg/net/http/transport_te... > src/pkg/net/http/transport_test.go:116: tr.Dial = testDial > just put this in the {}. > > tr := &Transport{ > Dial: testDial, > }
Sign in to reply to this message.
LGTM
Sign in to reply to this message.
*** Submitted as http://code.google.com/p/go/source/detail?r=820ffde8c396 *** net/http: non-keepalive connections close successfully Connections did not close if Request.Close or Response.Close was true. This meant that if the user wanted the connection to close, or if the server requested it via "Connection: close", the connection would not be closed. Fixes issue 1967. R=golang-dev, rsc, bradfitz CC=golang-dev http://codereview.appspot.com/6201044 Committer: Brad Fitzpatrick <bradfitz@golang.org>
Sign in to reply to this message.
On 2012/05/18 17:34:41, bradfitz wrote: > *** Submitted as http://code.google.com/p/go/source/detail?r=820ffde8c396 *** > > net/http: non-keepalive connections close successfully > > Connections did not close if Request.Close or Response.Close was true. This > meant that if the user wanted the connection to close, or if the server > requested it via "Connection: close", the connection would not be closed. > > Fixes issue 1967. > > R=golang-dev, rsc, bradfitz > CC=golang-dev > http://codereview.appspot.com/6201044 > > Committer: Brad Fitzpatrick <mailto:bradfitz@golang.org> This code breaks Client.Get() on non-persistent ("Connection: close") connections. Response.Body returns error("use of closed network connection"). eg: response,err := http.Get("http://...") // err == nil, but response.Close == true n,err := response.Body.Read(buf) // err == use of closed network connection
Sign in to reply to this message.
Full example (works in go1.0.1 but not after this CL): package main import ( "io/ioutil" "log" "net/http" ) func foo(rw http.ResponseWriter, rq *http.Request) { // Set header indicating keep-alive connection should be closed rw.Header().Set("Connection", "close") // Message must be of meaningful size to cause failure for i := 0; i < 1024; i++ { rw.Write([]byte("foo ")) } } func init() { http.HandleFunc("/", foo) go func() { if err := http.ListenAndServe(":8081", nil); err != nil { panic(err) } }() } func main() { resp, err := http.Get("http://localhost:8081/") if err != nil { log.Fatal(err) } defer resp.Body.Close() log.Printf("%#v", resp) bs, err := ioutil.ReadAll(resp.Body) if err != nil { log.Fatal(err) } log.Print(string(bs)) }
Sign in to reply to this message.
Thanks for the report. Will fix. http://code.google.com/p/go/issues/detail?id=3644 On Sat, May 19, 2012 at 1:21 AM, <cookieo9@gmail.com> wrote: > Full example (works in go1.0.1 but not after this CL): > > package main > > import ( > "io/ioutil" > "log" > "net/http" > ) > > func foo(rw http.ResponseWriter, rq *http.Request) { > // Set header indicating keep-alive connection should be closed > rw.Header().Set("Connection", "close") > // Message must be of meaningful size to cause failure > for i := 0; i < 1024; i++ { > rw.Write([]byte("foo ")) > } > } > > func init() { > http.HandleFunc("/", foo) > go func() { > if err := http.ListenAndServe(":8081", nil); err != nil { > panic(err) > } > }() > } > > func main() { > resp, err := http.Get("http://localhost:**8081/<http://localhost:8081/> > ") > if err != nil { > log.Fatal(err) > } > defer resp.Body.Close() > log.Printf("%#v", resp) > > bs, err := ioutil.ReadAll(resp.Body) > if err != nil { > log.Fatal(err) > } > > log.Print(string(bs)) > } > > > > http://codereview.appspot.com/**6201044/<http://codereview.appspot.com/6201044/> >
Sign in to reply to this message.
*** Abandoned ***
Sign in to reply to this message.
hg change -D 6201044 not -d, despite what the helpful text says. On Fri, Jan 4, 2013 at 7:42 AM, <james@james4k.com> wrote: > *** Abandoned *** > > https://codereview.appspot.com/6201044/
Sign in to reply to this message.
Message was sent while issue was closed.
Eek, sorry. Thanks. On 2013/01/03 22:59:06, dfc wrote: > hg change -D 6201044 > > not -d, despite what the helpful text says. > > On Fri, Jan 4, 2013 at 7:42 AM, <mailto:james@james4k.com> wrote: > > *** Abandoned *** > > > > https://codereview.appspot.com/6201044/
Sign in to reply to this message.
|