[#104307] Float truncate — Eustáquio Rangel <eustaquiorangel@...>
Hi!
4 messages
2021/06/16
[ruby-core:104340] [Ruby master Feature#13396] Net::HTTP has no write timeout
From:
miguelfteixeira@...
Date:
2021-06-17 13:33:31 UTC
List:
ruby-core #104340
Issue #13396 has been updated by miguelfteixeira (Miguel Teixeira).
There's an open issue on `Net::HTTP#write_timeout` not working when `body_stream` is used: https://bugs.ruby-lang.org/issues/17933
I'm just sharing this here for visibility.
----------------------------------------
Feature #13396: Net::HTTP has no write timeout
https://bugs.ruby-lang.org/issues/13396#change-92563
* Author: byroot (Jean Boussier)
* Status: Closed
* Priority: Normal
* Assignee: naruse (Yui NARUSE)
----------------------------------------
When sending a large request to an unresponsive server, `Net::HTTP` can hang pretty much forever.
```ruby
# server.rb
require 'socket'
server = TCPServer.new('localhost', 2345)
loop do
socket = server.accept
end
```
```ruby
# client.rb
require 'net/http'
connection = Net::HTTP.new('localhost', 2345)
connection.open_timeout = 1
connection.read_timeout = 3
connection.start
post = Net::HTTP::Post.new('/')
body = (('a' * 1023) + "\n") * 5_000
post.body = body
puts "Sending #{body.bytesize} bytes"
connection.request(post)
```
The above code will hang forever on all system I tested it on (OSX / Linux 3.19).
The issue only trigger once the request body is above a certain threshold. That threshold depends on the system, I assume it's due to the system's TCP settings, but a request over 4MB will trigger the issue consistently.
I assume it happens when the request is bigger than the socket buffer.
It's stuck on the following path:
```
/net/protocol.rb:211:in `write': Interrupt
/net/protocol.rb:211:in `write0'
/net/protocol.rb:185:in `block in write'
/net/protocol.rb:202:in `writing'
/net/protocol.rb:184:in `write'
/net/http/generic_request.rb:188:in `send_request_with_body'
/net/http/generic_request.rb:121:in `exec'
/net/http.rb:1435:in `block in transport_request'
/net/http.rb:1434:in `catch'
/net/http.rb:1434:in `transport_request'
/net/http.rb:1407:in `request'
```
I tried setting `setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDTIMEO, ...)` on the client socket, but without success. However adding a `Timeout.timeout` call around `req.exec` did work.
--
https://bugs.ruby-lang.org/
Unsubscribe: <mailto:[email protected]?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>