diff options
author | nahi <nahi@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2011-05-31 08:10:42 +0000 |
---|---|---|
committer | nahi <nahi@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2011-05-31 08:10:42 +0000 |
commit | b219a56c07ad5d9fb1f6cddfb78e97eff1e89379 (patch) | |
tree | abbc8b358cb403ce305697538fd7c47f3a485f3a /lib/net | |
parent | da1db8b454c6f8f0714d762c72815cf73efba4d8 (diff) |
* lib/net/http.rb, lib/net/protocol.rb: Allow to configure to wait
server returning '100 continue' response befor sending HTTP request
body. See NEWS for more detail. See #3622.
Original patch is made by Eric Hodel <drbrain@segment7.net>.
* test/net/http/test_http.rb: test it.
* NEWS: Add new feature.
On my env (Ubuntu 11.04 64bit),
9510 tests, 2203824 assertions, 0 failures, 0 errors, 29 skips
->
9514 tests, 2203836 assertions, 0 failures, 0 errors, 29 skips
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@31860 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/net')
-rw-r--r-- | lib/net/http.rb | 45 | ||||
-rw-r--r-- | lib/net/protocol.rb | 2 |
2 files changed, 41 insertions, 6 deletions
diff --git a/lib/net/http.rb b/lib/net/http.rb index 4faf6c87ae..9a99338d50 100644 --- a/lib/net/http.rb +++ b/lib/net/http.rb @@ -581,6 +581,7 @@ module Net #:nodoc: @started = false @open_timeout = nil @read_timeout = 60 + @continue_timeout = nil @debug_output = nil @use_ssl = false @ssl_context = nil @@ -634,6 +635,16 @@ module Net #:nodoc: @read_timeout = sec end + # Seconds to wait for 100 Continue response. If the HTTP object does not + # receive a response in this many seconds it sends the request body. + attr_reader :continue_timeout + + # Setter for the continue_timeout attribute. + def continue_timeout=(sec) + @socket.continue_timeout = sec if @socket + @continue_timeout = sec + end + # Returns true if the HTTP session has been started. def started? @started @@ -764,6 +775,7 @@ module Net #:nodoc: end @socket = BufferedIO.new(s) @socket.read_timeout = @read_timeout + @socket.continue_timeout = @continue_timeout @socket.debug_output = @debug_output if use_ssl? begin @@ -1298,12 +1310,15 @@ module Net #:nodoc: def transport_request(req) begin_transport req - 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 = 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 @@ -1915,6 +1930,7 @@ module Net #:nodoc: delete 'Transfer-Encoding' supply_default_content_type write_header sock, ver, path + wait_for_continue sock, ver if sock.continue_timeout sock.write body end @@ -1925,6 +1941,7 @@ module Net #:nodoc: end supply_default_content_type write_header sock, ver, path + wait_for_continue sock, ver if sock.continue_timeout if chunked? while s = f.read(1024) sock.write(sprintf("%x\r\n", s.length) << s << "\r\n") @@ -2030,6 +2047,22 @@ module Net #:nodoc: set_content_type 'application/x-www-form-urlencoded' end + ## + # Waits up to the continue timeout for a response from the server provided + # we're speaking HTTP 1.1 and are expecting a 100-continue response. + + def wait_for_continue(sock, ver) + if ver >= '1.1' and @header['expect'] and + @header['expect'].include?('100-continue') + if IO.select([sock.io], nil, nil, sock.continue_timeout) + res = HTTPResponse.read_new(sock) + unless res.kind_of?(Net::HTTPContinue) + throw :response, res + end + end + end + end + def write_header(sock, ver, path) buf = "#{@method} #{path} HTTP/#{ver}\r\n" each_capitalized do |k,v| diff --git a/lib/net/protocol.rb b/lib/net/protocol.rb index f908f3a1d6..ab0e70e609 100644 --- a/lib/net/protocol.rb +++ b/lib/net/protocol.rb @@ -50,12 +50,14 @@ module Net # :nodoc: def initialize(io) @io = io @read_timeout = 60 + @continue_timeout = nil @debug_output = nil @rbuf = '' end attr_reader :io attr_accessor :read_timeout + attr_accessor :continue_timeout attr_accessor :debug_output def inspect |