非常教程

Ruby 2.4参考手册

Net::IMAP

Net::IMAP

父:ObjectIncluded模块:MonitorMixin,OpenSSL,OpenSSL :: SSL

Net :: IMAP实现Internet消息访问协议(IMAP)客户端功能。该协议在IMAP中进行了描述。

IMAP概述

IMAP客户端连接到服务器,然后使用authenticate()或login()进行身份验证。通过身份验证后,可以使用一系列命令。大多数使用邮箱,可以安排在分层名称空间中,并且每个邮箱都包含零个或多个邮件。这在服务器上如何实现是依赖于实现的; 在UNIX服务器上,它经常以目录层次结构中的邮箱格式实现为文件。

要处理邮箱内的邮件,客户端必须首先使用select()或(对于只读访问)examine()来选择该邮箱。一旦客户端成功选择了一个邮箱,它们就进入选定状态,并且该邮箱成为当前邮箱,邮件项目相关命令将隐式操作。

消息有两种标识符:消息序列号和UID。

消息序号将邮箱中的邮件数从1增加到邮箱中的邮件数。如果新消息在会话期间到达,它会收到一个等于邮箱新大小的序列号。如果从邮箱中删除邮件,则剩余的邮件会将其序列号“乱码”以填补空白。

另一方面,UID永久保证不会在同一个邮箱中标识另一个邮件,即使现有邮件已被删除。UID需要在邮箱内以升序(但不一定是顺序)顺序进行分配; 这意味着如果非IMAP客户端重新排列邮箱中邮件项目的顺序,则必须重新分配UID。因此,IMAP客户端无法重新排列消息订单。

使用示例

列出默认邮箱中所有最近消息的发件人和主题

imap = Net::IMAP.new('mail.example.com')
imap.authenticate('LOGIN', 'joe_user', 'joes_password')
imap.examine('INBOX')
imap.search(["RECENT"]).each do |message_id|
  envelope = imap.fetch(message_id, "ENVELOPE")[0].attr["ENVELOPE"]
  puts "#{envelope.from[0].name}: \t#{envelope.subject}"
end

将所有邮件从2003年4月的“邮件/发送邮件”从“Mail / sent-apr03”

imap = Net::IMAP.new('mail.example.com')
imap.authenticate('LOGIN', 'joe_user', 'joes_password')
imap.select('Mail/sent-mail')
if not imap.list('Mail/', 'sent-apr03')
  imap.create('Mail/sent-apr03')
end
imap.search(["BEFORE", "30-Apr-2003", "SINCE", "1-Apr-2003"]).each do |message_id|
  imap.copy(message_id, "Mail/sent-apr03")
  imap.store(message_id, "+FLAGS", [:Deleted])
end
imap.expunge

线程安全

Net :: IMAP支持并发线程。例如,

imap = Net::IMAP.new("imap.foo.net", "imap2")
imap.authenticate("cram-md5", "bar", "password")
imap.select("inbox")
fetch_thread = Thread.start { imap.fetch(1..-1, "UID") }
search_result = imap.search(["BODY", "hello"])
fetch_result = fetch_thread.value
imap.disconnect

该脚本同时调用FETCH命令和SEARCH命令。

错误

IMAP服务器可以发送三种不同类型的响应来指示失败:

NO

试图执行的命令无法成功完成。例如,用于登录的用户名/密码不正确; 所选邮箱不存在; 等等

BAD

来自客户端的请求并不遵循服务器对IMAP协议的理解。这包括尝试来自错误的客户端状态的命令; 例如,试图在没有选择当前邮箱的情况下执行SEARCH命令。它也可能表示发生了内部服务器故障(如磁盘崩溃)。

BYE

服务器正在说再见。这可以是正常注销序列的一部分,并且可以用作登录序列的一部分,以表明服务器(由于某种原因)不愿意接受您的连接。作为对任何其他命令的响应,它表明服务器正在关闭,或者服务器由于不活动而超时客户端连接。

这三个错误响应由错误Net :: IMAP :: NoResponseError,Net :: IMAP :: BadResponseError和Net :: IMAP :: ByeResponseError表示,所有这些都是Net :: IMAP :: ResponseError的子类。从本质上讲,所有涉及向服务器发送请求的方法都可能会产生这些错误之一。以下仅记录最相关的实例。

由于IMAP类使用套接字进行通信,因此其方法也易受使用套接字时可能发生的各种错误的影响。这些通常表示为Errno错误。例如,任何涉及向服务器发送请求和/或从其接收响应的方法都会在网络连接意外关闭时引发Errno :: EPIPE错误。请参阅套接字(7),ip(7),tcp(7),套接字(2),连接(2)以及关联的手册页。

最后,如果发现低级别数据的格式不正确(例如,在UTF-8和UTF-16之间转换时),则Net :: IMAP :: DataFormatError被抛出,并且Net :: IMAP :: ResponseParseError为如果服务器响应不可解析则抛出。

参考

IMAP

  • Crispin,“INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4rev1”,

RFC 2060,December 1996.(注:由于RFC 3501已经过时)

LANGUAGE-TAGS

Alvestrand,H.,“用于识别语言的标签”,RFC 1766,1995年3月。

MD5

Myers,J.和M. Rose,“Content-MD5 Header Field”,RFC 1864,1995年10月。

MIME-IMB

Freed,N.和N.Borenstein,“MIME(多用途因特网邮件扩展)第一部分:Internet消息体的格式”,RFC 2045,1996年11月。

RFC-822

Crocker,D.,“ARPA因特网文本消息格式标准”,STD 11,RFC 822,特拉华大学,1982年8月。

RFC-2087

Myers,J。,“IMAP4 QUOTA扩展”,RFC 2087,1997年1月。

RFC-2086

Myers,J.,“IMAP4 ACL扩展”,RFC 2086,1997年1月。

RFC-2195

Klensin,J.,Catoe,R.和Krumviede,P.,“IMAP / POP AUTHorize Extension for Simple Challenge / Response”,RFC 2195,1997年9月。

SORT-THREAD-EXT

Crispin,M.,“INTERNET MESSAGE ACCESS PROTOCOL - SORT和THREAD Extensions”,Draft-ietf-imapext-sort,2003年5月。

OSSL

www.openssl.org

RSSL

savannah.gnu.org/projects/rubypki

UTF7

Goldsmith,D。和Davis,M.,“UTF-7:Unicode的邮件安全转换格式”,RFC 2152,1997年5月。

常量

ANSWERED

指示消息的标志已被回答。

Address

Net :: IMAP :: Address表示电子邮件地址。

领域:

name

从RFC-822邮箱返回短语。

route

返回RFC-822 route-addr的路由。

mailbox

nil表示RFC-822组的结束。如果非零和主机为零,则返回RFC-822组名。否则,返回RFC-822本地部分。

host

nil表示RFC-822组语法。否则,返回RFC-822域名。

ContentDisposition

Net :: IMAP :: ContentDisposition表示Content-Disposition字段。

Fields:

dsp_type

返回处置类型。

param

返回表示Content-Disposition字段参数的散列。

ContinuationRequest

Net :: IMAP :: ContinuationRequest表示命令继续请求。

命令继续请求响应由“+”标记而不是标记指示。这种形式的响应表明服务器已准备好接受来自客户端的命令的继续。这个回应的其余部分是一行文字。

continue_req    ::= "+" SPACE (resp_text / base64)

Fields:

data

返回数据(Net :: IMAP :: ResponseText)。

raw_data

返回原始数据字符串。

