summaryrefslogtreecommitdiff
path: root/lib/net/protocol.rb
diff options
context:
space:
mode:
authornaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-06-06 08:03:47 +0000
committernaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-06-06 08:03:47 +0000
commitbd7c46a7aa8b4f44ef683e22f469033b96d3dd5f (patch)
tree8100dd93ab2032f3d61f3b82e80b0d37f0ae2f82 /lib/net/protocol.rb
parentacc48fce30b413c158d06e5578ac73b07ed60b69 (diff)
Introduce write_timeout to Net::HTTP [Feature #13396]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63587 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/net/protocol.rb')
-rw-r--r--lib/net/protocol.rb39
1 files changed, 35 insertions, 4 deletions
diff --git a/lib/net/protocol.rb b/lib/net/protocol.rb
index 7ec636b384..cf9fc3d434 100644
--- a/lib/net/protocol.rb
+++ b/lib/net/protocol.rb
@@ -77,11 +77,18 @@ module Net # :nodoc:
class ReadTimeout < Timeout::Error; end
+ ##
+ # WriteTimeout, a subclass of Timeout::Error, is raised if a chunk of the
+ # response cannot be read within the read_timeout.
+
+ class WriteTimeout < Timeout::Error; end
+
class BufferedIO #:nodoc: internal use only
- def initialize(io, read_timeout: 60, continue_timeout: nil, debug_output: nil)
+ def initialize(io, read_timeout: 60, write_timeout: 60, continue_timeout: nil, debug_output: nil)
@io = io
@read_timeout = read_timeout
+ @write_timeout = write_timeout
@continue_timeout = continue_timeout
@debug_output = debug_output
@rbuf = ''.b
@@ -89,6 +96,7 @@ module Net # :nodoc:
attr_reader :io
attr_accessor :read_timeout
+ attr_accessor :write_timeout
attr_accessor :continue_timeout
attr_accessor :debug_output
@@ -237,9 +245,32 @@ module Net # :nodoc:
def write0(*strs)
@debug_output << strs.map(&:dump).join if @debug_output
- len = @io.write(*strs)
- @written_bytes += len
- len
+ case len = @io.write_nonblock(*strs, exception: false)
+ when Integer
+ orig_len = len
+ strs.each_with_index do |str, i|
+ @written_bytes += str.bytesize
+ len -= str.bytesize
+ if len == 0
+ if strs.size == i+1
+ return orig_len
+ else
+ strs = strs[i+1..] # rest
+ break
+ end
+ elsif len < 0
+ strs = strs[i..] # str and rest
+ strs[0] = str[len, -len]
+ break
+ else # len > 0
+ # next
+ end
+ end
+ # continue looping
+ when :wait_writable
+ @io.to_io.wait_writable(@write_timeout) or raise Net::WriteTimeout
+ # continue looping
+ end while true
end
#