summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--lib/net/imap.rb14
-rw-r--r--test/net/imap/test_imap.rb44
3 files changed, 61 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 12b006c28a..5c2d1b27f9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Thu Oct 22 18:25:10 2015 Shugo Maeda <shugo@ruby-lang.org>
+
+ * lib/net/imap (idle): add a new argument timeout for keep-alive.
+ [ruby-core:63693] [Bug #10031]
+
Thu Oct 22 15:30:08 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
* compile.c (iseq_peephole_optimize): peephole optimization for
diff --git a/lib/net/imap.rb b/lib/net/imap.rb
index cc7935ec43..5d642ecac4 100644
--- a/lib/net/imap.rb
+++ b/lib/net/imap.rb
@@ -935,7 +935,17 @@ module Net
# messages. Yields responses from the server during the IDLE.
#
# Use #idle_done() to leave IDLE.
- def idle(&response_handler)
+ #
+ # If +timeout+ is given, this method returns after +timeout+ seconds passed.
+ # +timeout+ can be used for keep-alive. For example, the following code
+ # checks the connection for each 60 seconds.
+ #
+ # loop do
+ # imap.idle(60) do |res|
+ # ...
+ # end
+ # end
+ def idle(timeout = nil, &response_handler)
raise LocalJumpError, "no block given" unless response_handler
response = nil
@@ -947,7 +957,7 @@ module Net
begin
add_response_handler(response_handler)
@idle_done_cond = new_cond
- @idle_done_cond.wait
+ @idle_done_cond.wait(timeout)
@idle_done_cond = nil
if @receiver_thread_terminating
raise Net::IMAP::Error, "connection closed"
diff --git a/test/net/imap/test_imap.rb b/test/net/imap/test_imap.rb
index bf57aa5cc4..20172204e3 100644
--- a/test/net/imap/test_imap.rb
+++ b/test/net/imap/test_imap.rb
@@ -285,6 +285,50 @@ class IMAPTest < Test::Unit::TestCase
end
end
+ def test_idle_timeout
+ server = create_tcp_server
+ port = server.addr[1]
+ requests = []
+ @threads << Thread.start do
+ sock = server.accept
+ begin
+ sock.print("* OK test server\r\n")
+ requests.push(sock.gets)
+ sock.print("+ idling\r\n")
+ sock.print("* 3 EXISTS\r\n")
+ sock.print("* 2 EXPUNGE\r\n")
+ requests.push(sock.gets)
+ sock.print("RUBY0001 OK IDLE terminated\r\n")
+ sock.gets
+ sock.print("* BYE terminating connection\r\n")
+ sock.print("RUBY0002 OK LOGOUT completed\r\n")
+ ensure
+ sock.close
+ server.close
+ end
+ end
+
+ begin
+ imap = Net::IMAP.new(SERVER_ADDR, :port => port)
+ responses = []
+ imap.idle(0.1) do |res|
+ responses.push(res)
+ end
+ assert_equal(3, responses.length)
+ assert_instance_of(Net::IMAP::ContinuationRequest, responses[0])
+ assert_equal("EXISTS", responses[1].name)
+ assert_equal(3, responses[1].data)
+ assert_equal("EXPUNGE", responses[2].name)
+ assert_equal(2, responses[2].data)
+ assert_equal(2, requests.length)
+ assert_equal("RUBY0001 IDLE\r\n", requests[0])
+ assert_equal("DONE\r\n", requests[1])
+ imap.logout
+ ensure
+ imap.disconnect if imap
+ end
+ end
+
def test_unexpected_bye
server = create_tcp_server
port = server.addr[1]