diff --git a/README.md b/README.md index 7fc6d635..a8d9f7da 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ # Net::IMAP Net::IMAP implements Internet Message Access Protocol (IMAP) client -functionality. The protocol is described in [RFC3501](https://www.rfc-editor.org/rfc/rfc3501). +functionality. The protocol is described in +[RFC3501](https://www.rfc-editor.org/rfc/rfc3501), +[RFC9051](https://www.rfc-editor.org/rfc/rfc9051) and various extensions. ## Installation diff --git a/docs/styles.css b/docs/styles.css index e945aea0..1d1e27f1 100644 --- a/docs/styles.css +++ b/docs/styles.css @@ -10,18 +10,28 @@ main .method-detail { justify-content: space-between; } -main .method-header, main .method-controls { +main .method-header, +main .method-controls, +.attribute-method-heading { padding: 0.5em; /* border: 1px solid var(--highlight-color); */ background: var(--table-header-background-color); line-height: 1.6; } +.attribute-method-heading .attribute-access-type { + float: right; +} + main .method-header { border-right: none; border-radius: 4px 0 0 4px; } +main .method-heading :any-link { + text-decoration: none; +} + main .method-controls { border-left: none; border-radius: 0 4px 4px 0; diff --git a/lib/net/imap/config.rb b/lib/net/imap/config.rb index 7532737c..edeea30e 100644 --- a/lib/net/imap/config.rb +++ b/lib/net/imap/config.rb @@ -75,7 +75,7 @@ class IMAP # # client = Net::IMAP.new(hostname, config: :future) # client.config.sasl_ir # => true - # client.config.responses_without_block # => :raise + # client.config.responses_without_block # => :frozen_dup # # The versioned default configs inherit certain specific config options from # Config.global, for example #debug: @@ -109,9 +109,11 @@ class IMAP # [+:future+] # The _planned_ eventual config for some future +x.y+ version. # - # For example, to raise exceptions for all current deprecations: + # For example, to disable all currently deprecated behavior: # client = Net::IMAP.new(hostname, config: :future) - # client.responses # raises an ArgumentError + # client.config.response_without_args # => :frozen_dup + # client.responses.frozen? # => true + # client.responses.values.all?(&:frozen?) # => true # # == Thread Safety # diff --git a/lib/net/imap/fetch_data.rb b/lib/net/imap/fetch_data.rb index 3d8554b5..271063ab 100644 --- a/lib/net/imap/fetch_data.rb +++ b/lib/net/imap/fetch_data.rb @@ -103,6 +103,15 @@ class IMAP < Protocol # as BODY[#{specifier}] or BINARY[#{section}]. # class FetchStruct < Struct + ## + # method: attr + # :call-seq: attr -> hash + # + # Each key specifies a message attribute, and the value is the + # corresponding data item. Standard data items have corresponding + # accessor methods. The definitions of each attribute type is documented + # on its accessor. + # :call-seq: attr_upcase -> hash # # A transformation of #attr, with all the keys converted to upper case. diff --git a/lib/net/imap/response_data.rb b/lib/net/imap/response_data.rb index 108ff29b..16ff306c 100644 --- a/lib/net/imap/response_data.rb +++ b/lib/net/imap/response_data.rb @@ -160,13 +160,20 @@ class TaggedResponse < Struct.new(:tag, :name, :data, :raw_data) # The raw response data. end - # Net::IMAP::ResponseText represents texts of responses. + # ResponseText represents texts of responses. # # The text may be prefixed by a ResponseCode. # - # ResponseText is returned from TaggedResponse#data, or from - # UntaggedResponse#data when the response type is a "condition" ("OK", "NO", - # "BAD", "PREAUTH", or "BYE"). + # ResponseText is returned from TaggedResponse#data or + # UntaggedResponse#data for + # {"status responses"}[https://www.rfc-editor.org/rfc/rfc3501#section-7.1]: + # * every TaggedResponse, name[rdoc-ref:TaggedResponse#name] is always + # "+OK+", "+NO+", or "+BAD+". + # * any UntaggedResponse when name[rdoc-ref:UntaggedResponse#name] is + # "+OK+", "+NO+", "+BAD+", "+PREAUTH+", or "+BYE+". + # + # Note that these "status responses" are confusingly _not_ the same as the + # +STATUS+ UntaggedResponse (see IMAP#status and StatusData). class ResponseText < Struct.new(:code, :text) # Used to avoid an allocation when ResponseText is empty EMPTY = new(nil, "").freeze @@ -184,32 +191,35 @@ class ResponseText < Struct.new(:code, :text) # Returns the response text, not including any response code end - # Net::IMAP::ResponseCode represents response codes. Response codes can be - # retrieved from ResponseText#code and can be included in any "condition" - # response: any TaggedResponse and UntaggedResponse when the response type - # is a "condition" ("OK", "NO", "BAD", "PREAUTH", or "BYE"). + # ResponseCode represents an \IMAP response code, which can be retrieved + # from ResponseText#code for + # {"status responses"}[https://www.rfc-editor.org/rfc/rfc3501#section-7.1]: + # * every TaggedResponse, name[rdoc-ref:TaggedResponse#name] is always + # "+OK+", "+NO+", or "+BAD+". + # * any UntaggedResponse when name[rdoc-ref:UntaggedResponse#name] is + # "+OK+", "+NO+", "+BAD+", "+PREAUTH+", or "+BYE+". + # + # Note that these "status responses" are confusingly _not_ the same as the + # +STATUS+ UntaggedResponse (see IMAP#status and StatusData). # # Some response codes come with additional data which will be parsed by # Net::IMAP. Others return +nil+ for #data, but are used as a # machine-readable annotation for the human-readable ResponseText#text in - # the same response. When Net::IMAP does not know how to parse response - # code text, #data returns the unparsed string. + # the same response. # # Untagged response code #data is pushed directly onto Net::IMAP#responses, # keyed by #name, unless it is removed by the command that generated it. # Use Net::IMAP#add_response_handler to view tagged response codes for # command methods that do not return their TaggedResponse. # + # == Standard response codes + # # \IMAP extensions may define new codes and the data that comes with them. # The IANA {IMAP Response # Codes}[https://www.iana.org/assignments/imap-response-codes/imap-response-codes.xhtml] # registry has links to specifications for all standard response codes. - # Response codes are backwards compatible: Servers are allowed to send new - # response codes even if the client has not enabled the extension that - # defines them. When unknown response code data is encountered, #data - # will return an unparsed string. # - # ==== +IMAP4rev1+ Response Codes + # === +IMAP4rev1+ response codes # See [IMAP4rev1[https://www.rfc-editor.org/rfc/rfc3501]] {§7.1, "Server # Responses - Status # Responses"}[https://www.rfc-editor.org/rfc/rfc3501#section-7.1] for full @@ -240,24 +250,24 @@ class ResponseText < Struct.new(:code, :text) # the \Seen flag set. # DEPRECATED by IMAP4rev2. # - # ==== +BINARY+ extension + # === +BINARY+ extension # See {[RFC3516]}[https://www.rfc-editor.org/rfc/rfc3516]. # * +UNKNOWN-CTE+, with a tagged +NO+ response, when the server does not # known how to decode a CTE (content-transfer-encoding). #data is +nil+. # See IMAP#fetch. # - # ==== +UIDPLUS+ extension + # === +UIDPLUS+ extension # See {[RFC4315 §3]}[https://www.rfc-editor.org/rfc/rfc4315#section-3]. # * +APPENDUID+, #data is UIDPlusData. See IMAP#append. # * +COPYUID+, #data is UIDPlusData. See IMAP#copy. # * +UIDNOTSTICKY+, #data is +nil+. See IMAP#select. # - # ==== +SEARCHRES+ extension + # === +SEARCHRES+ extension # See {[RFC5182]}[https://www.rfc-editor.org/rfc/rfc5182]. # * +NOTSAVED+, with a tagged +NO+ response, when the search result variable # is not saved. #data is +nil+. # - # ==== +RFC5530+ Response Codes + # === +RFC5530+ response codes # See {[RFC5530]}[https://www.rfc-editor.org/rfc/rfc5530], "IMAP Response # Codes" for the definition of the following response codes, which are all # machine-readable annotations for the human-readable ResponseText#text, and @@ -280,22 +290,22 @@ class ResponseText < Struct.new(:code, :text) # * +ALREADYEXISTS+ # * +NONEXISTENT+ # - # ==== +QRESYNC+ extension + # === +QRESYNC+ extension # See {[RFC7162]}[https://www.rfc-editor.org/rfc/rfc7162.html]. # * +CLOSED+, returned when the currently selected mailbox is closed # implicitly by selecting or examining another mailbox. #data is +nil+. # - # ==== +IMAP4rev2+ Response Codes + # === +IMAP4rev2+ response codes # See {[RFC9051]}[https://www.rfc-editor.org/rfc/rfc9051] {§7.1, "Server # Responses - Status # Responses"}[https://www.rfc-editor.org/rfc/rfc9051#section-7.1] for full # descriptions of IMAP4rev2 response codes. IMAP4rev2 includes all of the - # response codes listed above (except "UNSEEN") and adds the following: + # response codes listed above (except "+UNSEEN+") and adds the following: # * +HASCHILDREN+, with a tagged +NO+ response, when a mailbox delete failed # because the server doesn't allow deletion of mailboxes with children. # #data is +nil+. # - # ==== +CONDSTORE+ extension + # === +CONDSTORE+ extension # See {[RFC7162]}[https://www.rfc-editor.org/rfc/rfc7162.html]. # * +NOMODSEQ+, when selecting a mailbox that does not support # mod-sequences. #data is +nil+. See IMAP#select. @@ -305,10 +315,17 @@ class ResponseText < Struct.new(:code, :text) # since the +UNCHANGEDSINCE+ mod-sequence given to +STORE+ or UID # STORE. # - # ==== +OBJECTID+ extension + # === +OBJECTID+ extension # See {[RFC8474]}[https://www.rfc-editor.org/rfc/rfc8474.html]. # * +MAILBOXID+, #data is a string # + # == Extension compatibility + # + # Response codes are backwards compatible: Servers are allowed to send new + # response codes even if the client has not enabled the extension that + # defines them. When Net::IMAP does not know how to parse response + # code text, #data returns the unparsed string. + # class ResponseCode < Struct.new(:name, :data) ## # method: name @@ -327,14 +344,9 @@ class ResponseCode < Struct.new(:name, :data) # code data can take. end - # Net::IMAP::UIDPlusData represents the ResponseCode#data that accompanies - # the +APPENDUID+ and +COPYUID+ response codes. - # - # See [[UIDPLUS[https://www.rfc-editor.org/rfc/rfc4315.html]]. - # - # ==== Capability requirement + # UIDPlusData represents the ResponseCode#data that accompanies the + # +APPENDUID+ and +COPYUID+ {response codes}[rdoc-ref:ResponseCode]. # - # The +UIDPLUS+ capability[rdoc-ref:Net::IMAP#capability] must be supported. # A server that supports +UIDPLUS+ should send a UIDPlusData object inside # every TaggedResponse returned by the append[rdoc-ref:Net::IMAP#append], # copy[rdoc-ref:Net::IMAP#copy], move[rdoc-ref:Net::IMAP#move], {uid @@ -342,9 +354,9 @@ class ResponseCode < Struct.new(:name, :data) # move}[rdoc-ref:Net::IMAP#uid_move] commands---unless the destination # mailbox reports +UIDNOTSTICKY+. # - #-- - # TODO: support MULTIAPPEND - #++ + # == Required capability + # Requires either +UIDPLUS+ [RFC4315[https://www.rfc-editor.org/rfc/rfc4315]] + # or +IMAP4rev2+ capability. # class UIDPlusData < Struct.new(:uidvalidity, :source_uids, :assigned_uids) ## @@ -381,10 +393,8 @@ def uid_mapping end end - # Net::IMAP::MailboxList represents contents of the LIST response, - # representing a single mailbox path. - # - # Net::IMAP#list returns an array of MailboxList objects. + # MailboxList represents the data of an untagged +LIST+ response, for a + # _single_ mailbox path. IMAP#list returns an array of MailboxList objects. # class MailboxList < Struct.new(:attr, :delim, :name) ## @@ -394,11 +404,11 @@ class MailboxList < Struct.new(:attr, :delim, :name) # Returns the name attributes. Each name attribute is a symbol capitalized # by String#capitalize, such as :Noselect (not :NoSelect). For the # semantics of each attribute, see: - # * rdoc-ref:Net::IMAP@Basic+Mailbox+Attributes - # * rdoc-ref:Net::IMAP@Mailbox+role+Attributes - # * Net::IMAP@SPECIAL-USE + # * Net::IMAP@Basic+Mailbox+Attributes + # * Net::IMAP@Mailbox+role+Attributes # * The IANA {IMAP Mailbox Name Attributes # registry}[https://www.iana.org/assignments/imap-mailbox-name-attributes/imap-mailbox-name-attributes.xhtml] + # has links to specifications for all standard mailbox attributes. ## # method: delim @@ -413,16 +423,16 @@ class MailboxList < Struct.new(:attr, :delim, :name) # Returns the mailbox name. end - # Net::IMAP::MailboxQuota represents contents of GETQUOTA response. - # This object can also be a response to GETQUOTAROOT. In the syntax - # specification below, the delimiter used with the "#" construct is a - # single space (SPACE). + # MailboxQuota represents the data of an untagged +QUOTA+ response. # - # Net:IMAP#getquota returns an array of MailboxQuota objects. + # IMAP#getquota returns an array of MailboxQuota objects. # # Net::IMAP#getquotaroot returns an array containing both MailboxQuotaRoot # and MailboxQuota objects. # + # == Required capability + # Requires +QUOTA+ [RFC2087[https://www.rfc-editor.org/rfc/rfc2087]] + # capability. class MailboxQuota < Struct.new(:mailbox, :usage, :quota) ## # method: mailbox @@ -444,12 +454,14 @@ class MailboxQuota < Struct.new(:mailbox, :usage, :quota) # end - # Net::IMAP::MailboxQuotaRoot represents part of the GETQUOTAROOT - # response. (GETQUOTAROOT can also return Net::IMAP::MailboxQuota.) + # MailboxQuotaRoot represents the data of an untagged +QUOTAROOT+ response. # - # Net::IMAP#getquotaroot returns an array containing both MailboxQuotaRoot - # and MailboxQuota objects. + # IMAP#getquotaroot returns an array containing both MailboxQuotaRoot and + # MailboxQuota objects. # + # == Required capability + # Requires +QUOTA+ [RFC2087[https://www.rfc-editor.org/rfc/rfc2087]] + # capability. class MailboxQuotaRoot < Struct.new(:mailbox, :quotaroots) ## # method: mailbox @@ -464,12 +476,13 @@ class MailboxQuotaRoot < Struct.new(:mailbox, :quotaroots) # Zero or more quotaroots that affect the quota on the specified mailbox. end - # Net::IMAP::MailboxACLItem represents the response from GETACL. + # MailboxACLItem represents the data of an untagged +ACL+ response. # - # Net::IMAP#getacl returns an array of MailboxACLItem objects. + # IMAP#getacl returns an array of MailboxACLItem objects. # - # ==== Required capability - # +ACL+ - described in [ACL[https://www.rfc-editor.org/rfc/rfc4314]] + # == Required capability + # Requires +ACL+ [RFC4314[https://www.rfc-editor.org/rfc/rfc4314]] + # capability. class MailboxACLItem < Struct.new(:user, :rights, :mailbox) ## # method: mailbox @@ -491,11 +504,12 @@ class MailboxACLItem < Struct.new(:user, :rights, :mailbox) # The access rights the indicated #user has to the #mailbox. end - # Net::IMAP::Namespace represents a single namespace contained inside a - # NAMESPACE response. - # - # Returned by Net::IMAP#namespace, contained inside a Namespaces object. + # Namespace represents a _single_ namespace, contained inside a Namespaces + # object. # + # == Required capability + # Requires either +NAMESPACE+ [RFC2342[https://www.rfc-editor.org/rfc/rfc2342]] + # or +IMAP4rev2+ capability. class Namespace < Struct.new(:prefix, :delim, :extensions) ## # method: prefix @@ -517,11 +531,14 @@ class Namespace < Struct.new(:prefix, :delim, :extensions) # Extension parameter semantics would be defined by the extension. end - # Net::IMAP::Namespaces represents a +NAMESPACE+ server response, which - # contains lists of #personal, #shared, and #other namespaces. + # Namespaces represents the data of an untagged +NAMESPACE+ response, + # returned by IMAP#namespace. # - # Net::IMAP#namespace returns a Namespaces object. + # Contains lists of #personal, #shared, and #other namespaces. # + # == Required capability + # Requires either +NAMESPACE+ [RFC2342[https://www.rfc-editor.org/rfc/rfc2342]] + # or +IMAP4rev2+ capability. class Namespaces < Struct.new(:personal, :other, :shared) ## # method: personal @@ -542,9 +559,9 @@ class Namespaces < Struct.new(:personal, :other, :shared) # Returns an array of Shared Namespace objects. end - # Net::IMAP::StatusData represents the contents of the STATUS response. + # StatusData represents the contents of an untagged +STATUS+ response. # - # Net::IMAP#status returns the contents of #attr. + # IMAP#status returns the contents of #attr. class StatusData < Struct.new(:mailbox, :attr) ## # method: mailbox @@ -695,7 +712,7 @@ class Envelope < Struct.new(:date, :subject, :from, :sender, :reply_to, # parsed into its component parts by the server. Address objects are # returned within Envelope fields. # - # === Group syntax + # == Group syntax # # When the #host field is +nil+, this is a special form of address structure # that indicates the [RFC5322[https://www.rfc-editor.org/rfc/rfc5322]] group @@ -802,7 +819,7 @@ def all_seqnos(node = self) # for full description of all +BODYSTRUCTURE+ fields, and also # Net::IMAP@Message+envelope+and+body+structure for other relevant RFCs. # - # === Classes that include BodyStructure + # == Classes that include BodyStructure # BodyTypeBasic:: Represents any message parts that are not handled by # BodyTypeText, BodyTypeMessage, or BodyTypeMultipart. # BodyTypeText:: Used by text/* parts. Contains all of the