aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--lib/net/http.rb48
-rw-r--r--test/net/http/test_http.rb12
3 files changed, 44 insertions, 23 deletions
diff --git a/ChangeLog b/ChangeLog
index dbc18cb873..9e405bcb9c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Fri Feb 24 10:08:33 2012 Eric Hodel <drbrain@segment7.net>
+
+ * 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@segment7.net>
* complex.c (Init_Complex): Document Complex::I. Patch by Sylvain
diff --git a/lib/net/http.rb b/lib/net/http.rb
index b6e5de0a54..690690ae28 100644
--- a/lib/net/http.rb
+++ b/lib/net/http.rb
@@ -1343,33 +1343,35 @@ module Net #:nodoc:
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?
+ raise
+ rescue => exception
+ 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 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)
diff --git a/test/net/http/test_http.rb b/test/net/http/test_http.rb
index 6de57d3196..e2cfb42670 100644
--- a/test/net/http/test_http.rb
+++ b/test/net/http/test_http.rb
@@ -605,4 +605,16 @@ class TestNetHTTPKeepAlive < Test::Unit::TestCase
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