DATE_MONTH DELETED

指示消息的标志已被标记为删除。邮箱关闭或清除时会发生这种情况。

DRAFT

指示消息的标志只是草稿或正在进行中的版本。

Envelope

Net :: IMAP :: Envelope表示消息的信封结构。

Fields:

date

返回表示日期的字符串。

subject

返回表示主题的字符串。

from

返回表示from的Net :: IMAP :: Address数组。

sender

返回表示发件人的Net :: IMAP :: Address数组。

reply_to

返回表示答复的Net :: IMAP :: Address数组。

to

返回表示to的Net :: IMAP :: Address数组。

cc

返回表示cc的Net :: IMAP :: Address数组。

bcc

返回表示密件抄送的Net :: IMAP :: Address数组。

in_reply_to

返回一个表示in-reply-to的字符串。

message_id

返回表示消息ID的字符串。

FLAGGED

表示消息的标志已被标记为特别或紧急关注。

FetchData

Net :: IMAP :: FetchData表示FETCH响应的内容。

Fields:

seqno

返回消息序列号。(注意:即使对于UID命令响应,也不是唯一标识符。)

attr

返回一个散列。每个键都是数据项名称,每个值都是其值。

目前的数据项是:

BODY

没有扩展数据的BODYSTRUCTURE形式。

Net::IMAP::BodyTypeBasic, Net::IMAP::BodyTypeText, Net::IMAP::BodyTypeMessage, Net::IMAP::BodyTypeMultipart. ENVELOPE

描述消息信封结构的Net :: IMAP :: Envelope对象。

FLAGS

为此消息设置的标志符号数组。标志符号大写字符串#大写。

INTERNALDATE

表示消息内部日期的字符串。

RFC822

相当于BODY []。

RFC822.HEADER

Equivalent to BODY.PEEK.

RFC822.SIZE

表示消息的RFC-822大小的数字。

RFC822.TEXT

相当于BODY。

UID

表示消息唯一标识符的数字。

MARKED

指示邮箱已被服务器标记为“有趣”的标志; 这通常表示邮箱包含新邮件。

MailboxACLItem

Net :: IMAP :: MailboxACLItem表示来自GETACL的响应。

acl_data        ::= "ACL" SPACE mailbox *(SPACE identifier SPACE rights)

identifier      ::= astring

rights          ::= astring

Fields:

user

对使用getacl命令指定的邮箱具有某些权限的登录名。

rights

指定用户对邮箱的访问权限。

MailboxList

Net :: IMAP :: MailboxList表示LIST响应的内容。

mailbox_list    ::= "(" #("\Marked" / "\Noinferiors" /
                    "\Noselect" / "\Unmarked" / flag_extension) ")"
                    SPACE (<"> QUOTED_CHAR <"> / nil) SPACE mailbox

Fields:

attr

返回名称属性。每个名称属性都是由String#capitalize大写的符号,例如:Noselect(not:NoSelect)。

delim

返回层次结构分隔符。

name

返回邮箱名称。

MailboxQuota

Net :: IMAP :: MailboxQuota表示GETQUOTA响应的内容。该对象也可以是对GETQUOTAROOT的响应。在下面的语法规范中,与“#”构造一起使用的分隔符是单个空格(SPACE)。

quota_list      ::= "(" #quota_resource ")"

quota_resource  ::= atom SPACE number SPACE number

quota_response  ::= "QUOTA" SPACE astring SPACE quota_list

Fields:

mailbox

带有关联配额的邮箱。

usage

邮箱的当前存储使用情况。

quota

对邮箱施加配额限制。

MailboxQuotaRoot

Net :: IMAP :: MailboxQuotaRoot表示GETQUOTAROOT响应的一部分。(GETQUOTAROOT也可以返回Net :: IMAP :: MailboxQuota。)

quotaroot_response ::= "QUOTAROOT" SPACE astring *(SPACE astring)

Fields:

mailbox

带有关联配额的邮箱。

quotaroots

影响指定邮箱配额的零个或多个quotaroots。

NOINFERIORS

指示邮箱上下文名称不能包含子项的标志。

NOSELECT

表示邮箱未被选中的标志。

RECENT

表示该消息为“最近”的标志,表示该会话是客户端已收到此消息通知的第一个会话。

ResponseCode

Net :: IMAP :: ResponseCode表示响应代码。

resp_text_code  ::= "ALERT" / "PARSE" /
                    "PERMANENTFLAGS" SPACE "(" #(flag / "\*") ")" /
                    "READ-ONLY" / "READ-WRITE" / "TRYCREATE" /
                    "UIDVALIDITY" SPACE nz_number /
                    "UNSEEN" SPACE nz_number /
                    atom [SPACE 1*<any TEXT_CHAR except "]">]

Fields:

name

返回名称,例如“ALERT”,“PERMANENTFLAGS”或“UIDVALIDITY”。

data

返回数据(如果存在)。

ResponseText

Net :: IMAP :: ResponseText表示响应的文本。文本可能以响应代码为前缀。

resp_text       ::= ["[" resp_text_code "]" SPACE] (text_mime2 / text)
                    ;; text SHOULD NOT begin with "[" or "="

Fields:

code

返回响应代码。请参阅((<Net :: IMAP :: ResponseCode>))。

text

返回文本。

SEEN

表示消息的标志已被看到。

StatusData

Net :: IMAP :: StatusData表示STATUS响应的内容。

Fields:

mailbox

返回邮箱名称。

attr

返回一个散列。每个密钥都是“消息”,“最近”,“下一个”,“无效”,“未使用”之一。每个值都是一个数字。

TaggedResponse

Net :: IMAP :: TaggedResponse表示标记的响应。

服务器完成结果响应指示操作的成功或失败。它使用与开始操作的客户端命令相同的标记进行标记。

response_tagged ::= tag SPACE resp_cond_state CRLF

tag             ::= 1*<any ATOM_CHAR except "+">

resp_cond_state ::= ("OK" / "NO" / "BAD") SPACE resp_text

Fields:

tag

返回标签。

name

返回名称,“OK”,“NO”或“BAD”之一。

data

返回数据。请参阅((<Net :: IMAP :: ResponseText>))。

raw_data

返回原始数据字符串。

ThreadMember

Net :: IMAP :: ThreadMember表示由#thread返回的线程节点。

Fields:

seqno

此消息的序列号。

children

用于邮件项目的Net :: IMAP :: ThreadMember对象的数组,它们是线程中的子项。

UNMARKED

指示邮箱不包含新邮件的标志。

UntaggedResponse

Net :: IMAP :: UntaggedResponse表示无标记的响应。

由服务器传输到客户端的数据以及不表示命令完成的状态响应以标记“*”作为前缀,并称为未标记的响应。

response_data   ::= "*" SPACE (resp_cond_state / resp_cond_bye /
                    mailbox_data / message_data / capability_data)

Fields:

name

返回名称,例如“FLAGS”,“LIST”或“FETCH”。

data

返回数据,如标志符号数组,一个((<Net :: IMAP :: MailboxList>))对象。

raw_data

返回原始数据字符串。

属性

client_threadRW

接收异常的线程。

greetingR

返回来自服务器的初始问候响应。

response_handlersR

返回所有响应处理程序。

responsesR

返回未标记的响应。例如:

imap.select("inbox")
p imap.responses["EXISTS"][-1]
#=> 2
p imap.responses["UIDVALIDITY"][-1]
#=> 968263756

公共类方法

add_authenticator(auth_type,authenticator)显示源文件

