If Net::HTTP's open_timeout and read_timeout are not set, will it wait indefinitely?

StackOverflow https://stackoverflow.com/questions/20450314

  •  30-08-2022
  •  | 
  •  

Question

If Net::HTTP's open_timeout and read_timeout are not set, will it wait indefinitely?

According to the docs, open_timeout is defined as:

Number of seconds to wait for the connection to open. Any number may be used, including Floats for fractional seconds. If the HTTP object cannot open a connection in this many seconds, it raises a Net::OpenTimeout exception. The default value is nil.

OK so the default value is nil. What happens if the server (say, a malicious server) never responds and the client has not set an open_timeout? Will the client wait indefinitely?

I ask because I am trying to debug a scenario in which all of my processes are hung, indefinitely, with an SSL connection request at the top of the stack:

#0  0x00007f33a07acb13 in ppoll () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x00007f33a1962558 in rb_wait_for_single_fd (fd=<optimized out>, events=<optimized out>, tv=0x0) at thread.c:3583
#2  0x00007f33a1966ea2 in rb_thread_wait_fd_rw (read=1, fd=<optimized out>) at thread.c:3422
#3  rb_thread_wait_fd (fd=<optimized out>) at thread.c:3433
#4  0x00007f33a1854ebf in rb_io_wait_readable (f=40) at io.c:1081
#5  0x00007f339ed72184 in ossl_start_ssl (self=139859849103720, func=0x7f339eb1ab20 <SSL_connect>, funcname=0x7f339ed82d89 "SSL_connect", nonblock=<optimized out>) at ossl_ssl.c:1278

Which was apparently triggered by this call:

from /usr/local/lib/ruby/gems/2.0.0/gems/httparty-0.11.0/lib/httparty.rb:497:in `post'
from /usr/local/lib/ruby/gems/2.0.0/gems/httparty-0.11.0/lib/httparty.rb:414:in `post'
from /usr/local/lib/ruby/gems/2.0.0/gems/httparty-0.11.0/lib/httparty.rb:461:in `perform_request'
from /usr/local/lib/ruby/gems/2.0.0/gems/httparty-0.11.0/lib/httparty/request.rb:92:in `perform'
from /usr/local/lib/ruby/2.0.0/net/http.rb:1367:in `request'
from /usr/local/lib/ruby/2.0.0/net/http.rb:851:in `start'
from /usr/local/lib/ruby/2.0.0/net/http.rb:862:in `do_start'
from /usr/local/lib/ruby/2.0.0/net/http.rb:918:in `connect'
from /usr/local/lib/ruby/2.0.0/timeout.rb:52:in `timeout'
from /usr/local/lib/ruby/2.0.0/net/http.rb:918:in `block in connect'
from /usr/local/lib/ruby/2.0.0/net/http.rb:918:in `connect'
Was it helpful?

Solution

This actually means that server exists and accepts the request, but doesn’t return data, still keeping a connection open. Yes, in a case of such a malicious server the client will hang up.

There is no default timeout in Net::HTTP. In normal scenario it will receive HTTPRequestTimeOut response (which server is on duty of.) If you feel there might be any problem, you set the timeout yourself. But sometimes you really need to wait infinitely (server is processing large amount of data and you know it.)

Actually, I’d suggest it’s not a Net::HTTP problem. Matz has already had problems with rb_wait_for_single_fd calls. It actually looks like deadlock inside ruby thread synching, not like a server hangup.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top