summaryrefslogtreecommitdiff
path: root/lib/net/http.rb
diff options
context:
space:
mode:
authornahi <nahi@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-05-31 08:10:42 +0000
committernahi <nahi@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-05-31 08:10:42 +0000
commitb219a56c07ad5d9fb1f6cddfb78e97eff1e89379 (patch)
treeabbc8b358cb403ce305697538fd7c47f3a485f3a /lib/net/http.rb
parentda1db8b454c6f8f0714d762c72815cf73efba4d8 (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/http.rb')
-rw-r--r--lib/net/http.rb45
1 files changed, 39 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|