为#authenticate添加一个验证器。auth_type是此验证器支持的验证类型(例如“LOGIN”)。该authenticator对象定义了一个process()方法来处理与服务器的身份验证。有关示例,请参阅Net :: IMAP :: LoginAuthenticator,Net :: IMAP :: CramMD5Authenticator和Net :: IMAP :: DigestMD5Authenticator。

如果auth_type引用现有的身份验证器,它将被新的替换。

# File lib/net/imap.rb, line 294
def self.add_authenticator(auth_type, authenticator)
  @@authenticators[auth_type] = authenticator
end

debug() Show source

返回调试模式。

# File lib/net/imap.rb, line 264
def self.debug
  return @@debug
end

debug=(val) Show source

设置调试模式。

# File lib/net/imap.rb, line 269
def self.debug=(val)
  return @@debug = val
end

decode_utf7(s) Show source

将字符串从修改的UTF-7格式解码为UTF-8。

UTF-7是Unicode UTF7的7位编码。IMAP使用稍微修改后的版本来编码包含非ASCII字符的邮箱名称; 请参阅IMAP第5.1.3节。

网:: IMAP并不会自动编码和邮箱名称和UTF-7进行解码。

# File lib/net/imap.rb, line 991
def self.decode_utf7(s)
  return s.gsub(/&([^-]+)?-/n) {
    if $1
      ($1.tr(",", "/") + "===").unpack("m")[0].encode(Encoding::UTF_8, Encoding::UTF_16BE)
    else
      "&"
    end
  }
end

default_imap_port()

别名为:default_port

default_imaps_port()

别名为:default_tls_port

default_port() Show source

IMAP连接的默认端口,端口143

# File lib/net/imap.rb, line 299
def self.default_port
  return PORT
end

另外别名为:default_imap_port

default_ssl_port()

别名为:default_tls_port

default_tls_port() Show source

IMAPS连接的默认端口,端口993

# File lib/net/imap.rb, line 304
def self.default_tls_port
  return SSL_PORT
end

另外别名为:default_imaps_port,default_ssl_port

encode_utf7(s) Show source

将UTF-8格式的字符串编码为修改后的UTF-7。

# File lib/net/imap.rb, line 1002
def self.encode_utf7(s)
  return s.gsub(/(&)|[^\x20-\x7e]+/) {
    if $1
      "&-"
    else
      base64 = [$&.encode(Encoding::UTF_16BE)].pack("m0")
      "&" + base64.delete("=").tr("/", ",") + "-"
    end
  }.force_encoding("ASCII-8BIT")
end

format_date(time) Show source

格式化time为IMAP风格的日期。

# File lib/net/imap.rb, line 1014
def self.format_date(time)
  return time.strftime('%d-%b-%Y')
end

format_datetime(time) Show source

格式化time为IMAP风格的日期时间。

# File lib/net/imap.rb, line 1019
def self.format_datetime(time)
  return time.strftime('%d-%b-%Y %H:%M %z')
end

max_flag_count() Show source

返回实现为符号的最大标志数。

# File lib/net/imap.rb, line 274
def self.max_flag_count
  return @@max_flag_count
end

max_flag_count=(count) Show source

将实际标记的最大数量设置为符号。

# File lib/net/imap.rb, line 279
def self.max_flag_count=(count)
  @@max_flag_count = count
end

Net::IMAP.new(host, options = {}) Show source

创建一个新的Net :: IMAP对象并将其连接到指定的对象host

options 是一个选项散列,其中的每个键都是一个符号。

可用的选项是:

port

端口号(imap的缺省值是143,imaps的缺省值是993)

ssl

如果选项为真,那么将尝试使用SSL(现在称为TLS)连接到服务器。为此,需要安装OpenSSL OSSL和Ruby OpenSSL RSSL扩展。如果options是一个散列,它将作为参数传递给OpenSSL :: SSL :: SSLContext#set_params。

最常见的错误是:

Errno::ECONNREFUSED

连接拒绝host或介入防火墙。

Errno::ETIMEDOUT

连接超时(可能是由于数据包被干扰防火墙丢弃)。

Errno::ENETUNREACH

没有通往该网络的路线。

SocketError

主机名未知或其他套接字错误。

Net::IMAP::ByeResponseError

连接到主机是成功的,但它立即说再见。

调用超类方法MonitorMixin.new

# File lib/net/imap.rb, line 1061
def initialize(host, port_or_options = {},
               usessl = false, certs = nil, verify = true)
  super()
  @host = host
  begin
    options = port_or_options.to_hash
  rescue NoMethodError
    # for backward compatibility
    options = {}
    options[:port] = port_or_options
    if usessl
      options[:ssl] = create_ssl_params(certs, verify)
    end
  end
  @port = options[:port] || (options[:ssl] ? SSL_PORT : PORT)
  @tag_prefix = "RUBY"
  @tagno = 0
  @parser = ResponseParser.new
  @sock = TCPSocket.open(@host, @port)
  begin
    if options[:ssl]
      start_tls_session(options[:ssl])
      @usessl = true
    else
      @usessl = false
    end
    @responses = Hash.new([].freeze)
    @tagged_responses = {}
    @response_handlers = []
    @tagged_response_arrival = new_cond
    @continuation_request_arrival = new_cond
    @idle_done_cond = nil
    @logout_command_tag = nil
    @debug_output_bol = true
    @exception = nil

    @greeting = get_response
    if @greeting.nil?
      raise Error, "connection closed"
    end
    if @greeting.name == "BYE"
      raise ByeResponseError, @greeting
    end

    @client_thread = Thread.current
    @receiver_thread = Thread.start {
      begin
        receive_responses
      rescue Exception
      end
    }
    @receiver_thread_terminating = false
  rescue Exception
    @sock.close
    raise
  end
end

公共实例方法

add_response_handler(handler = Proc.new) Show source

添加一个响应处理程序。例如,要检测服务器何时发送新的EXISTS响应(通常表示将新邮件添加到邮箱中),请在选择邮箱后添加以下处理程序:

imap.add_response_handler { |resp|
  if resp.kind_of?(Net::IMAP::UntaggedResponse) and resp.name == "EXISTS"
    puts "Mailbox now has #{resp.data} messages"
  end
}
# File lib/net/imap.rb, line 898
def add_response_handler(handler = Proc.new)
  @response_handlers.push(handler)
end

append(mailbox, message, flags = nil, date_time = nil) Show source

发送一个APPEND命令来追加message到。的末尾mailbox。可选flags参数是最初传递给新消息的标志数组。可选date_time参数指定分配给新消息的创建时间; 它默认为当前时间。例如:

