Bug #9744
closedUse Ruby DNS resolver to handle DNS timeout in Net::HTTP
Description
This is a patch for Net::HTTP standard library.
I ran into an issue when DNS resolution failed because of poor network connection. In this case, even though I had Net::HTTP open_timeout set it didn't stop the operation but kept hanging until some low level timeout (30s) stopped it. I was seeing error messages like this:
getaddrinfo: nodename nor servname provided, or not known for host ******:80
I traced it to lib/net/http.rb:880
where it calls TCPSocket.open
within Timeout.timeout
block. I dived into the C code for TCPSocket and eventually found a syscall to getaddrinfo
. This is a blocking syscall which cannot be handled by Ruby timeout mechanism.
I'm not sure why this issue hasn't been reported before. I think open_timeout
should halt the execution no matter if there is an issue with DNS or opening network connection to the host.
I looked for people experiencing similar issues and found this thread. I took the idea for my patch from there. This small patch calls Ruby DNS resolver first before passing connection address to TCPSocket. Ruby DNS resolver works nice with timeouts.
As far as I can see it shouldn't introduce any problems or significant performance degradation. Please review and give your feedback.
For everybody else experiencing this issue as a workaround I suggest to use Resolv.getaddress(hostname)
inside Timeout.timeout
block before passing connection address to Net::HTTP. If this patch gets accepted it will make Net::HTTP open_timeout more reliable for everyone.
I opened a pull request on GitHub: https://github.com/ruby/ruby/pull/597
Files
Updated by hsbt (Hiroshi SHIBATA) almost 10 years ago
- Status changed from Open to Rejected