Skip to content

Commit bbe901a

Browse files
committed
🍒 pick 0ea729c: 📚 Update QUOTA rdoc, params, attrs to match RFCs [backports #636]
This updates the QUOTA docs with references to RFC9208 (`QUOTA=RES-*`). For the most part, RFC9208 is backward compatible with RFC2087. So this updates the documentation to reference it wherever relevant. This also documents how `net-imap`'s support for `QUOTA` is incomplete: that it only supports setting `STORAGE` and can only parse a single resource type (which is _usually_ `STORAGE`). The RFCs are very clear that `quota root` is _not_ the same as `mailbox`, so this updates method parameters and rdoc to reflect that. `MailboxQuota#mailbox` is incorrectly named, but renaming it would be backward incompatible. This just updates the documentation and adds `quota_root` as an alias. This also fixes the rdoc for `MailboxQuota#quota` to specify that it is the _storage_ limit, rather than any other quota resource type. This adds a note in the rdoc that _only_ `STORAGE` is currently supported. `GETQUOTA` generally _is_ available to normal users. That comment on `#getquota` may have been copied from `SETQUOTA`. See also: #622
1 parent cf9bee0 commit bbe901a

2 files changed

Lines changed: 88 additions & 30 deletions

File tree

‎lib/net/imap.rb‎

Lines changed: 68 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,9 @@ module Net
462462
# +LITERAL-+, and +SPECIAL-USE+.</em>
463463
#
464464
# ==== RFC2087: +QUOTA+
465+
# +NOTE:+ Only the +STORAGE+ quota resource type is currently supported.
466+
# - Obsoleted by <tt>QUOTA=RES-*</tt> [RFC9208[https://www.rfc-editor.org/rfc/rfc9208]],
467+
# although the commands are backward compatible.
465468
# - #getquota: returns the resource usage and limits for a quota root
466469
# - #getquotaroot: returns the list of quota roots for a mailbox, as well as
467470
# their resource usage and limits.
@@ -578,6 +581,16 @@ module Net
578581
# See FetchData#emailid and FetchData#emailid.
579582
# - Updates #status with support for the +MAILBOXID+ status attribute.
580583
#
584+
# ==== RFC9208: <tt>QUOTA=RES-*</tt>
585+
# +NOTE:+ Only the +STORAGE+ quota resource type is currently supported.
586+
# - Obsoletes the +QUOTA+ [RFC2087[https://www.rfc-editor.org/rfc/rfc2087]]
587+
# extension and provides strict semantics for different resource types.
588+
# - #getquota: returns the resource usage and limits for a quota root
589+
# - #getquotaroot: returns the list of quota roots for a mailbox, as well as
590+
# their resource usage and limits.
591+
# - #setquota: sets the resource limits for a given quota root.
592+
# - Updates #status with <tt>"DELETED"</tt> and +DELETED-STORAGE+ attributes.
593+
#
581594
# ==== RFC9394: +PARTIAL+
582595
# - Updates #search, #uid_search with the +PARTIAL+ return option which adds
583596
# ESearchResult#partial return data.
@@ -698,13 +711,12 @@ module Net
698711
#
699712
# === \IMAP Extensions
700713
#
701-
# [QUOTA[https://www.rfc-editor.org/rfc/rfc9208]]::
702-
# Melnikov, A., "IMAP QUOTA Extension", RFC 9208, DOI 10.17487/RFC9208,
703-
# March 2022, <https://www.rfc-editor.org/info/rfc9208>.
714+
# [QUOTA[https://www.rfc-editor.org/rfc/rfc2087]]::
715+
# Myers, J., "IMAP4 QUOTA extension", RFC 2087, DOI 10.17487/RFC2087,
716+
# January 1997, <https://www.rfc-editor.org/info/rfc2087>.
704717
#
705-
# <em>Note: obsoletes</em>
706-
# RFC-2087[https://www.rfc-editor.org/rfc/rfc2087]<em> (January 1997)</em>.
707-
# <em>Net::IMAP does not fully support the RFC9208 updates yet.</em>
718+
# *NOTE*: _obsoleted_ by RFC9208[https://www.rfc-editor.org/rfc/rfc9208]
719+
# (March 2022).
708720
# [IDLE[https://www.rfc-editor.org/rfc/rfc2177]]::
709721
# Leiba, B., "IMAP4 IDLE command", RFC 2177, DOI 10.17487/RFC2177,
710722
# June 1997, <https://www.rfc-editor.org/info/rfc2177>.
@@ -756,6 +768,11 @@ module Net
756768
# Gondwana, B., Ed., "IMAP Extension for Object Identifiers",
757769
# RFC 8474, DOI 10.17487/RFC8474, September 2018,
758770
# <https://www.rfc-editor.org/info/rfc8474>.
771+
# [{QUOTA=RES-*}[https://www.rfc-editor.org/rfc/rfc9208]]::
772+
# Melnikov, A., "IMAP QUOTA Extension", RFC 9208, DOI 10.17487/RFC9208,
773+
# March 2022, <https://www.rfc-editor.org/info/rfc9208>.
774+
#
775+
# Obsoletes RFC2087[https://www.rfc-editor.org/rfc/rfc2087].
759776
# [PARTIAL[https://www.rfc-editor.org/info/rfc9394]]::
760777
# Melnikov, A., Achuthan, A., Nagulakonda, V., and L. Alves,
761778
# "IMAP PARTIAL Extension for Paged SEARCH and FETCH", RFC 9394,
@@ -769,6 +786,7 @@ module Net
769786
#
770787
# === IANA registries
771788
# * {IMAP Capabilities}[http://www.iana.org/assignments/imap4-capabilities]
789+
# * {IMAP Quota Resource Types}[http://www.iana.org/assignments/imap4-capabilities#imap-capabilities-2]
772790
# * {IMAP Response Codes}[https://www.iana.org/assignments/imap-response-codes/imap-response-codes.xhtml]
773791
# * {IMAP Mailbox Name Attributes}[https://www.iana.org/assignments/imap-mailbox-name-attributes/imap-mailbox-name-attributes.xhtml]
774792
# * {IMAP and JMAP Keywords}[https://www.iana.org/assignments/imap-jmap-keywords/imap-jmap-keywords.xhtml]
@@ -779,8 +797,8 @@ module Net
779797
# * {GSSAPI/Kerberos/SASL Service Names}[https://www.iana.org/assignments/gssapi-service-names/gssapi-service-names.xhtml]:
780798
# +imap+
781799
# * {Character sets}[https://www.iana.org/assignments/character-sets/character-sets.xhtml]
800+
#
782801
# ==== For currently unsupported features:
783-
# * {IMAP Quota Resource Types}[http://www.iana.org/assignments/imap4-capabilities#imap-capabilities-2]
784802
# * {LIST-EXTENDED options and responses}[https://www.iana.org/assignments/imap-list-extended/imap-list-extended.xhtml]
785803
# * {IMAP METADATA Server Entry and Mailbox Entry Registries}[https://www.iana.org/assignments/imap-metadata/imap-metadata.xhtml]
786804
# * {IMAP ANNOTATE Extension Entries and Attributes}[https://www.iana.org/assignments/imap-annotate-extension/imap-annotate-extension.xhtml]
@@ -1828,12 +1846,18 @@ def xlist(refname, mailbox)
18281846
# to both admin and user. If this mailbox exists, it returns an array
18291847
# containing objects of type MailboxQuotaRoot and MailboxQuota.
18301848
#
1849+
# *NOTE:* Currently, Net::IMAP only supports +QUOTA+ responses with a single
1850+
# resource type. This is usually +STORAGE+, but you may need to verify this
1851+
# with UntaggedResponse#raw_data.
1852+
#
18311853
# Related: #getquota, #setquota, MailboxQuotaRoot, MailboxQuota
18321854
#
18331855
# ==== Capabilities
18341856
#
1835-
# The server's capabilities must include +QUOTA+
1836-
# [RFC2087[https://www.rfc-editor.org/rfc/rfc2087]].
1857+
# Requires +QUOTA+ [RFC2087[https://www.rfc-editor.org/rfc/rfc2087]]
1858+
# capability, or a capability prefixed with <tt>QUOTA=RES-*</tt>
1859+
# {[RFC9208]}[https://www.rfc-editor.org/rfc/rfc9208] for each supported
1860+
# resource type.
18371861
def getquotaroot(mailbox)
18381862
synchronize do
18391863
send_command("GETQUOTAROOT", mailbox)
@@ -1845,41 +1869,55 @@ def getquotaroot(mailbox)
18451869
end
18461870

18471871
# Sends a {GETQUOTA command [RFC2087 §4.2]}[https://www.rfc-editor.org/rfc/rfc2087#section-4.2]
1848-
# along with specified +mailbox+. If this mailbox exists, then an array
1849-
# containing a MailboxQuota object is returned. This command is generally
1850-
# only available to server admin.
1872+
# for the +quota_root+. If this quota root exists, then an array
1873+
# containing a MailboxQuota object is returned.
1874+
#
1875+
# The names of quota roots that are applicable to a particular mailbox can
1876+
# be discovered with #getquotaroot.
1877+
#
1878+
# *NOTE:* Currently, Net::IMAP only supports +QUOTA+ responses with a single
1879+
# resource type. This is usually +STORAGE+, but you may need to verify this
1880+
# with UntaggedResponse#raw_data.
18511881
#
18521882
# Related: #getquotaroot, #setquota, MailboxQuota
18531883
#
18541884
# ==== Capabilities
18551885
#
1856-
# The server's capabilities must include +QUOTA+
1857-
# [RFC2087[https://www.rfc-editor.org/rfc/rfc2087]].
1858-
def getquota(mailbox)
1886+
# Requires +QUOTA+ [RFC2087[https://www.rfc-editor.org/rfc/rfc2087]]
1887+
# capability, or a capability prefixed with <tt>QUOTA=RES-*</tt>
1888+
# {[RFC9208]}[https://www.rfc-editor.org/rfc/rfc9208] for each supported
1889+
# resource type.
1890+
def getquota(quota_root)
18591891
synchronize do
1860-
send_command("GETQUOTA", mailbox)
1892+
send_command("GETQUOTA", quota_root)
18611893
clear_responses("QUOTA")
18621894
end
18631895
end
18641896

18651897
# Sends a {SETQUOTA command [RFC2087 §4.1]}[https://www.rfc-editor.org/rfc/rfc2087#section-4.1]
1866-
# along with the specified +mailbox+ and +quota+. If +quota+ is nil, then
1867-
# +quota+ will be unset for that mailbox. Typically one needs to be logged
1868-
# in as a server admin for this to work.
1898+
# along with the specified +quota_root+ and +storage_limit+. If
1899+
# +storage_limit+ is +nil+, resource limits are unset for that quota root.
1900+
# Otherwise, it sets the +STORAGE+ resource limit.
1901+
#
1902+
# Typically one needs to be logged in as a server admin for this to work.
1903+
#
1904+
# *NOTE:* Currently, Net::IMAP only supports setting +STORAGE+ quota limits.
18691905
#
18701906
# Related: #getquota, #getquotaroot
18711907
#
18721908
# ==== Capabilities
18731909
#
1874-
# The server's capabilities must include +QUOTA+
1875-
# [RFC2087[https://www.rfc-editor.org/rfc/rfc2087]].
1876-
def setquota(mailbox, quota)
1877-
if quota.nil?
1878-
data = '()'
1910+
# Requires +QUOTA+ [RFC2087[https://www.rfc-editor.org/rfc/rfc2087]]
1911+
# capability, or a capability prefixed with <tt>QUOTA=RES-*</tt>
1912+
# {[RFC9208]}[https://www.rfc-editor.org/rfc/rfc9208] for each supported
1913+
# resource type.
1914+
def setquota(quota_root, storage_limit)
1915+
if storage_limit.nil?
1916+
list = '()'
18791917
else
1880-
data = '(STORAGE ' + quota.to_s + ')'
1918+
list = '(STORAGE ' + storage_limit.to_s + ')'
18811919
end
1882-
send_command("SETQUOTA", mailbox, RawData.new(data))
1920+
send_command("SETQUOTA", quota_root, RawData.new(list))
18831921
end
18841922

18851923
# Sends a {SETACL command [RFC4314 §3.1]}[https://www.rfc-editor.org/rfc/rfc4314#section-3.1]
@@ -1986,7 +2024,10 @@ def lsub(refname, mailbox)
19862024
# <tt>STATUS=SIZE</tt>
19872025
# {[RFC8483]}[https://www.rfc-editor.org/rfc/rfc8483.html].
19882026
#
1989-
# +DELETED+ requires the server's capabilities to include +IMAP4rev2+.
2027+
# +DELETED+ must be supported when the server's capabilities includes
2028+
# +IMAP4rev2+.
2029+
# or <tt>QUOTA=RES-MESSAGES</tt>
2030+
# {[RFC9208]}[https://www.rfc-editor.org/rfc/rfc9208.html].
19902031
#
19912032
# +HIGHESTMODSEQ+ requires the server's capabilities to include +CONDSTORE+
19922033
# {[RFC7162]}[https://www.rfc-editor.org/rfc/rfc7162.html].

‎lib/net/imap/response_data.rb‎

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,14 @@ class ResponseText < Struct.new(:code, :text)
307307
# because the server doesn't allow deletion of mailboxes with children.
308308
# #data is +nil+.
309309
#
310+
# === <tt>QUOTA=RES-*</tt> response codes
311+
# See {[RFC9208]}[https://www.rfc-editor.org/rfc/rfc9208.html#section-4.3].
312+
# * +OVERQUOTA+ (also in RFC5530[https://www.rfc-editor.org/rfc/rfc5530]),
313+
# with a tagged +NO+ response to an +APPEND+/+COPY+/+MOVE+ command when
314+
# the command would put the target mailbox over any quota, and with an
315+
# untagged +NO+ when a mailbox exceeds a soft quota (which may be caused
316+
# be external events). #data is +nil+.
317+
#
310318
# === +CONDSTORE+ extension
311319
# See {[RFC7162]}[https://www.rfc-editor.org/rfc/rfc7162.html].
312320
# * +NOMODSEQ+, when selecting a mailbox that does not support
@@ -384,14 +392,23 @@ class MailboxList < Struct.new(:attr, :delim, :name)
384392
# and MailboxQuota objects.
385393
#
386394
# == Required capability
395+
#
387396
# Requires +QUOTA+ [RFC2087[https://www.rfc-editor.org/rfc/rfc2087]]
388-
# capability.
397+
# or <tt>QUOTA=RES-STORAGE</tt>
398+
# [RFC9208[https://www.rfc-editor.org/rfc/rfc9208]] capability.
389399
class MailboxQuota < Struct.new(:mailbox, :usage, :quota)
390400
##
391401
# method: mailbox
392402
# :call-seq: mailbox -> string
393403
#
394-
# The mailbox with the associated quota.
404+
# The quota root with the associated quota.
405+
#
406+
# NOTE: this was mistakenly named "mailbox". But the quota root's name may
407+
# differ from the mailbox. A single quota root may cover multiple
408+
# mailboxes, and a single mailbox may be governed by multiple quota roots.
409+
410+
# The quota root with the associated quota.
411+
alias quota_root mailbox
395412

396413
##
397414
# method: usage
@@ -403,7 +420,7 @@ class MailboxQuota < Struct.new(:mailbox, :usage, :quota)
403420
# method: quota
404421
# :call-seq: quota -> Integer
405422
#
406-
# Quota limit imposed on the mailbox.
423+
# Storage limit imposed on the mailbox.
407424
#
408425
end
409426

0 commit comments

Comments
 (0)