summaryrefslogtreecommitdiff
path: root/lib/net
diff options
context:
space:
mode:
authornaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-01-20 05:56:35 +0000
committernaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-01-20 05:56:35 +0000
commitbee7ccddd254c7b6e781f5ea9bbf651b50b590ee (patch)
tree63acb0605ff9e8cf88b5a5b2acd3efd5e854d691 /lib/net
parent87daaf61b9a6db7d4e4c7df9c72c4621ef0162c2 (diff)
* lib/net/http.rb (Net::HTTP#transport_request): retry a idempotent
request automatically. [ruby-dev:45030] [Bug #5790] [ruby-core:41821] [Bug #5813] * lib/net/http.rb (Net::HTTP#keep_alive_timeout=): added to specify the second to reconnect the TCP connection on Keep-Alive. The default value is 2 second because current servers uses 2 sec. http://ftp-admin.blogspot.com/2009/09/keepalivetimeout2.html * lib/net/http.rb (Net::HTTP#begin_transport): reconnect TCP connection on keep-alive timeout. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@34341 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/net')
-rw-r--r--lib/net/http.rb33
1 files changed, 31 insertions, 2 deletions
diff --git a/lib/net/http.rb b/lib/net/http.rb
index 879cfe0045..53093492c2 100644
--- a/lib/net/http.rb
+++ b/lib/net/http.rb
@@ -578,7 +578,8 @@ module Net #:nodoc:
@address = address
@port = (port || HTTP.default_port)
@curr_http_version = HTTPVersion
- @no_keepalive_server = false
+ @keep_alive_timeout = 2
+ @last_communicated = nil
@close_on_empty_response = false
@socket = nil
@started = false
@@ -648,6 +649,12 @@ module Net #:nodoc:
@continue_timeout = sec
end
+ # Seconds to reuse the connection of the previous request.
+ # If the idle time is less than this Keep-Alive Timeout,
+ # Net::HTTP reuses the TCP/IP socket used by the previous communication.
+ # The default value is 2 seconds.
+ attr_accessor :keep_alive_timeout
+
# Returns true if the HTTP session has been started.
def started?
@started
@@ -1332,7 +1339,10 @@ module Net #:nodoc:
res
end
+ IDEMPOTENT_METHODS_ = %w/GET HEAD PUT DELETE OPTIONS TRACE/ # :nodoc:
+
def transport_request(req)
+ count = 0
begin_transport req
res = catch(:response) {
req.exec @socket, @curr_http_version, edit_path(req.path)
@@ -1346,6 +1356,16 @@ module Net #:nodoc:
}
end_transport req, res
res
+ 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?
@@ -1353,7 +1373,14 @@ module Net #:nodoc:
end
def begin_transport(req)
- connect if @socket.closed?
+ if @socket.closed?
+ connect
+ elsif @last_communicated && @last_communicated + @keep_alive_timeout < Time.now
+ D 'Conn close because of keep_alive_timeout'
+ @socket.close
+ connect
+ end
+
if not req.response_body_permitted? and @close_on_empty_response
req['connection'] ||= 'close'
end
@@ -1362,6 +1389,7 @@ module Net #:nodoc:
def end_transport(req, res)
@curr_http_version = res.http_version
+ @last_communicated = nil
if @socket.closed?
D 'Conn socket closed'
elsif not res.body and @close_on_empty_response
@@ -1369,6 +1397,7 @@ module Net #:nodoc:
@socket.close
elsif keep_alive?(req, res)
D 'Conn keep-alive'
+ @last_communicated = Time.now
else
D 'Conn close'
@socket.close