mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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
This commit is contained in:
parent
87daaf61b9
commit
bee7ccddd2
4 changed files with 90 additions and 2 deletions
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
|||
Fri Jan 20 14:31:43 2012 NARUSE, Yui <naruse@ruby-lang.org>
|
||||
|
||||
* 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.
|
||||
|
||||
Thu Jan 19 07:53:09 2012 Tadayoshi Funaba <tadf@dotrb.org>
|
||||
|
||||
* ext/date/date_strptime.c: moved detector of leftover.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -564,3 +564,47 @@ class TestNetHTTPContinue < Test::Unit::TestCase
|
|||
assert_not_match(/HTTP\/1.1 100 continue/, @debug.string)
|
||||
end
|
||||
end
|
||||
|
||||
class TestNetHTTPKeepAlive < Test::Unit::TestCase
|
||||
CONFIG = {
|
||||
'host' => '127.0.0.1',
|
||||
'port' => 10081,
|
||||
'proxy_host' => nil,
|
||||
'proxy_port' => nil,
|
||||
'RequestTimeout' => 1,
|
||||
}
|
||||
|
||||
include TestNetHTTPUtils
|
||||
|
||||
def test_keep_alive_get_auto_reconnect
|
||||
start {|http|
|
||||
http.set_debug_output($stderr)
|
||||
res = http.get('/')
|
||||
http.keep_alive_timeout = 1
|
||||
assert_kind_of Net::HTTPResponse, res
|
||||
assert_kind_of String, res.body
|
||||
sleep 1.5
|
||||
assert_nothing_raised {
|
||||
res = http.get('/')
|
||||
}
|
||||
assert_kind_of Net::HTTPResponse, res
|
||||
assert_kind_of String, res.body
|
||||
}
|
||||
end
|
||||
|
||||
def test_keep_alive_get_auto_retry
|
||||
start {|http|
|
||||
http.set_debug_output($stderr)
|
||||
res = http.get('/')
|
||||
http.keep_alive_timeout = 5
|
||||
assert_kind_of Net::HTTPResponse, res
|
||||
assert_kind_of String, res.body
|
||||
sleep 1.5
|
||||
assert_nothing_raised {
|
||||
res = http.get('/')
|
||||
}
|
||||
assert_kind_of Net::HTTPResponse, res
|
||||
assert_kind_of String, res.body
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -51,6 +51,7 @@ module TestNetHTTPUtils
|
|||
:ServerType => Thread,
|
||||
}
|
||||
server_config[:OutputBufferSize] = 4 if config('chunked')
|
||||
server_config[:RequestTimeout] = config('RequestTimeout') if config('RequestTimeout')
|
||||
if defined?(OpenSSL) and config('ssl_enable')
|
||||
server_config.update({
|
||||
:SSLEnable => true,
|
||||
|
|
Loading…
Reference in a new issue