ruby-changes:22730
From: drbrain <ko1@a...>
Date: Fri, 24 Feb 2012 10:10:28 +0900 (JST)
Subject: [ruby-changes:22730] drbrain:r34779 (trunk): * lib/net/http.rb (Net::HTTP#transport_request): Fix infinite loop
drbrain 2012-02-24 10:10:07 +0900 (Fri, 24 Feb 2012) New Revision: 34779 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=34779 Log: * lib/net/http.rb (Net::HTTP#transport_request): Fix infinite loop upon EOFError or Errno::ECONNRESET where count is reset to 0. * test/net/http/test_http.rb (class TestNetHTTPKeepAlive): Test for above. Modified files: trunk/ChangeLog trunk/lib/net/http.rb trunk/test/net/http/test_http.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 34778) +++ ChangeLog (revision 34779) @@ -1,3 +1,10 @@ +Fri Feb 24 10:08:33 2012 Eric Hodel <drbrain@s...> + + * lib/net/http.rb (Net::HTTP#transport_request): Fix infinite loop + upon EOFError or Errno::ECONNRESET where count is reset to 0. + * test/net/http/test_http.rb (class TestNetHTTPKeepAlive): Test for + above. + Fri Feb 24 09:05:40 2012 Eric Hodel <drbrain@s...> * complex.c (Init_Complex): Document Complex::I. Patch by Sylvain Index: lib/net/http.rb =================================================================== --- lib/net/http.rb (revision 34778) +++ lib/net/http.rb (revision 34779) @@ -1343,33 +1343,35 @@ def transport_request(req) count = 0 - begin_transport req - res = catch(:response) { - req.exec @socket, @curr_http_version, edit_path(req.path) - begin - res = HTTPResponse.read_new(@socket) - end while res.kind_of?(HTTPContinue) - res.reading_body(@socket, req.response_body_permitted?) { - yield res if block_given? + begin + begin_transport req + res = catch(:response) { + req.exec @socket, @curr_http_version, edit_path(req.path) + begin + res = HTTPResponse.read_new(@socket) + end while res.kind_of?(HTTPContinue) + res.reading_body(@socket, req.response_body_permitted?) { + yield res if block_given? + } + res } + end_transport req, res res - } - end_transport req, res - res - rescue EOFError, Errno::ECONNRESET => exception - if count == 0 && IDEMPOTENT_METHODS_.include?(req.method) - count += 1 + rescue EOFError, Errno::ECONNRESET => exception + if count == 0 && IDEMPOTENT_METHODS_.include?(req.method) + count += 1 + @socket.close if @socket and not @socket.closed? + D "Conn close because of error #{exception}, and retry" + retry + end + D "Conn close because of error #{exception}" @socket.close if @socket and not @socket.closed? - D "Conn close because of error #{exception}, and retry" - retry + raise + rescue => exception + D "Conn close because of error #{exception}" + @socket.close if @socket and not @socket.closed? + raise exception end - D "Conn close because of error #{exception}" - @socket.close if @socket and not @socket.closed? - raise - rescue => exception - D "Conn close because of error #{exception}" - @socket.close if @socket and not @socket.closed? - raise exception end def begin_transport(req) Index: test/net/http/test_http.rb =================================================================== --- test/net/http/test_http.rb (revision 34778) +++ test/net/http/test_http.rb (revision 34779) @@ -605,4 +605,16 @@ assert_kind_of String, res.body } end + + def test_keep_alive_EOF + def @server.run(sock) + sock.close + end + + start {|http| + assert_raises(EOFError) { + res = http.get('/') + } + } + end end -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/