summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgsinclair <gsinclair@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-08-31 13:04:25 +0000
committergsinclair <gsinclair@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-08-31 13:04:25 +0000
commit50ca9237b33eed8a3132833b7622f9f0fb61fc83 (patch)
tree917aa4449686393be89025eeaa85ad156084060f
parent34e218f14d1af48d9d31820f7c7f1cc5e3157391 (diff)
* lib/net/http.rb: cosmetic improvements to documentation
* lib/net/imap.rb: ditto git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4468 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--lib/net/http.rb288
-rw-r--r--lib/net/imap.rb346
2 files changed, 318 insertions, 316 deletions
diff --git a/lib/net/http.rb b/lib/net/http.rb
index 93199e09f6..38dca6a440 100644
--- a/lib/net/http.rb
+++ b/lib/net/http.rb
@@ -1,157 +1,27 @@
#
# = net/http.rb
#
-#--
# Copyright (c) 1999-2003 Yukihiro Matsumoto
# Copyright (c) 1999-2003 Minero Aoki
#
-# written & maintained by Minero Aoki <aamine@loveruby.net>.
+# Written & maintained by Minero Aoki <aamine@loveruby.net>.
+#
# This file is derived from "http-access.rb".
+#
+# Documented by Minero Aoki; converted to RDoc by William Webber.
#
# This program is free software. You can re-distribute and/or
# modify this program under the same terms of ruby itself ---
-# Ruby Distribute License or GNU General Public License.
+# Ruby Distribution License or GNU General Public License.
+#
+# See Net:::HTTP for an overview and examples.
#
# NOTE: You can find Japanese version of this document here:
-# ((<URL:http://www.ruby-lang.org/ja/man-1.6/?cmd=view;name=net%2Fhttp.rb>))
+# http://www.ruby-lang.org/ja/man-1.6/?cmd=view;name=net%2Fhttp.rb
#
+#--
# $Id$
#++
-#
-# == What Is This Library?
-#
-# This library provides your program functions to access WWW
-# documents via HTTP, Hyper Text Transfer Protocol version 1.1.
-# For details of HTTP, refer [RFC2616]
-# ((<URL:http://www.ietf.org/rfc/rfc2616.txt>)).
-#
-# == Examples
-#
-# === Getting Document From WWW Server
-#
-# (formal version)
-#
-# require 'net/http'
-# Net::HTTP.start('www.example.com', 80) {|http|
-# response = http.get('/index.html')
-# puts response.body
-# }
-#
-# (shorter version)
-#
-# require 'net/http'
-# Net::HTTP.get_print 'www.example.com', '/index.html'
-#
-# or
-#
-# require 'net/http'
-# require 'uri'
-# Net::HTTP.get_print URI.parse('http://www.example.com/index.html')
-#
-# === Posting Form Data
-#
-# require 'net/http'
-# Net::HTTP.start('some.www.server', 80) {|http|
-# response = http.post('/cgi-bin/search.rb', 'query=ruby')
-# }
-#
-# === Accessing via Proxy
-#
-# Net::HTTP.Proxy creates http proxy class. It has same
-# methods of Net::HTTP but its instances always connect to
-# proxy, instead of given host.
-#
-# require 'net/http'
-#
-# proxy_addr = 'your.proxy.host'
-# proxy_port = 8080
-# :
-# Net::HTTP::Proxy(proxy_addr, proxy_port).start('www.example.com') {|http|
-# # always connect to your.proxy.addr:8080
-# :
-# }
-#
-# Since Net::HTTP.Proxy returns Net::HTTP itself when proxy_addr is nil,
-# there's no need to change code if there's proxy or not.
-#
-# There are two additional parameters in Net::HTTP.Proxy which allow to
-# specify proxy user name and password:
-#
-# Net::HTTP::Proxy(proxy_addr, proxy_port, proxy_user = nil, proxy_pass = nil)
-#
-# You may use them to work with authorization-enabled proxies:
-#
-# require 'net/http'
-# require 'uri'
-#
-# proxy_host = 'your.proxy.host'
-# proxy_port = 8080
-# uri = URI.parse(ENV['http_proxy'])
-# proxy_user, proxy_pass = uri.userinfo.split(/:/) if uri.userinfo
-# Net::HTTP::Proxy(proxy_host, proxy_port,
-# proxy_user, proxy_pass).start('www.example.com') {|http|
-# # always connect to your.proxy.addr:8080 using specified username and password
-# :
-# }
-#
-#
-# === Following Redirection
-#
-# require 'net/http'
-# require 'uri'
-#
-# def fetch( uri_str, limit = 10 )
-# # You should choose better exception.
-# raise ArgumentError, 'http redirect too deep' if limit == 0
-#
-# response = Net::HTTP.get_response(URI.parse(uri_str))
-# case response
-# when Net::HTTPSuccess then response
-# when Net::HTTPRedirection then fetch(response['location'], limit - 1)
-# else
-# response.error!
-# end
-# end
-#
-# print fetch('http://www.ruby-lang.org')
-#
-# Net::HTTPSuccess and Net::HTTPRedirection is a HTTPResponse class.
-# All HTTPResponse objects belong to its own response class which
-# indicate HTTP result status. For details of response classes,
-# see section "HTTP Response Classes".
-#
-# === Basic Authentication
-#
-# require 'net/http'
-#
-# Net::HTTP.start('www.example.com') {|http|
-# req = Net::HTTP::Get.new('/secret-page.html')
-# req.basic_auth 'account', 'password'
-# response = http.request(req)
-# print response.body
-# }
-#
-# === HTTP Response Classes
-#
-# TODO: write me.
-#
-# == Switching Net::HTTP versions
-#
-# You can use net/http.rb 1.1 features (bundled with Ruby 1.6)
-# by calling HTTP.version_1_1. Calling Net::HTTP.version_1_2
-# allows you to use 1.2 features again.
-#
-# # example
-# Net::HTTP.start {|http1| ...(http1 has 1.2 features)... }
-#
-# Net::HTTP.version_1_1
-# Net::HTTP.start {|http2| ...(http2 has 1.1 features)... }
-#
-# Net::HTTP.version_1_2
-# Net::HTTP.start {|http3| ...(http3 has 1.2 features)... }
-#
-# This function is NOT multithread-safe.
-#
require 'net/protocol'
require 'uri'
@@ -164,11 +34,139 @@ module Net # :nodoc:
class HTTPHeaderSyntaxError < StandardError; end
# :startdoc:
+ # == What Is This Library?
+ #
+ # This library provides your program functions to access WWW
+ # documents via HTTP, Hyper Text Transfer Protocol version 1.1.
+ # For details of HTTP, refer [RFC2616]
+ # ((<URL:http://www.ietf.org/rfc/rfc2616.txt>)).
+ #
+ # == Examples
+ #
+ # === Getting Document From WWW Server
+ #
+ # (formal version)
+ #
+ # require 'net/http'
+ # Net::HTTP.start('www.example.com', 80) { |http|
+ # response = http.get('/index.html')
+ # puts response.body
+ # }
+ #
+ # (shorter version)
+ #
+ # require 'net/http'
+ # Net::HTTP.get_print 'www.example.com', '/index.html'
+ #
+ # or
+ #
+ # require 'net/http'
+ # require 'uri'
+ # Net::HTTP.get_print URI.parse('http://www.example.com/index.html')
+ #
+ # === Posting Form Data
+ #
+ # require 'net/http'
+ # Net::HTTP.start('some.www.server', 80) { |http|
+ # response = http.post('/cgi-bin/search.rb', 'query=ruby')
+ # }
+ #
+ # === Accessing via Proxy
+ #
+ # Net::HTTP.Proxy creates http proxy class. It has same
+ # methods of Net::HTTP but its instances always connect to
+ # proxy, instead of given host.
+ #
+ # require 'net/http'
+ #
+ # proxy_addr = 'your.proxy.host'
+ # proxy_port = 8080
+ # :
+ # Net::HTTP::Proxy(proxy_addr, proxy_port).start('www.example.com') {|http|
+ # # always connect to your.proxy.addr:8080
+ # :
+ # }
+ #
+ # Since Net::HTTP.Proxy returns Net::HTTP itself when proxy_addr is nil,
+ # there's no need to change code if there's proxy or not.
+ #
+ # There are two additional parameters in Net::HTTP.Proxy which allow to
+ # specify proxy user name and password:
+ #
+ # Net::HTTP::Proxy(proxy_addr, proxy_port, proxy_user = nil, proxy_pass = nil)
+ #
+ # You may use them to work with authorization-enabled proxies:
+ #
+ # require 'net/http'
+ # require 'uri'
+ #
+ # proxy_host = 'your.proxy.host'
+ # proxy_port = 8080
+ # uri = URI.parse(ENV['http_proxy'])
+ # proxy_user, proxy_pass = uri.userinfo.split(/:/) if uri.userinfo
+ # Net::HTTP::Proxy(proxy_host, proxy_port,
+ # proxy_user, proxy_pass).start('www.example.com') {|http|
+ # # always connect to your.proxy.addr:8080 using specified username and password
+ # :
+ # }
+ #
+ #
+ # === Following Redirection
+ #
+ # require 'net/http'
+ # require 'uri'
+ #
+ # def fetch( uri_str, limit = 10 )
+ # # You should choose better exception.
+ # raise ArgumentError, 'http redirect too deep' if limit == 0
+ #
+ # response = Net::HTTP.get_response(URI.parse(uri_str))
+ # case response
+ # when Net::HTTPSuccess then response
+ # when Net::HTTPRedirection then fetch(response['location'], limit - 1)
+ # else
+ # response.error!
+ # end
+ # end
+ #
+ # print fetch('http://www.ruby-lang.org')
+ #
+ # Net::HTTPSuccess and Net::HTTPRedirection is a HTTPResponse class.
+ # All HTTPResponse objects belong to its own response class which
+ # indicate HTTP result status. For details of response classes,
+ # see section "HTTP Response Classes".
+ #
+ # === Basic Authentication
+ #
+ # require 'net/http'
+ #
+ # Net::HTTP.start('www.example.com') {|http|
+ # req = Net::HTTP::Get.new('/secret-page.html')
+ # req.basic_auth 'account', 'password'
+ # response = http.request(req)
+ # print response.body
+ # }
+ #
+ # === HTTP Response Classes
#
- # Class providing both short-cut class methods for retrieving entities,
- # and instance methods for fuller HTTP functionality.
- #
- # See comment to the file http.rb for examples of usage.
+ # TODO: write me.
+ #
+ # == Switching Net::HTTP versions
+ #
+ # You can use net/http.rb 1.1 features (bundled with Ruby 1.6)
+ # by calling HTTP.version_1_1. Calling Net::HTTP.version_1_2
+ # allows you to use 1.2 features again.
+ #
+ # # example
+ # Net::HTTP.start { |http1| ...(http1 has 1.2 features)... }
+ #
+ # Net::HTTP.version_1_1
+ # Net::HTTP.start { |http2| ...(http2 has 1.1 features)... }
+ #
+ # Net::HTTP.version_1_2
+ # Net::HTTP.start { |http3| ...(http3 has 1.2 features)... }
+ #
+ # This function is NOT thread-safe.
#
class HTTP < Protocol
@@ -190,7 +188,7 @@ module Net # :nodoc:
@@newimpl = true
end
- # Turns on net/http 1.2 (ruby 1.8) features.
+ # Turns on net/http 1.1 (ruby 1.6) features.
# Defaults to OFF in ruby 1.8.
def HTTP.version_1_1
@@newimpl = false
@@ -359,7 +357,7 @@ module Net # :nodoc:
end
# *WARNING* This method causes serious security hole.
- # Never use this method in product code.
+ # Never use this method in production code.
#
# Set an output stream for debugging.
#
diff --git a/lib/net/imap.rb b/lib/net/imap.rb
index 0463665bd5..475c2ad0de 100644
--- a/lib/net/imap.rb
+++ b/lib/net/imap.rb
@@ -1,181 +1,15 @@
+#
# = net/imap.rb
#
-#--
# Copyright (C) 2000 Shugo Maeda <shugo@ruby-lang.org>
#
# This library is distributed under the terms of the Ruby license.
# You can freely distribute/modify this library.
-#++
-#
-# == IMAP OVERVIEW
-#
-# An IMAP client connects to a server, and then authenticates
-# itself using either #authenticate() or #login(). Having
-# authenticated itself, there is a range of commands
-# available to it. Most work with mailboxes, which may be
-# arranged in an hierarchical namespace, and each of which
-# contains zero or more messages. How this is implemented on
-# the server is implementation-dependent; on a UNIX server, it
-# will frequently be implemented as a files in mailbox format
-# within a hierarchy of directories.
-#
-# To work on the messages within a mailbox, the client must
-# first select that mailbox, using either #select() or (for
-# read-only access) #examine(). Once the client has successfully
-# selected a mailbox, they enter _selected_ state, and that
-# mailbox becomes the _current_ mailbox, on which mail-item
-# related commands implicitly operate.
-#
-# Messages have two sorts of identifiers: message sequence
-# numbers, and UIDs.
-#
-# Message sequence numbers number messages within a mail box
-# from 1 up to the number of items in the mail box. If new
-# message arrives during a session, it receives a sequence
-# number equal to the new size of the mail box. If messages
-# are expunged from the mailbox, remaining messages have their
-# sequence numbers "shuffled down" to fill the gaps.
-#
-# UIDs, on the other hand, are permanently guaranteed not to
-# identify another message within the same mailbox, even if
-# the existing message is deleted. UIDs are required to
-# be assigned in ascending (but not necessarily sequential)
-# order within a mailbox; this means that if a non-IMAP client
-# rearranges the order of mailitems within a mailbox, the
-# UIDs have to be reassigned. An IMAP client cannot thus
-# rearrange message orders.
-#
-# == EXAMPLES OF USAGE
-#
-# === List sender and subject of all recent messages in the default mailbox
-#
-# 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
-#
-# === Move all messages from April 2003 from "Mail/sent-mail" to "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
-#
-# == THREAD-SAFENESS
-#
-# Net::IMAP supports concurrent threads. For example,
-#
-# 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
-#
-# This script invokes the FETCH command and the SEARCH command concurrently.
-#
-# == ERRORS
-#
-# An IMAP server can send three different types of responses to indicate
-# failure:
-#
-# NO:: the attempted command could not be successfully completed. For
-# instance, the username/password used for logging in are incorrect;
-# the selected mailbox does not exists; etc.
-#
-# BAD:: the request from the client does not follow the server's
-# understanding of the IMAP protocol. This includes attempting
-# commands from the wrong client state; for instance, attempting
-# to perform a SEARCH command without having SELECTed a current
-# mailbox. It can also signal an internal server
-# failure (such as a disk crash) has occurred.
-#
-# BYE:: the server is saying goodbye. This can be part of a normal
-# logout sequence, and can be used as part of a login sequence
-# to indicate that the server is (for some reason) unwilling
-# to accept our connection. As a response to any other command,
-# it indicates either that the server is shutting down, or that
-# the server is timing out the client connection due to inactivity.
#
-# These three error response are represented by the errors
-# Net::IMAP::NoResponseError, Net::IMAP::BadResponseError, and
-# Net::IMAP::ByeResponseError, all of which are subclasses of
-# Net::IMAP::ResponseError. Essentially, all methods that involve
-# sending a request to the server can generate one of these errors.
-# Only the most pertinent instances have been documented below.
+# Documentation: Shugo Maeda, with RDoc conversion and overview by William
+# Webber.
#
-# Because the IMAP class uses Sockets for communication, its methods
-# are also susceptible to the various errors that can occur when
-# working with sockets. These are generally represented as
-# Errno errors. For instance, any method that involves sending a
-# request to the server and/or receiving a response from it could
-# raise an Errno::EPIPE error if the network connection unexpectedly
-# goes down. See the socket(7), ip(7), tcp(7), socket(2), connect(2),
-# and associated man pages.
-#
-# Finally, a Net::IMAP::DataFormatError is thrown if low-level data
-# is found to be in an incorrect format (for instance, when converting
-# between UTF-8 and UTF-16), and Net::IMAP::ResponseParseError is
-# thrown if a server response is non-parseable.
-#
-#
-# == References
-#
-# [[IMAP]]
-# M. Crispin, "INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4rev1",
-# RFC 2060, December 1996. (Note: since obsoleted by RFC 3501)
-#
-# [[LANGUAGE-TAGS]]
-# Alvestrand, H., "Tags for the Identification of
-# Languages", RFC 1766, March 1995.
-#
-# [[MD5]]
-# Myers, J., and M. Rose, "The Content-MD5 Header Field", RFC
-# 1864, October 1995.
-#
-# [[MIME-IMB]]
-# Freed, N., and N. Borenstein, "MIME (Multipurpose Internet
-# Mail Extensions) Part One: Format of Internet Message Bodies", RFC
-# 2045, November 1996.
-#
-# [[RFC-822]]
-# Crocker, D., "Standard for the Format of ARPA Internet Text
-# Messages", STD 11, RFC 822, University of Delaware, August 1982.
-#
-# [[RFC-2087]]
-# Myers, J., "IMAP4 QUOTA extension", RFC 2087, January 1997.
-#
-# [[RFC-2086]]
-# Myers, J., "IMAP4 ACL extension", RFC 2086, January 1997.
-#
-# [[RFC-2195]]
-# Klensin, J., Catoe, R., and Krumviede, P., "IMAP/POP AUTHorize Extension
-# for Simple Challenge/Response", RFC 2195, September 1997.
-#
-# [[SORT-THREAD-EXT]]
-# Crispin, M., "INTERNET MESSAGE ACCESS PROTOCOL - SORT and THREAD
-# Extensions", draft-ietf-imapext-sort, May 2003.
-#
-# [[OSSL]]
-# http://www.openssl.org
-#
-# [[RSSL]]
-# http://savannah.gnu.org/projects/rubypki
-#
-# [[UTF7]]
-# Goldsmith, D. and Davis, M., "UTF-7: A Mail-Safe Transformation Format of
-# Unicode", RFC 2152, May 1997.
+
require "socket"
require "monitor"
@@ -187,10 +21,180 @@ end
module Net # :nodoc:
+ #
# Net::IMAP implements Internet Message Access Protocol (IMAP) client
# functionality. The protocol is described in [IMAP].
#
- # See comment to the file imap.rb for examples of usage.
+ # == IMAP OVERVIEW
+ #
+ # An IMAP client connects to a server, and then authenticates
+ # itself using either #authenticate() or #login(). Having
+ # authenticated itself, there is a range of commands
+ # available to it. Most work with mailboxes, which may be
+ # arranged in an hierarchical namespace, and each of which
+ # contains zero or more messages. How this is implemented on
+ # the server is implementation-dependent; on a UNIX server, it
+ # will frequently be implemented as a files in mailbox format
+ # within a hierarchy of directories.
+ #
+ # To work on the messages within a mailbox, the client must
+ # first select that mailbox, using either #select() or (for
+ # read-only access) #examine(). Once the client has successfully
+ # selected a mailbox, they enter _selected_ state, and that
+ # mailbox becomes the _current_ mailbox, on which mail-item
+ # related commands implicitly operate.
+ #
+ # Messages have two sorts of identifiers: message sequence
+ # numbers, and UIDs.
+ #
+ # Message sequence numbers number messages within a mail box
+ # from 1 up to the number of items in the mail box. If new
+ # message arrives during a session, it receives a sequence
+ # number equal to the new size of the mail box. If messages
+ # are expunged from the mailbox, remaining messages have their
+ # sequence numbers "shuffled down" to fill the gaps.
+ #
+ # UIDs, on the other hand, are permanently guaranteed not to
+ # identify another message within the same mailbox, even if
+ # the existing message is deleted. UIDs are required to
+ # be assigned in ascending (but not necessarily sequential)
+ # order within a mailbox; this means that if a non-IMAP client
+ # rearranges the order of mailitems within a mailbox, the
+ # UIDs have to be reassigned. An IMAP client cannot thus
+ # rearrange message orders.
+ #
+ # == EXAMPLES OF USAGE
+ #
+ # === List sender and subject of all recent messages in the default mailbox
+ #
+ # 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
+ #
+ # === Move all messages from April 2003 from "Mail/sent-mail" to "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
+ #
+ # == THREAD-SAFENESS
+ #
+ # Net::IMAP supports concurrent threads. For example,
+ #
+ # 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
+ #
+ # This script invokes the FETCH command and the SEARCH command concurrently.
+ #
+ # == ERRORS
+ #
+ # An IMAP server can send three different types of responses to indicate
+ # failure:
+ #
+ # NO:: the attempted command could not be successfully completed. For
+ # instance, the username/password used for logging in are incorrect;
+ # the selected mailbox does not exists; etc.
+ #
+ # BAD:: the request from the client does not follow the server's
+ # understanding of the IMAP protocol. This includes attempting
+ # commands from the wrong client state; for instance, attempting
+ # to perform a SEARCH command without having SELECTed a current
+ # mailbox. It can also signal an internal server
+ # failure (such as a disk crash) has occurred.
+ #
+ # BYE:: the server is saying goodbye. This can be part of a normal
+ # logout sequence, and can be used as part of a login sequence
+ # to indicate that the server is (for some reason) unwilling
+ # to accept our connection. As a response to any other command,
+ # it indicates either that the server is shutting down, or that
+ # the server is timing out the client connection due to inactivity.
+ #
+ # These three error response are represented by the errors
+ # Net::IMAP::NoResponseError, Net::IMAP::BadResponseError, and
+ # Net::IMAP::ByeResponseError, all of which are subclasses of
+ # Net::IMAP::ResponseError. Essentially, all methods that involve
+ # sending a request to the server can generate one of these errors.
+ # Only the most pertinent instances have been documented below.
+ #
+ # Because the IMAP class uses Sockets for communication, its methods
+ # are also susceptible to the various errors that can occur when
+ # working with sockets. These are generally represented as
+ # Errno errors. For instance, any method that involves sending a
+ # request to the server and/or receiving a response from it could
+ # raise an Errno::EPIPE error if the network connection unexpectedly
+ # goes down. See the socket(7), ip(7), tcp(7), socket(2), connect(2),
+ # and associated man pages.
+ #
+ # Finally, a Net::IMAP::DataFormatError is thrown if low-level data
+ # is found to be in an incorrect format (for instance, when converting
+ # between UTF-8 and UTF-16), and Net::IMAP::ResponseParseError is
+ # thrown if a server response is non-parseable.
+ #
+ #
+ # == References
+ #
+ # [[IMAP]]
+ # M. Crispin, "INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4rev1",
+ # RFC 2060, December 1996. (Note: since obsoleted by RFC 3501)
+ #
+ # [[LANGUAGE-TAGS]]
+ # Alvestrand, H., "Tags for the Identification of
+ # Languages", RFC 1766, March 1995.
+ #
+ # [[MD5]]
+ # Myers, J., and M. Rose, "The Content-MD5 Header Field", RFC
+ # 1864, October 1995.
+ #
+ # [[MIME-IMB]]
+ # Freed, N., and N. Borenstein, "MIME (Multipurpose Internet
+ # Mail Extensions) Part One: Format of Internet Message Bodies", RFC
+ # 2045, November 1996.
+ #
+ # [[RFC-822]]
+ # Crocker, D., "Standard for the Format of ARPA Internet Text
+ # Messages", STD 11, RFC 822, University of Delaware, August 1982.
+ #
+ # [[RFC-2087]]
+ # Myers, J., "IMAP4 QUOTA extension", RFC 2087, January 1997.
+ #
+ # [[RFC-2086]]
+ # Myers, J., "IMAP4 ACL extension", RFC 2086, January 1997.
+ #
+ # [[RFC-2195]]
+ # Klensin, J., Catoe, R., and Krumviede, P., "IMAP/POP AUTHorize Extension
+ # for Simple Challenge/Response", RFC 2195, September 1997.
+ #
+ # [[SORT-THREAD-EXT]]
+ # Crispin, M., "INTERNET MESSAGE ACCESS PROTOCOL - SORT and THREAD
+ # Extensions", draft-ietf-imapext-sort, May 2003.
+ #
+ # [[OSSL]]
+ # http://www.openssl.org
+ #
+ # [[RSSL]]
+ # http://savannah.gnu.org/projects/rubypki
+ #
+ # [[UTF7]]
+ # Goldsmith, D. and Davis, M., "UTF-7: A Mail-Safe Transformation Format of
+ # Unicode", RFC 2152, May 1997.
+ #
class IMAP
include MonitorMixin
if defined?(OpenSSL)