Feature #13379 » imap.patch
lib/net/imap.rb | ||
---|---|---|
require "monitor"
|
||
require "digest/md5"
|
||
require "strscan"
|
||
require 'net/protocol'
|
||
begin
|
||
require "openssl"
|
||
rescue LoadError
|
||
... | ... | |
# Returns all response handlers.
|
||
attr_reader :response_handlers
|
||
# Seconds to wait until a connection is opened.
|
||
# If the IMAP object cannot open a connection within this time,
|
||
# it raises a Net::OpenTimeout exception. The default value is 30 seconds.
|
||
attr_reader :open_timeout
|
||
# Seconds to wait until reading one block (by one read(1) call).
|
||
# If the IMAP object cannot complete a read() within this time,
|
||
# it raises a Net::ReadTimeout exception. The default value is 60 seconds.
|
||
attr_reader :read_timeout
|
||
# The thread to receive exceptions.
|
||
attr_accessor :client_thread
|
||
... | ... | |
# be installed.
|
||
# If options[:ssl] is a hash, it's passed to
|
||
# OpenSSL::SSL::SSLContext#set_params as parameters.
|
||
# open_timeout:: Seconds to wait until a connection is opened
|
||
# read_timeout:: Seconds to wait until reading one block
|
||
#
|
||
# The most common errors are:
|
||
#
|
||
... | ... | |
@port = options[:port] || (options[:ssl] ? SSL_PORT : PORT)
|
||
@tag_prefix = "RUBY"
|
||
@tagno = 0
|
||
@open_timeout = options[:open_timeout] || 30
|
||
@read_timeout = options[:read_timeout] || 60
|
||
@parser = ResponseParser.new
|
||
@sock = TCPSocket.open(@host, @port)
|
||
@sock = Socket.tcp(@host, @port, :connect_timeout => @open_timeout)
|
||
begin
|
||
if options[:ssl]
|
||
start_tls_session(options[:ssl])
|
||
... | ... | |
end
|
||
end
|
||
def get_response_data(length, terminator = nil)
|
||
str = nil
|
||
buff = String.new
|
||
while true
|
||
str = @sock.read_nonblock(length, :exception => false)
|
||
case str
|
||
when :wait_readable
|
||
@sock.to_io.wait_readable(@read_timeout) or
|
||
raise Net::ReadTimeout, "#{@host}:#{@port} read timeout (exceeds #{@read_timeout} seconds)"
|
||
when nil
|
||
break
|
||
else
|
||
buff.concat(str)
|
||
if terminator ? buff.include?(terminator) : (buff.length >= length)
|
||
break
|
||
end
|
||
end
|
||
end
|
||
buff
|
||
end
|
||
def get_response
|
||
buff = String.new
|
||
while true
|
||
s = @sock.gets(CRLF)
|
||
break unless s
|
||
s = get_response_data(1, CRLF)
|
||
break if s.length == 0
|
||
buff.concat(s)
|
||
if /\{(\d+)\}\r\n/n =~ s
|
||
s = @sock.read($1.to_i)
|
||
s = get_response_data($1.to_i)
|
||
buff.concat(s)
|
||
else
|
||
break
|