imap.append("inbox", "Subject: hello
From: shugo@ruby-lang.org
To: shugo@ruby-lang.org

hello world
".gsub(/\n/, "\r\n"), [:Seen], Time.now)

如果邮箱不存在(它不会自动创建),或者如果flags,date_time或message参数包含错误,则会引发Net :: IMAP :: NoResponseError。

# File lib/net/imap.rb, line 691
def append(mailbox, message, flags = nil, date_time = nil)
  args = []
  if flags
    args.push(flags)
  end
  args.push(date_time) if date_time
  args.push(Literal.new(message))
  send_command("APPEND", mailbox, *args)
end

authenticate(auth_type, *args) Show source

发送一个AUTHENTICATE命令来认证客户端。该auth_type参数是一个表示要使用的认证机制的字符串。目前Net :: IMAP支持认证机制:

LOGIN:: login using cleartext user and password.
CRAM-MD5:: login with cleartext user and encrypted password
           (see [RFC-2195] for a full description).  This
           mechanism requires that the server have the user's
           password stored in clear-text password.

对于这两种机制,应该有两个args:用户名和(明文)密码。服务器可能不支持这些机制中的一种或另一种; 检查能力()的形式为“AUTH = LOGIN”或“AUTH = CRAM-MD5”的能力。

身份验证使用适当的身份验证器对象完成:有关插入自己的身份验证器的更多信息,请参阅@@ authenticators。

例如:

imap.authenticate('LOGIN', user, password)

如果身份验证失败,则会引发Net :: IMAP :: NoResponseError。

# File lib/net/imap.rb, line 409
def authenticate(auth_type, *args)
  auth_type = auth_type.upcase
  unless @@authenticators.has_key?(auth_type)
    raise ArgumentError,
      format('unknown auth type - "%s"', auth_type)
  end
  authenticator = @@authenticators[auth_type].new(*args)
  send_command("AUTHENTICATE", auth_type) do |resp|
    if resp.instance_of?(ContinuationRequest)
      data = authenticator.process(resp.data.text.unpack("m")[0])
      s = [data].pack("m0")
      send_string_data(s)
      put_string(CRLF)
    end
  end
end

capability() Show source

发送CAPABILITY命令,并返回服务器支持的一组功能。每个功能都是一个字符串。请参阅IMAP以获取可能的功能列表。

请注意,Net :: IMAP类不会根据服务器的功能修改其行为; 在使用服务器之前,要确保服务器支持某种功能,这取决于该类的用户。

# File lib/net/imap.rb, line 351
def capability
  synchronize do
    send_command("CAPABILITY")
    return @responses.delete("CAPABILITY")[-1]
  end
end

check() Show source

发送CHECK命令以请求当前所选邮箱的检查点。这将执行特定于实施的内务管理; 例如,协调邮箱的内存和磁盘状态。

# File lib/net/imap.rb, line 705
def check
  send_command("CHECK")
end

close() Show source

发送CLOSE命令关闭当前选定的邮箱。CLOSE命令将从邮箱中永久删除所有设置了“已删除”标志的邮件。

# File lib/net/imap.rb, line 712
def close
  send_command("CLOSE")
end

copy(set, mailbox) Show source

发送COPY命令将指定的消息复制到指定目标的末尾mailbox。该set参数是一个数字,一个数字数组或一个Range对象。该号码是消息序号。

# File lib/net/imap.rb, line 845
def copy(set, mailbox)
  copy_internal("COPY", set, mailbox)
end

create(mailbox) Show source

发送一个CREATE命令来创建一个新的mailbox

如果无法创建具有该名称的邮箱,则会引发Net :: IMAP :: NoResponseError。

# File lib/net/imap.rb, line 472
def create(mailbox)
  send_command("CREATE", mailbox)
end

delete(mailbox) Show source

发送DELETE命令以删除mailbox

如果具有该名称的邮箱无法删除,或者因为它不存在或者因为客户端没有删除它的权限,则会引发Net :: IMAP :: NoResponseError。

# File lib/net/imap.rb, line 481
def delete(mailbox)
  send_command("DELETE", mailbox)
end

disconnect() Show source

断开与服务器的连接。

# File lib/net/imap.rb, line 315
def disconnect
  begin
    begin
      # try to call SSL::SSLSocket#io.
      @sock.io.shutdown
    rescue NoMethodError
      # @sock is not an SSL::SSLSocket.
      @sock.shutdown
    end
  rescue Errno::ENOTCONN
    # ignore `Errno::ENOTCONN: Socket is not connected' on some platforms.
  rescue Exception => e
    @receiver_thread.raise(e)
  end
  @receiver_thread.join
  synchronize do
    @sock.close
  end
  raise e if e
end

disconnected?() Show source

如果与服务器断开连接,则返回true。

# File lib/net/imap.rb, line 337
def disconnected?
  return @sock.closed?
end

examine(mailbox) Show source

发送一个EXAMINE命令来选择一个,mailbox以便mailbox可以访问该消息。与select()的行为相同,只是所选内容mailbox被标识为只读。

如果邮箱不存在或出于某种原因不可检查,则会引发Net :: IMAP :: NoResponseError。

# File lib/net/imap.rb, line 461
def examine(mailbox)
  synchronize do
    @responses.clear
    send_command("EXAMINE", mailbox)
  end
end

expunge() Show source

发送EXPUNGE命令,从当前选定的邮箱中永久删除所有设置了“已删除”标志的邮件。

# File lib/net/imap.rb, line 718
def expunge
  synchronize do
    send_command("EXPUNGE")
    return @responses.delete("EXPUNGE")
  end
end

fetch(set, attr) Show source

发送FETCH命令以检索与邮箱中的邮件相关的数据。

set参数是两个数字之间的数字或范围,或者是这些数字的数组。该数字是一个消息序列号,其中-1表示用于范围表示法(如100 ..- 1)的'*'被解释为'100:*'。请注意,根据exclude_end?协议规范,Range对象的属性将被忽略,并且范围的内容与范围端点的顺序无关,因此1 ... 5,5..1和5 ... 1全部等于1 ..5。

attr是要提取的属性列表; 有关有效属性的列表,请参阅Net :: IMAP :: FetchData的文档。

如果没有匹配的消息,则返回值是一个Net :: IMAP :: FetchData或nil(而不是空数组)的数组。

例如:

p imap.fetch(6..8, "UID")
#=> [#<Net::IMAP::FetchData seqno=6, attr={"UID"=>98}>, \\
     #<Net::IMAP::FetchData seqno=7, attr={"UID"=>99}>, \\
     #<Net::IMAP::FetchData seqno=8, attr={"UID"=>100}>]
p imap.fetch(6, "BODY[HEADER.FIELDS (SUBJECT)]")
#=> [#<Net::IMAP::FetchData seqno=6, attr={"BODY[HEADER.FIELDS (SUBJECT)]"=>"Subject: test\r\n\r\n"}>]
data = imap.uid_fetch(98, ["RFC822.SIZE", "INTERNALDATE"])[0]
p data.seqno
#=> 6
p data.attr["RFC822.SIZE"]
#=> 611
p data.attr["INTERNALDATE"]
#=> "12-Oct-2000 22:40:59 +0900"
p data.attr["UID"]
#=> 98
# File lib/net/imap.rb, line 809
def fetch(set, attr)
  return fetch_internal("FETCH", set, attr)
end

getacl(mailbox) Show source

发送GETACL命令以及指定的mailbox。如果此邮箱存在,则会返回一个包含Net :: IMAP :: MailboxACLItem对象的数组。

# File lib/net/imap.rb, line 631
def getacl(mailbox)
  synchronize do
    send_command("GETACL", mailbox)
    return @responses.delete("ACL")[-1]
  end
end

getquota(mailbox) Show source

与指定一起发送GETQUOTA命令mailbox。如果此邮箱存在,则返回包含Net :: IMAP :: MailboxQuota对象的数组。此命令通常仅适用于服务器管理员。

# File lib/net/imap.rb, line 595
def getquota(mailbox)
  synchronize do
    send_command("GETQUOTA", mailbox)
    return @responses.delete("QUOTA")
  end
end

getquotaroot(mailbox) Show source

发送GETQUOTAROOT命令以及指定的命令mailbox。该命令通常对管理员和用户都可用。如果此邮箱存在,它将返回一个包含Net :: IMAP :: MailboxQuotaRoot和Net :: IMAP :: MailboxQuota类型对象的数组。

# File lib/net/imap.rb, line 581
def getquotaroot(mailbox)
  synchronize do
    send_command("GETQUOTAROOT", mailbox)
    result = []
    result.concat(@responses.delete("QUOTAROOT"))
    result.concat(@responses.delete("QUOTA"))
    return result
  end
end

idle(timeout = nil, &response_handler) Show source

发送IDLE命令,等待新消息或已删除消息的通知。在IDLE期间从服务器收到响应。

Use idle_done() to leave IDLE.

如果timeout给出,则此方法在timeout秒过后返回。timeout可以用于保持活力。例如,以下代码每60秒检查一次连接。

loop do
  imap.idle(60) do |res|
    ...
  end
end
# File lib/net/imap.rb, line 944
def idle(timeout = nil, &response_handler)
  raise LocalJumpError, "no block given" unless response_handler

  response = nil

  synchronize do
    tag = Thread.current[:net_imap_tag] = generate_tag
    put_string("#{tag} IDLE#{CRLF}")

    begin
      add_response_handler(response_handler)
      @idle_done_cond = new_cond
      @idle_done_cond.wait(timeout)
      @idle_done_cond = nil
      if @receiver_thread_terminating
        raise Net::IMAP::Error, "connection closed"
      end
    ensure
      unless @receiver_thread_terminating
        remove_response_handler(response_handler)
        put_string("DONE#{CRLF}")
        response = get_tagged_response(tag, "IDLE")
      end
    end
  end

  return response
end

idle_done() Show source

留下 IDLE.

# File lib/net/imap.rb, line 974
def idle_done
  synchronize do
    if @idle_done_cond.nil?
      raise Net::IMAP::Error, "not during IDLE"
    end
    @idle_done_cond.signal
  end
end

list(refname, mailbox) Show source

发送LIST命令,并从客户端可用的全部名称集中返回名称的子集。refname提供上下文(例如,基于目录的邮箱层次结构中的基本目录)。mailbox在该上下文中指定邮箱或(通过通配符)邮箱。两个通配符可用于mailbox:'*',它匹配包括层次结构定界符在内的所有字符(例如,在UNIX托管的基于目录的邮箱层次结构上的'/'); 和'%',它匹配层次分隔符的所有字符。

如果refname为空,mailbox则直接用于确定要匹配哪些邮箱。如果mailbox为空,refname则返回根名称和层次分隔符。

返回值是一个数组Net::IMAP::MailboxList。例如:

imap.create("foo/bar")
imap.create("foo/baz")
p imap.list("", "foo/%")
#=> [#<Net::IMAP::MailboxList attr=[:Noselect], delim="/", name="foo/">, \\
     #<Net::IMAP::MailboxList attr=[:Noinferiors, :Marked], delim="/", name="foo/bar">, \\
     #<Net::IMAP::MailboxList attr=[:Noinferiors], delim="/", name="foo/baz">]
# File lib/net/imap.rb, line 538
def list(refname, mailbox)
  synchronize do
    send_command("LIST", refname, mailbox)
    return @responses.delete("LIST")
  end
end

登录(用户,密码)显示源

Sends a LOGIN command to identify the client and carries the plaintext password authenticating this user. Note that, unlike calling authenticate() with an auth_type of “LOGIN”, login() does not use the login authenticator.

如果身份验证失败,则会引发Net :: IMAP :: NoResponseError。

# File lib/net/imap.rb, line 432
def login(user, password)
  send_command("LOGIN", user, password)
end

注销()显示源

发送LOGOUT命令以通知服务器客户端已完成连接。

# File lib/net/imap.rb, line 365
def logout
  send_command("LOGOUT")
end

lsub(refname,mailbox)显示源文件

发送LSUB命令,并返回用户声明为“活动”或“订阅”的一组名称中的名称子集,refname并将mailbox其解释为list()。返回值是一个数组Net::IMAP::MailboxList

# File lib/net/imap.rb, line 643
def lsub(refname, mailbox)
  synchronize do
    send_command("LSUB", refname, mailbox)
    return @responses.delete("LSUB")
  end
end

移动(设置,邮箱)显示源

发送MOVE命令将指定的消息移动到指定目标的末尾mailbox。该set参数是一个数字,一个数字数组或一个Range对象。该号码是消息序号。RFC-6851中描述了IMAP MOVE扩展。

# File lib/net/imap.rb, line 859
def move(set, mailbox)
  copy_internal("MOVE", set, mailbox)
end

noop()显示源代码

向服务器发送NOOP命令。它什么也没做。

# File lib/net/imap.rb, line 359
def noop
  send_command("NOOP")
end

remove_response_handler(处理程序)显示源

删除响应处理程序。

# File lib/net/imap.rb, line 903
def remove_response_handler(handler)
  @response_handlers.delete(handler)
end

重命名(邮箱,新名称)显示源

发送重命名命令来改变名称mailboxnewname

如果具有名称的邮箱因任何原因mailbox无法重命名,则会引发Net :: IMAP :: NoResponseError newname; 例如,因为mailbox不存在,或者因为已经有一个名称为邮箱newname

# File lib/net/imap.rb, line 492
def rename(mailbox, newname)
  send_command("RENAME", mailbox, newname)
end

搜索(键,字符集=零)显示源

发送 SEARCH 命令在邮箱中搜索符合给定搜索条件的邮件,并返回邮件序列号。keys可以是保存整个搜索字符串的字符串,也可以是搜索关键字和参数的单维数组。以下是一些常见的搜索标准; 有关完整列表,请参阅IMAP第6.4.4节。

<message set>

一组消息序列号。','表示间隔,':'表示范围。例如,'2,10:12,15'表示“2,10,11,12,15”。

BEFORE <date>

严格在<date>之前包含内部日期的消息。日期参数的格式类似于2002年8月8日。

BODY <string>

在其正文中包含<string>的消息。

CC <string>

在CC字段中包含<string>的消息。

FROM <string>

在其FROM字段中包含<string>的消息。

NEW

消息与最近,但不是看到,标志设置。

NOT <search-key>

否定以下搜索键。

OR <search-key> <search-key>

“或”两个搜索键在一起。

ON <date>

内部日期完全等于<date>的消息,其格式类似于2002年8月8日。

SINCE <date>

内部日期在<日期>之后或之后的消息。

SUBJECT <string>

在主题中包含<string>的消息。

TO <string>

带有<string>的消息在其TO域中。

例如:

p imap.search(["SUBJECT", "hello", "NOT", "NEW"])
#=> [1, 6, 7, 8]
# File lib/net/imap.rb, line 765
def search(keys, charset = nil)
  return search_internal("SEARCH", keys, charset)
end

选择(邮箱)显示源

发送一个SELECT命令来选择一个,mailbox以便mailbox可以访问该消息。

选择邮箱后,您可以从@response-1中检索该邮箱中的邮件数量,并从@response-1中检索最近邮件的数量。请注意,如果在会话期间新消息到达,这些值可能会更改; 有关检测此事件的方法,请参阅add_response_handler()。

如果邮箱不存在或出于某种原因不可选,则会引发Net :: IMAP :: NoResponseError。

# File lib/net/imap.rb, line 448
def select(mailbox)
  synchronize do
    @responses.clear
    send_command("SELECT", mailbox)
  end
end

setacl(邮箱,用户,权限)显示源

发送SETACL命令mailboxuser并且该rights用户将在该邮箱中拥有该命令。如果rights为零,则该用户将被剥夺该邮箱的任何权利。IMAP ACL命令在RFC-2086中进行了描述。

# File lib/net/imap.rb, line 620
def setacl(mailbox, user, rights)
  if rights.nil?
    send_command("SETACL", mailbox, user, "")
  else
    send_command("SETACL", mailbox, user, rights)
  end
end

setquota(邮箱,配额)显示源

发送SETQUOTA命令以及指定的mailboxquota。如果quota是零,那么quota将取消设置该邮箱。通常需要以服务器管理员身份登录才能正常工作。RFC-2087中描述了IMAP配额命令。

# File lib/net/imap.rb, line 607
def setquota(mailbox, quota)
  if quota.nil?
    data = '()'
  else
    data = '(STORAGE ' + quota.to_s + ')'
  end
  send_command("SETQUOTA", mailbox, RawData.new(data))
end

排序(sort_keys,search_keys,charset)显示源文件

发送一个SORT命令对邮箱中的邮件进行分类。返回一组消息序列号。例如:

p imap.sort(["FROM"], ["ALL"], "US-ASCII")
#=> [1, 2, 3, 5, 6, 7, 8, 4, 9]
p imap.sort(["DATE"], ["SUBJECT", "hello"], "US-ASCII")
#=> [6, 7, 8, 1]

有关更多详细信息,请参见SORT-THREAD-EXT。

# File lib/net/imap.rb, line 877
def sort(sort_keys, search_keys, charset)
  return sort_internal("SORT", sort_keys, search_keys, charset)
end

starttls(options = {},verify = true)显示源文件

发送STARTTLS命令以启动TLS会话。

# File lib/net/imap.rb, line 370
def starttls(options = {}, verify = true)
  send_command("STARTTLS") do |resp|
    if resp.kind_of?(TaggedResponse) && resp.name == "OK"
      begin
        # for backward compatibility
        certs = options.to_str
        options = create_ssl_params(certs, verify)
      rescue NoMethodError
      end
      start_tls_session(options)
    end
  end
end

status(mailbox, attr) Show source

发送一个STATUS命令,并返回指示的状态mailboxattr是其状态将被请求的一个或多个属性的列表。支持的属性包括:

MESSAGES:: the number of messages in the mailbox.
RECENT:: the number of recent messages in the mailbox.
UNSEEN:: the number of unseen messages in the mailbox.

返回值是属性的散列值。例如:

p imap.status("inbox", ["MESSAGES", "RECENT"])
#=> {"RECENT"=>0, "MESSAGES"=>44}

如果mailbox无法返回状态值,则会引发Net :: IMAP :: NoResponseError ; 例如,因为它不存在。

# File lib/net/imap.rb, line 666
def status(mailbox, attr)
  synchronize do
    send_command("STATUS", mailbox, attr)
    return @responses.delete("STATUS")[-1].attr
  end
end

存储(set,attr,flags)显示源文件

发送STORE命令来更改与邮箱中的邮件相关的数据,特别是其标志。该set参数是一个数字,一个数字数组或一个Range对象。每个号码都是一个消息序号。attr是要存储的数据项目的名称:'FLAGS'将用提供的标记替换消息的标记列表,'+ FLAGS'将添加提供的标记,'-FLAGS'将删除它们。flags是一个标志列表。

返回值是Net :: IMAP :: FetchData的数组。例如:

p imap.store(6..8, "+FLAGS", [:Deleted])
#=> [#<Net::IMAP::FetchData seqno=6, attr={"FLAGS"=>[:Seen, :Deleted]}>, \\
     #<Net::IMAP::FetchData seqno=7, attr={"FLAGS"=>[:Seen, :Deleted]}>, \\
     #<Net::IMAP::FetchData seqno=8, attr={"FLAGS"=>[:Seen, :Deleted]}>]
# File lib/net/imap.rb, line 832
def store(set, attr, flags)
  return store_internal("STORE", set, attr, flags)
end

subscribe(mailbox) Show source

发送SUBSCRIBE命令,将指定的mailbox名称添加到由lsub()返回的服务器的“活动”或“订阅”邮箱集。

如果mailbox无法订阅,则会引发Net :: IMAP :: NoResponseError ; 例如,因为它不存在。

# File lib/net/imap.rb, line 502
def subscribe(mailbox)
  send_command("SUBSCRIBE", mailbox)
end

线程(算法,search_keys,字符集)显示源文件

与search()类似,但以线程格式返回消息序列号,作为Net :: IMAP :: ThreadMember树。支持的算法是:

ORDEREDSUBJECT

根据主题分为单层线程,按日期排序。

REFERENCES

根据哪个消息是对其的回复确定的父/子关系拆分为线程。

与search()不同,它charset是一个必需的参数。US-ASCII和UTF-8是样本值。

有关更多详细信息,请参见SORT-THREAD-EXT。

# File lib/net/imap.rb, line 920
def thread(algorithm, search_keys, charset)
  return thread_internal("THREAD", algorithm, search_keys, charset)
end

uid_copy(set,mailbox)显示源文件

与copy()类似,但set包含唯一标识符。

# File lib/net/imap.rb, line 850
def uid_copy(set, mailbox)
  copy_internal("UID COPY", set, mailbox)
end

uid_fetch(set, attr) Show source

与fetch()类似,但set包含唯一标识符。

# File lib/net/imap.rb, line 814
def uid_fetch(set, attr)
  return fetch_internal("UID FETCH", set, attr)
end

uid_move(set, mailbox) Show source

与move()类似,但set包含唯一标识符。

# File lib/net/imap.rb, line 864
def uid_move(set, mailbox)
  copy_internal("UID MOVE", set, mailbox)
end

uid_search(keys, charset = nil) Show source

与搜索()类似,但返回唯一标识符。

# File lib/net/imap.rb, line 770
def uid_search(keys, charset = nil)
  return search_internal("UID SEARCH", keys, charset)
end

uid_sort(sort_keys, search_keys, charset) Show source

与sort()类似,但返回一个唯一标识符数组。

# File lib/net/imap.rb, line 882
def uid_sort(sort_keys, search_keys, charset)
  return sort_internal("UID SORT", sort_keys, search_keys, charset)
end

uid_store(set, attr, flags) Show source

与store()类似,但set包含唯一标识符。

# File lib/net/imap.rb, line 837
def uid_store(set, attr, flags)
  return store_internal("UID STORE", set, attr, flags)
end

uid_thread(algorithm, search_keys, charset) Show source

与thread()类似,但返回唯一标识符而不是消息序列号。

# File lib/net/imap.rb, line 926
def uid_thread(algorithm, search_keys, charset)
  return thread_internal("UID THREAD", algorithm, search_keys, charset)
end

unsubscribe(mailbox) Show source

发送UNSUBSCRIBE命令以mailbox从服务器的“活动”或“订阅”邮箱组中删除指定的名称。

如果mailbox无法取消订阅,则会引发Net :: IMAP :: NoResponseError ; 例如,因为客户当前没有订阅它。

# File lib/net/imap.rb, line 512
def unsubscribe(mailbox)
  send_command("UNSUBSCRIBE", mailbox)
end

xlist(refname, mailbox) Show source

发送XLIST命令,并从客户端可用的全部名称集中返回一个名称的子集。refname提供上下文(例如,基于目录的邮箱层次结构中的基本目录)。mailbox在该上下文中指定邮箱或(通过通配符)邮箱。两个通配符可用于mailbox:'*',它匹配包括层次结构定界符在内的所有字符(例如,在UNIX托管的基于目录的邮箱层次结构上的'/'); 和'%',它匹配层次分隔符的所有字符。

如果refname为空,mailbox则直接用于确定要匹配哪些邮箱。如果mailbox为空,refname则返回根名称和层次分隔符。

XLIST命令与LIST命令相似,只不过返回的标志引用了文件夹/邮箱的功能,例如:已发送

返回值是一个数组Net::IMAP::MailboxList。例如:

imap.create("foo/bar")
imap.create("foo/baz")
p imap.xlist("", "foo/%")
#=> [#<Net::IMAP::MailboxList attr=[:Noselect], delim="/", name="foo/">, \\
     #<Net::IMAP::MailboxList attr=[:Noinferiors, :Marked], delim="/", name="foo/bar">, \\
     #<Net::IMAP::MailboxList attr=[:Noinferiors], delim="/", name="foo/baz">]
# File lib/net/imap.rb, line 570
def xlist(refname, mailbox)
  synchronize do
    send_command("XLIST", refname, mailbox)
    return @responses.delete("XLIST")
  end
end

私有实例方法

copy_internal(cmd, set, mailbox) Show source

# File lib/net/imap.rb, line 1414
def copy_internal(cmd, set, mailbox)
  send_command(cmd, MessageSet.new(set), mailbox)
end

create_ssl_params(certs = nil, verify = true) Show source

# File lib/net/imap.rb, line 1453
def create_ssl_params(certs = nil, verify = true)
  params = {}
  if certs
    if File.file?(certs)
      params[:ca_file] = certs
    elsif File.directory?(certs)
      params[:ca_path] = certs
    end
  end
  if verify
    params[:verify_mode] = VERIFY_PEER
  else
    params[:verify_mode] = VERIFY_NONE
  end
  return params
end

fetch_internal(cmd, set, attr) Show source

# File lib/net/imap.rb, line 1386
def fetch_internal(cmd, set, attr)
  case attr
  when String then
    attr = RawData.new(attr)
  when Array then
    attr = attr.map { |arg|
      arg.is_a?(String) ? RawData.new(arg) : arg
    }
  end

  synchronize do
    @responses.delete("FETCH")
    send_command(cmd, MessageSet.new(set), attr)
    return @responses.delete("FETCH")
  end
end

generate_tag() Show source

# File lib/net/imap.rb, line 1256
def generate_tag
  @tagno += 1
  return format("%s%04d", @tag_prefix, @tagno)
end

get_response() Show source

# File lib/net/imap.rb, line 1201
def get_response
  buff = String.new
  while true
    s = @sock.gets(CRLF)
    break unless s
    buff.concat(s)
    if /\{(\d+)\}\r\n/n =~ s
      s = @sock.read($1.to_i)
      buff.concat(s)
    else
      break
    end
  end
  return nil if buff.length == 0
  if @@debug
    $stderr.print(buff.gsub(/^/n, "S: "))
  end
  return @parser.parse(buff)
end

get_tagged_response(tag, cmd) Show source

# File lib/net/imap.rb, line 1185
def get_tagged_response(tag, cmd)
  until @tagged_responses.key?(tag)
    raise @exception if @exception
    @tagged_response_arrival.wait
  end
  resp = @tagged_responses.delete(tag)
  case resp.name
  when /\A(?:NO)\z/ni
    raise NoResponseError, resp
  when /\A(?:BAD)\z/ni
    raise BadResponseError, resp
  else
    return resp
  end
end

normalize_searching_criteria(keys) Show source

# File lib/net/imap.rb, line 1442
def normalize_searching_criteria(keys)
  keys.collect! do |i|
    case i
    when -1, Range, Array
      MessageSet.new(i)
    else
      i
    end
  end
end

put_string(str) Show source

# File lib/net/imap.rb, line 1261
def put_string(str)
  @sock.print(str)
  if @@debug
    if @debug_output_bol
      $stderr.print("C: ")
    end
    $stderr.print(str.gsub(/\n(?!\z)/n, "\nC: "))
    if /\r\n\z/n.match(str)
      @debug_output_bol = true
    else
      @debug_output_bol = false
    end
  end
end

receive_responses() Show source

# File lib/net/imap.rb, line 1119
def receive_responses
  connection_closed = false
  until connection_closed
    synchronize do
      @exception = nil
    end
    begin
      resp = get_response
    rescue Exception => e
      synchronize do
        @sock.close
        @exception = e
      end
      break
    end
    unless resp
      synchronize do
        @exception = EOFError.new("end of file reached")
      end
      break
    end
    begin
      synchronize do
        case resp
        when TaggedResponse
          @tagged_responses[resp.tag] = resp
          @tagged_response_arrival.broadcast
          if resp.tag == @logout_command_tag
            return
          end
        when UntaggedResponse
          record_response(resp.name, resp.data)
          if resp.data.instance_of?(ResponseText) &&
              (code = resp.data.code)
            record_response(code.name, code.data)
          end
          if resp.name == "BYE" && @logout_command_tag.nil?
            @sock.close
            @exception = ByeResponseError.new(resp)
            connection_closed = true
          end
        when ContinuationRequest
          @continuation_request_arrival.signal
        end
        @response_handlers.each do |handler|
          handler.call(resp)
        end
      end
    rescue Exception => e
      @exception = e
      synchronize do
        @tagged_response_arrival.broadcast
        @continuation_request_arrival.broadcast
      end
    end
  end
  synchronize do
    @receiver_thread_terminating = true
    @tagged_response_arrival.broadcast
    @continuation_request_arrival.broadcast
    if @idle_done_cond
      @idle_done_cond.signal
    end
  end
end

record_response(name, data) Show source

# File lib/net/imap.rb, line 1221
def record_response(name, data)
  unless @responses.has_key?(name)
    @responses[name] = []
  end
  @responses[name].push(data)
end

search_internal(cmd, keys, charset) Show source

# File lib/net/imap.rb, line 1370
def search_internal(cmd, keys, charset)
  if keys.instance_of?(String)
    keys = [RawData.new(keys)]
  else
    normalize_searching_criteria(keys)
  end
  synchronize do
    if charset
      send_command(cmd, "CHARSET", charset, *keys)
    else
      send_command(cmd, *keys)
    end
    return @responses.delete("SEARCH")[-1]
  end
end

send_command(cmd, *args, &block) Show source

# File lib/net/imap.rb, line 1228
def send_command(cmd, *args, &block)
  synchronize do
    args.each do |i|
      validate_data(i)
    end
    tag = generate_tag
    put_string(tag + " " + cmd)
    args.each do |i|
      put_string(" ")
      send_data(i)
    end
    put_string(CRLF)
    if cmd == "LOGOUT"
      @logout_command_tag = tag
    end
    if block
      add_response_handler(block)
    end
    begin
      return get_tagged_response(tag, cmd)
    ensure
      if block
        remove_response_handler(block)
      end
    end
  end
end

send_data(data) Show source

# File lib/net/imap.rb, line 1293
def send_data(data)
  case data
  when nil
    put_string("NIL")
  when String
    send_string_data(data)
  when Integer
    send_number_data(data)
  when Array
    send_list_data(data)
  when Time
    send_time_data(data)
  when Symbol
    send_symbol_data(data)
  else
    data.send_data(self)
  end
end

send_list_data(list) Show source

# File lib/net/imap.rb, line 1342
def send_list_data(list)
  put_string("(")
  first = true
  list.each do |i|
    if first
      first = false
    else
      put_string(" ")
    end
    send_data(i)
  end
  put_string(")")
end

send_literal(str) Show source

# File lib/net/imap.rb, line 1331
def send_literal(str)
  put_string("{" + str.bytesize.to_s + "}" + CRLF)
  @continuation_request_arrival.wait
  raise @exception if @exception
  put_string(str)
end

send_number_data(num) Show source

# File lib/net/imap.rb, line 1338
def send_number_data(num)
  put_string(num.to_s)
end

send_quoted_string(str) Show source

# File lib/net/imap.rb, line 1327
def send_quoted_string(str)
  put_string('"' + str.gsub(/["\]/n, "\\\\\\&") + '"')
end

send_string_data(str) Show source

# File lib/net/imap.rb, line 1312
def send_string_data(str)
  case str
  when ""
    put_string('""')
  when /[\x80-\xff\r\n]/n
    # literal
    send_literal(str)
  when /[(){ \x00-\x1f\x7f%*"\]/n
    # quoted string
    send_quoted_string(str)
  else
    put_string(str)
  end
end

send_symbol_data(symbol) Show source

# File lib/net/imap.rb, line 1366
def send_symbol_data(symbol)
  put_string("\\" + symbol.to_s)
end

send_time_data(time) Show source

# File lib/net/imap.rb, line 1358
def send_time_data(time)
  t = time.dup.gmtime
  s = format('"%2d-%3s-%4d %02d:%02d:%02d +0000"',
             t.day, DATE_MONTH[t.month - 1], t.year,
             t.hour, t.min, t.sec)
  put_string(s)
end

sort_internal(cmd, sort_keys, search_keys, charset) Show source

# File lib/net/imap.rb, line 1418
def sort_internal(cmd, sort_keys, search_keys, charset)
  if search_keys.instance_of?(String)
    search_keys = [RawData.new(search_keys)]
  else
    normalize_searching_criteria(search_keys)
  end
  normalize_searching_criteria(search_keys)
  synchronize do
    send_command(cmd, sort_keys, charset, *search_keys)
    return @responses.delete("SORT")[-1]
  end
end

start_tls_session(params = {}) Show source

# File lib/net/imap.rb, line 1470
def start_tls_session(params = {})
  unless defined?(OpenSSL::SSL)
    raise "SSL extension not installed"
  end
  if @sock.kind_of?(OpenSSL::SSL::SSLSocket)
    raise RuntimeError, "already using SSL"
  end
  begin
    params = params.to_hash
  rescue NoMethodError
    params = {}
  end
  context = SSLContext.new
  context.set_params(params)
  if defined?(VerifyCallbackProc)
    context.verify_callback = VerifyCallbackProc
  end
  @sock = SSLSocket.new(@sock, context)
  @sock.sync_close = true
  @sock.connect
  if context.verify_mode != VERIFY_NONE
    @sock.post_connection_check(@host)
  end
end

store_internal(cmd, set, attr, flags) Show source

# File lib/net/imap.rb, line 1403
def store_internal(cmd, set, attr, flags)
  if attr.instance_of?(String)
    attr = RawData.new(attr)
  end
  synchronize do
    @responses.delete("FETCH")
    send_command(cmd, MessageSet.new(set), attr, flags)
    return @responses.delete("FETCH")
  end
end

thread_internal(cmd, algorithm, search_keys, charset) Show source

# File lib/net/imap.rb, line 1431
def thread_internal(cmd, algorithm, search_keys, charset)
  if search_keys.instance_of?(String)
    search_keys = [RawData.new(search_keys)]
  else
    normalize_searching_criteria(search_keys)
  end
  normalize_searching_criteria(search_keys)
  send_command(cmd, algorithm, charset, *search_keys)
  return @responses.delete("THREAD")[-1]
end

validate_data(data) Show source

# File lib/net/imap.rb, line 1276
def validate_data(data)
  case data
  when nil
  when String
  when Integer
    NumValidator.ensure_number(data)
  when Array
    data.each do |i|
      validate_data(i)
    end
  when Time
  when Symbol
  else
    data.validate
  end
end
Net::IMAP
Net::IMAP::BadResponseError 详细
Net::IMAP::BodyTypeAttachment 详细
Net::IMAP::BodyTypeBasic 详细
Net::IMAP::BodyTypeExtension 详细
Net::IMAP::BodyTypeMessage 详细
Net::IMAP::BodyTypeMultipart 详细
Net::IMAP::BodyTypeText 详细
Net::IMAP::ByeResponseError 详细
Net::IMAP::CramMD5Authenticator 详细
Net::IMAP::DataFormatError 详细
Net::IMAP::DigestMD5Authenticator 详细
Net::IMAP::Error 详细
Net::IMAP::FlagCountError 详细
Net::IMAP::LoginAuthenticator 详细
Net::IMAP::NoResponseError 详细
Net::IMAP::NumValidator 详细
Net::IMAP::PlainAuthenticator 详细
Net::IMAP::ResponseError 详细
Net::IMAP::ResponseParseError 详细
Ruby 2.4

Ruby 是一种面向对象、命令式、函数式、动态的通用编程语言,是世界上最优美而巧妙的语言。

主页 https://www.ruby-lang.org/
源码 https://github.com/ruby/ruby
版本 2.4
发布版本 2.4.1

Ruby 2.4目录

1.缩略 | Abbrev
2.ARGF
3.数组 | Array
4.Base64
5.基本对象 | BasicObject
6.基准测试 | Benchmark
7.BigDecimal
8.绑定 | Binding
9.CGI
10.类 | Class
11.比较 | Comparable
12.负责 | Complex
13.计算续体 | Continuation
14.覆盖 | Coverage
15.CSV
16.日期 | Date
17.日期时间 | DateTime
18.DBM
19.代理 | Delegator
20.摘要 | Digest
21.Dir
22.DRb
23.编码 | Encoding
24.枚举 | Enumerable
25.枚举 | Enumerator
26.ENV
27.ERB
28.错误 | Errors
29.Etc
30.期望值 | Exception
31.错误类 | FalseClass
32.Fiber
33.Fiddle
34.文件 | File
35.文件实用程序 | FileUtils
36.查找 | Find
37.浮点 | Float
38.Forwardable
39.GC
40.GDBM
41.GetoptLong
42.Hash
43.Integer
44.IO
45.IPAddr
46.JSON
47.Kernel
48.语言 | 3Language
49.记录 | Logger
50.编排 | Marshal
51.MatchData
52.数学 | Math
53.矩阵 | Matrix
54.方法 | Method
55.模型 | Module
56.监控 | Monitor
57. 互斥 | Mutex
58.Net
59.Net::FTP
60.Net::HTTP
61.Net::IMAP
62.Net::SMTP
63.NilClass
64.数字 | Numeric
65.对象 | Object
66.ObjectSpace
67.Observable
68.Open3
69.OpenSSL
70.OpenStruct
71.OpenURI
72.OptionParser
73.路径名 | Pathname
74.完整输出 | PrettyPrint
75.Prime
76.Proc
77.过程 | Process
78.PStore
79.PTY
80.队列 | Queue
81.随机 | Random
82.范围 | Range
83.合理的 | Rational
84.Readline
85.Regexp
86.Resolv
87.Ripper
88.RubyVM
89.Scanf
90.SDBM
91.SecureRandom
92.Set
93.Shell
94.信号 | Signal
95.Singleton
96.套接字 | Socket
97.字符串 | String
98.StringIO
99.StringScanner
100.结构 | Struct