From: shugo@... Date: 2017-03-29T02:33:16+00:00 Subject: [ruby-core:80442] [Ruby trunk Feature#13379] [PATCH] safe IMAP connections Issue #13379 has been updated by shugo (Shugo Maeda). Assignee set to shugo (Shugo Maeda) ahorek (Pavel Rosick��) wrote: > Hi, > I found out that using the standard IMAP library isn't very safe. It can be forced to hang the whole application. > > the problem is here > ``` > s = @sock.gets(CRLF) > ``` > -> the server accepted the connection but it didn't send any data. Now I need to reboot the server because my thread is blocked forever. > > I have no other option but to use this > ``` > Timeout.timeout(timeout, Net::OpenTimeout) { Net::IMAP.new(host, port, ssl) } > ``` > > which basically works, but I really don't want to create a new thread for each IMAP call, so I did these changes: > 1/ replaced TCPSocket with Socket.tcp > 2/ replaced sock.read and sock.gets with sock.read_nonblock > > now it works as expected. > > Patch > https://github.com/ruby/ruby/pull/1557 Thanks for the patch, but it doesn't seem enough because: 1. The :connect_timeout option of Socket.tcp doesn't work when DNS lookups by getaddrinfo block. A new thread by Timeout.timeout is needed to handle this case. 2. TLS handshakes in start_tls_session may also block. Protocol#ssl_socket_connect can be used to handle this case. And I'm not sure whether open_timeout should have the default value because a new thread is required. ---------------------------------------- Feature #13379: [PATCH] safe IMAP connections https://bugs.ruby-lang.org/issues/13379#change-63933 * Author: ahorek (Pavel Rosick��) * Status: Open * Priority: Normal * Assignee: shugo (Shugo Maeda) * Target version: ---------------------------------------- Hi, I found out that using the standard IMAP library isn't very safe. It can be forced to hang the whole application. the problem is here ``` s = @sock.gets(CRLF) ``` -> the server accepted the connection but it didn't send any data. Now I need to reboot the server because my thread is blocked forever. I have no other option but to use this ``` Timeout.timeout(timeout, Net::OpenTimeout) { Net::IMAP.new(host, port, ssl) } ``` which basically works, but I really don't want to create a new thread for each IMAP call, so I did these changes: 1/ replaced TCPSocket with Socket.tcp 2/ replaced sock.read and sock.gets with sock.read_nonblock now it works as expected. Patch https://github.com/ruby/ruby/pull/1557 related issue, please consider merging this one as well #12928 ---Files-------------------------------- imap.patch (3.29 KB) -- https://bugs.ruby-lang.org/ Unsubscribe: