[前][次][番号順一覧][スレッド一覧]

ruby-changes:66971

From: Miguel <ko1@a...>
Date: Thu, 29 Jul 2021 16:27:07 +0900 (JST)
Subject: [ruby-changes:66971] 60b02db516 (master): [ruby/net-http] Enforce write timeout when body_stream is used

https://git.ruby-lang.org/ruby.git/commit/?id=60b02db516

From 60b02db5161625dd5f7d22d31989dd966837333c Mon Sep 17 00:00:00 2001
From: Miguel Teixeira <miguel.teixeira@o...>
Date: Fri, 11 Jun 2021 16:49:22 +0100
Subject: [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
---
 lib/net/http/generic_request.rb |  4 +---
 test/net/http/test_http.rb      | 28 ++++++++++++++++++++++++++++
 2 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/lib/net/http/generic_request.rb b/lib/net/http/generic_request.rb
index 0b81243..d6198cd 100644
--- a/lib/net/http/generic_request.rb
+++ b/lib/net/http/generic_request.rb
@@ -202,9 +202,7 @@ class Net::HTTPGenericRequest https://github.com/ruby/ruby/blob/trunk/lib/net/http/generic_request.rb#L202
       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 60b6d51..89a7be1 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 https://github.com/ruby/ruby/blob/trunk/test/net/http/test_http.rb#L576
     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]"
 
-- 
cgit v1.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]