aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiguel Teixeira <miguel.teixeira@onfido.com>2021-06-11 16:49:22 +0100
committerHiroshi SHIBATA <hsbt@ruby-lang.org>2021-07-29 15:53:54 +0900
commit60b02db5161625dd5f7d22d31989dd966837333c (patch)
tree16ef40804cb72084bf3b1d42daaa1a5da189916d
parentb3413914d949677fb975824b23d3e66dc0fa2fbe (diff)
downloadruby-60b02db5161625dd5f7d22d31989dd966837333c.tar.gz
[ruby/net-http] Enforce write timeout when body_stream is used
The existing implementation of `Net::HTTP#write_timeout` relies on `Net::BefferedIO` to trigger the `Net::WriteTimeout` error. This commit changes `send_request_with_body_stream` to remove the optimization that was making `Net::HTTP#write_timeout` not work when `body_stream` is used. Open issue: https://bugs.ruby-lang.org/issues/17933 https://github.com/ruby/net-http/commit/a0fab1ab52
-rw-r--r--lib/net/http/generic_request.rb4
-rw-r--r--test/net/http/test_http.rb28
2 files changed, 29 insertions, 3 deletions
diff --git a/lib/net/http/generic_request.rb b/lib/net/http/generic_request.rb
index 0b81243064..d6198cd624 100644
--- a/lib/net/http/generic_request.rb
+++ b/lib/net/http/generic_request.rb
@@ -202,9 +202,7 @@ class Net::HTTPGenericRequest
IO.copy_stream(f, chunker)
chunker.finish
else
- # copy_stream can sendfile() to sock.io unless we use SSL.
- # If sock.io is an SSLSocket, copy_stream will hit SSL_write()
- IO.copy_stream(f, sock.io)
+ IO.copy_stream(f, sock)
end
end
diff --git a/test/net/http/test_http.rb b/test/net/http/test_http.rb
index 60b6d51f99..89a7be199e 100644
--- a/test/net/http/test_http.rb
+++ b/test/net/http/test_http.rb
@@ -576,6 +576,34 @@ module TestNetHTTP_version_1_1_methods
th&.join
end
+ def test_timeout_during_non_chunked_streamed_HTTP_session_write
+ th = nil
+ # listen for connections... but deliberately do not read
+ TCPServer.open('localhost', 0) {|server|
+ port = server.addr[1]
+
+ conn = Net::HTTP.new('localhost', port)
+ conn.write_timeout = 0.01
+ conn.read_timeout = 0.01 if windows?
+ conn.open_timeout = 0.1
+
+ req = Net::HTTP::Post.new('/')
+ data = "a"*50_000_000
+ req.content_length = data.size
+ req['Content-Type'] = 'application/x-www-form-urlencoded'
+ req.body_stream = StringIO.new(data)
+
+ th = Thread.new do
+ err = !windows? ? Net::WriteTimeout : Net::ReadTimeout
+ assert_raise(err) { conn.request(req) }
+ end
+ assert th.join(10)
+ }
+ ensure
+ th&.kill
+ th&.join
+ end
+
def test_timeout_during_HTTP_session
bug4246 = "expected the HTTP session to have timed out but have not. c.f. [ruby-core:34203]"