@@ -101,7 +101,7 @@ module Net
101101 # end
102102 # imap.expunge
103103 #
104- # == Server capabilities and protocol extensions
104+ # == Capabilities
105105 #
106106 # Net::IMAP does not _currently_ modify its behaviour according to the
107107 # server's advertised #capabilities. Users of this class must check that the
@@ -144,12 +144,12 @@ module Net
144144 #
145145 # === Caching +CAPABILITY+ responses
146146 #
147- # Net::IMAP stores and discards capability
148- # data according to the requirements and recommendations in IMAP4rev2
149- # {§6.1.1}[https://www.rfc-editor.org/rfc/rfc9051#section-6.1.1],
147+ # Net::IMAP automatically stores and discards capability data according to the
148+ # the requirements and recommendations in
149+ # {IMAP4rev2 §6.1.1}[https://www.rfc-editor.org/rfc/rfc9051#section-6.1.1],
150150 # {§6.2}[https://www.rfc-editor.org/rfc/rfc9051#section-6.2], and
151151 # {§7.1}[https://www.rfc-editor.org/rfc/rfc9051#section-7.1].
152- # Use #capable?, #auth_capable?, or #capabilities to this caching and avoid
152+ # Use #capable?, #auth_capable?, or #capabilities to use this cache and avoid
153153 # sending the #capability command unnecessarily.
154154 #
155155 # The server may advertise its initial capabilities using the +CAPABILITY+
@@ -166,6 +166,10 @@ module Net
166166 #
167167 # === Using IMAP4rev1 extensions
168168 #
169+ # See the {IANA IMAP4 capabilities
170+ # registry}[http://www.iana.org/assignments/imap4-capabilities] for a list of
171+ # all standard capabilities, and their reference RFCs.
172+ #
169173 # IMAP4rev1 servers must not activate behavior that is incompatible with the
170174 # base specification until an explicit client action invokes a capability,
171175 # e.g. sending a command or command argument specific to that capability.
@@ -179,7 +183,7 @@ module Net
179183 # BadResponseError, or cause other unexpected behavior.
180184 #
181185 # Some capabilities must be explicitly activated using the #enable command.
182- # See #enable for more details.
186+ # See #enable for details.
183187 #
184188 # == Thread Safety
185189 #
@@ -751,66 +755,61 @@ def disconnected?
751755 return @sock . closed?
752756 end
753757
754- # Returns the server capabilities. When available, cached capabilities are
755- # used without sending a new #capability command to the server.
756- #
757- # To ensure case-insensitive capability comparison, use #capable? instead.
758- #
759- # Related: #capable?, #auth_capable?, #capability
760- def capabilities
761- @capabilities || capability
762- end
763-
764758 # Returns whether the server supports a given +capability+. When available,
765759 # cached #capabilities are used without sending a new #capability command to
766760 # the server.
767761 #
768- # See the {IANA IMAP4 capabilities
769- # registry}[http://www.iana.org/assignments/imap4-capabilities] for a list
770- # of all standard capabilities, and their reference RFCs.
771- #
772- # >>>
773- # <em>*NOTE:* Net::IMAP does not _currently_ modify its behaviour
774- # according to the server's advertised capabilities. Users of this class
775- # must check that the server is #capable? of extension commands or command
776- # arguments before sending them.</em>
762+ # <em>*NOTE:* Net::IMAP does not</em> currently <em>modify its behaviour
763+ # according to the server's advertised capabilities.</em>
777764 #
778- # <em>Capability requirements—other than +IMAP4rev1+—are listed in the
779- # documentation for each command method.</em>
765+ # See Net::IMAP@Capabilities for more about \IMAP capabilities.
780766 #
781767 # Related: #auth_capable?, #capabilities, #capability, #enable
782768 #
783- # ===== Caching +CAPABILITY+ responses
784- #
785- # Servers may send their capability list unsolicited, using the +CAPABILITY+
786- # response code or an untagged +CAPABILITY+ response. Cached capabilities
787- # are discarded after #starttls, #login, or #authenticate. Caching and
788- # cache invalidation are handled internally by Net::IMAP.
789- #
790769 def capable? ( capability ) capabilities . include? capability . to_s . upcase end
791770 alias capability? capable?
792771
772+ # Returns the server capabilities. When available, cached capabilities are
773+ # used without sending a new #capability command to the server.
774+ #
775+ # To ensure a case-insensitive comparison, #capable? can be used instead.
776+ #
777+ # <em>*NOTE:* Net::IMAP does not</em> currently <em>modify its behaviour
778+ # according to the server's advertised capabilities.</em>
779+ #
780+ # See Net::IMAP@Capabilities for more about \IMAP capabilities.
781+ #
782+ # Related: #capable?, #auth_capable?, #capability
783+ def capabilities
784+ @capabilities || capability
785+ end
786+
793787 # Returns the #authenticate mechanisms that the server claims to support.
794788 # These are derived from the #capabilities with an <tt>AUTH=</tt> prefix.
795789 #
796790 # This may be different when the connection is cleartext or using TLS. Most
797791 # servers will drop all <tt>AUTH=</tt> mechanisms from #capabilities after
798792 # the connection has authenticated.
799793 #
800- # Related: #auth_capable?, #capabilities
801- #
802- # ===== Example
803- #
804794 # imap = Net::IMAP.new(hostname, ssl: false)
805795 # imap.capabilities # => ["IMAP4REV1", "LOGINDISABLED"]
806796 # imap.auth_mechanisms # => []
797+ #
807798 # imap.starttls
808799 # imap.capabilities # => ["IMAP4REV1", "AUTH=PLAIN", "AUTH=XOAUTH2",
809- # "AUTH=OAUTHBEARER", "AUTH=SCRAM-SHA-256"]
810- # imap.auth_mechanisms # => ["PLAIN", "XOAUTH2", "SCRAM-SHA-256"]
811- # imap.authenticate("OAUTHBEARER", username, oauth2_access_token)
800+ # # "AUTH=OAUTHBEARER"]
801+ # imap.auth_mechanisms # => ["PLAIN", "XOAUTH2", "OAUTHBEARER"]
802+ #
803+ # imap.authenticate("XOAUTH2", username, oauth2_access_token)
812804 # imap.auth_mechanisms # => []
813805 #
806+ # <em>*NOTE:* Net::IMAP does not</em> currently <em>modify its behaviour
807+ # according to the server's advertised capabilities.</em>
808+ #
809+ # See Net::IMAP@Capabilities for more about \IMAP capabilities.
810+ #
811+ # Related: #auth_capable?, #capabilities
812+ #
814813 def auth_mechanisms
815814 capabilities
816815 . grep ( /\A AUTH=/i )
@@ -823,12 +822,15 @@ def auth_mechanisms
823822 # available, cached capabilities are used without sending a new #capability
824823 # command to the server.
825824 #
826- # Per {[IMAP4rev1 §6.2.2]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.2.2],
827- #
828825 # imap.capable? "AUTH=PLAIN" # => true
829826 # imap.auth_capable? "PLAIN" # => true
830827 # imap.auth_capable? "blurdybloop" # => false
831828 #
829+ # <em>*NOTE:* Net::IMAP does not</em> currently <em>modify its behaviour
830+ # according to the server's advertised capabilities.</em>
831+ #
832+ # See Net::IMAP@Capabilities for more about \IMAP capabilities.
833+ #
832834 # Related: #authenticate, #capable?, #capabilities
833835 def auth_capable? ( mechanism )
834836 capable? "AUTH=#{ mechanism } "
@@ -837,16 +839,22 @@ def auth_capable?(mechanism)
837839 # Returns whether capabilities have been cached. When true, #capable? and
838840 # #capabilities don't require sending a #capability command to the server.
839841 #
840-
841- # Returns whether capabilities have been cached. When true, #capable? and
842- # #capabilities don't require sending a #capability command to the server.
842+ # See Net::IMAP@Capabilities for more about \IMAP capabilities.
843+ #
844+ # Related: #capable?, #capability, #clear_cached_capabilities
843845 def capabilities_cached?
844846 !!@capabilities
845847 end
846848
847- # Clears capabilities that are currently cached by the Net::IMAP client.
848- # This forces a #capability command to be sent the next time that #capable?
849- # or #capabilities? are called.
849+ # Clears capabilities that have been remembered by the Net::IMAP client.
850+ # This forces a #capability command to be sent the next time a #capabilities
851+ # query method is called.
852+ #
853+ # Net::IMAP automatically discards its cached capabilities when they can
854+ # change. Explicitly calling this _should_ be unnecessary for well-behaved
855+ # servers.
856+ #
857+ # Related: #capable?, #capability, #capabilities_cached?
850858 def clear_cached_capabilities
851859 synchronize do
852860 clear_responses ( "CAPABILITY" )
@@ -856,23 +864,22 @@ def clear_cached_capabilities
856864
857865 # Sends a {CAPABILITY command [IMAP4rev1 §6.1.1]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.1.1]
858866 # and returns an array of capabilities that are supported by the server.
859- # The result will be stored for use by #capable? and #capabilities.
867+ # The result is stored for use by #capable? and #capabilities.
860868 #
861- # In general, #capable? or #capabilities should be used instead. They cache
862- # the capability result to avoid sending unnecessary commands. They also
863- # ensure cache invalidation is handled correctly.
869+ # <em>*NOTE:* Net::IMAP does not</em> currently <em>modify its behaviour
870+ # according to the server's advertised capabilities.</em>
864871 #
865- # >>>
866- # <em>*NOTE:* Net::IMAP does not _currently_ modify its behaviour
867- # according to the server's advertised capabilities. Users of this class
868- # must check that the server is #capable? of extension commands or command
869- # arguments before sending them.</em>
872+ # Net::IMAP automatically stores and discards capability data according to
873+ # the requirements and recommendations in
874+ # {IMAP4rev2 §6.1.1}[https://www.rfc-editor.org/rfc/rfc9051#section-6.1.1],
875+ # {§6.2}[https://www.rfc-editor.org/rfc/rfc9051#section-6.2], and
876+ # {§7.1}[https://www.rfc-editor.org/rfc/rfc9051#section-7.1].
877+ # Use #capable?, #auth_capable?, or #capabilities to this cache and avoid
878+ # sending the #capability command unnecessarily.
870879 #
871- # <em>Capability requirements—other than +IMAP4rev1+—are listed in the
872- # documentation for each command method.</em>
880+ # See Net::IMAP@Capabilities for more about \IMAP capabilities.
873881 #
874882 # Related: #capable?, #auth_capable?, #capability, #enable
875- #
876883 def capability
877884 synchronize do
878885 send_command ( "CAPABILITY" )
@@ -994,7 +1001,7 @@ def starttls(options = {}, verify = true)
9941001 #
9951002 # An exception Net::IMAP::NoResponseError is raised if authentication fails.
9961003 #
997- # Related: #login, #starttls
1004+ # Related: #login, #starttls, #auth_capable?, #auth_mechanisms
9981005 #
9991006 # ==== Supported SASL Mechanisms
10001007 #
@@ -1024,40 +1031,28 @@ def starttls(options = {}, verify = true)
10241031 # for information on these and other SASL mechanisms.
10251032 #
10261033 # ===== Capabilities
1027- # Clients should not call #authenticate with mechanisms that are included in the server #capabilities as <tt>"AUTH=#{mechanism}"</tt>.
1034+ #
1035+ # The server should list <tt>"AUTH=#{mechanism}"</tt> capabilities for
1036+ # supported mechanisms. Check #auth_capable? or #auth_mechanisms before
1037+ # using a particular mechanism.
1038+ #
1039+ # if imap.auth_capable? "XOAUTH2"
1040+ # imap.authenticate "XOAUTH2", username, oauth2_access_token
1041+ # elsif imap.auth_capable? "PLAIN"
1042+ # imap.authenticate "PLAIN", username, password
1043+ # elsif imap.auth_capable? "DIGEST-MD5"
1044+ # imap.authenticate "DIGEST-MD5", username, password
1045+ # elsif !imap.capability? "LOGINDISABLED"
1046+ # imap.login username, password
1047+ # else
1048+ # raise "No acceptable authentication mechanism is available"
1049+ # end
10281050 #
10291051 # Server capabilities may change after #starttls, #login, and #authenticate.
10301052 # Cached #capabilities will be cleared when this method completes.
10311053 # If the TaggedResponse to #authenticate includes updated capabilities, they
10321054 # will be cached.
10331055 #
1034- # ===== Example
1035- # Use auth_capable? to discover which mechanisms are suuported by the
1036- # server. For authenticators that ignore unhandled keyword arguments, the
1037- # same config can be used for multiple mechanisms:
1038- #
1039- # password = nil # saved locally, so we don't ask more than once
1040- # accesstok = nil # saved locally...
1041- # creds = {
1042- # authcid: username,
1043- # password: proc { password ||= ui.prompt_for_password },
1044- # oauth2_token: proc { accesstok ||= kms.fresh_access_token },
1045- # }
1046- # mechanism = %w[
1047- # OAUTHBEARER XOAUTH2
1048- # SCRAM-SHA-256 SCRAM-SHA-1
1049- # PLAIN
1050- # ].find {|m|
1051- # imap.auth_capable?(m)
1052- # }
1053- # if mechanism
1054- # imap.authenticate mechanism, **creds
1055- # elsif capable? "LOGINDISABLED"
1056- # raise "the server has disabled login"
1057- # else
1058- # imap.login username, password
1059- # end
1060- #
10611056 def authenticate ( mechanism , ...)
10621057 authenticator = self . class . authenticator ( mechanism , ...)
10631058 send_command ( "AUTHENTICATE" , mechanism ) do |resp |
@@ -1085,10 +1080,17 @@ def authenticate(mechanism, ...)
10851080 #
10861081 # Related: #authenticate, #starttls
10871082 #
1088- # ==== Capabilities
1089- # An IMAP client MUST NOT call #login unless the server advertises the
1083+ # ===== Capabilities
1084+ #
1085+ # An IMAP client MUST NOT call #login when the server advertises the
10901086 # +LOGINDISABLED+ capability.
10911087 #
1088+ # if imap.capability? "LOGINDISABLED"
1089+ # raise "Remote server has disabled the login command"
1090+ # else
1091+ # imap.login username, password
1092+ # end
1093+ #
10921094 # Server capabilities may change after #starttls, #login, and #authenticate.
10931095 # Cached capabilities _must_ be invalidated after this method completes.
10941096 # The TaggedResponse to #login may include updated capabilities in its
0 commit comments