// // AsyncPop3Client.cs // // Author: Jeffrey Stedfast // // Copyright (c) 2013-2020 .NET Foundation and Contributors // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // using System; using System.IO; using System.Net; using System.Text; using System.Threading; using System.Net.Sockets; using System.Threading.Tasks; using System.Collections.Generic; using MimeKit; using MailKit.Security; namespace MailKit.Net.Pop3 { public partial class Pop3Client { /// /// Asynchronously authenticate using the specified SASL mechanism. /// /// /// Authenticates using the specified SASL mechanism. /// For a list of available SASL authentication mechanisms supported by the server, /// check the property after the service has been /// connected. /// /// An asynchronous task context. /// The SASL mechanism. /// The cancellation token. /// /// is null. /// /// /// The has been disposed. /// /// /// The is not connected. /// /// /// The is already authenticated. /// /// /// The operation was canceled via the cancellation token. /// /// /// Authentication using the supplied credentials has failed. /// /// /// A SASL authentication error occurred. /// /// /// An I/O error occurred. /// /// /// A POP3 command failed. /// /// /// An POP3 protocol error occurred. /// public override Task AuthenticateAsync (SaslMechanism mechanism, CancellationToken cancellationToken = default (CancellationToken)) { return AuthenticateAsync (mechanism, true, cancellationToken); } /// /// Asynchronously authenticates using the supplied credentials. /// /// /// If the POP3 server supports the APOP authentication mechanism, /// then APOP is used. /// If the APOP authentication mechanism is not supported and the /// server supports one or more SASL authentication mechanisms, then /// the SASL mechanisms that both the client and server support are tried /// in order of greatest security to weakest security. Once a SASL /// authentication mechanism is found that both client and server support, /// the credentials are used to authenticate. /// If the server does not support SASL or if no common SASL mechanisms /// can be found, then the USER and PASS commands are used as a /// fallback. /// To prevent the usage of certain authentication mechanisms, /// simply remove them from the hash set /// before calling this method. /// In the case of the APOP authentication mechanism, remove it from the /// property instead. /// /// An asynchronous task context. /// The text encoding to use for the user's credentials. /// The user's credentials. /// The cancellation token. /// /// is null. /// -or- /// is null. /// /// /// The has been disposed. /// /// /// The is not connected. /// /// /// The is already authenticated. /// /// /// The operation was canceled via the cancellation token. /// /// /// Authentication using the supplied credentials has failed. /// /// /// A SASL authentication error occurred. /// /// /// An I/O error occurred. /// /// /// A POP3 command failed. /// /// /// An POP3 protocol error occurred. /// public override Task AuthenticateAsync (Encoding encoding, ICredentials credentials, CancellationToken cancellationToken = default (CancellationToken)) { return AuthenticateAsync (encoding, credentials, true, cancellationToken); } /// /// Asynchronously establish a connection to the specified POP3 or POP3/S server. /// /// /// Establishes a connection to the specified POP3 or POP3/S server. /// If the has a value of 0, then the /// parameter is used to determine the default port to /// connect to. The default port used with /// is 995. All other values will use a default port of 110. /// If the has a value of /// , then the is used /// to determine the default security options. If the has a value /// of 995, then the default options used will be /// . All other values will use /// . /// Once a connection is established, properties such as /// and will be /// populated. /// /// /// /// /// An asynchronous task context. /// The host name to connect to. /// The port to connect to. If the specified port is 0, then the default port will be used. /// The secure socket options to when connecting. /// The cancellation token. /// /// is null. /// /// /// is not between 0 and 65535. /// /// /// The is a zero-length string. /// /// /// The has been disposed. /// /// /// The is already connected. /// /// /// The operation was canceled via the cancellation token. /// /// /// was set to /// /// and the POP3 server does not support the STLS extension. /// /// /// A socket error occurred trying to connect to the remote host. /// /// /// An error occurred during the SSL/TLS negotiations. /// /// /// An I/O error occurred. /// /// /// A POP3 command failed. /// /// /// A POP3 protocol error occurred. /// public override Task ConnectAsync (string host, int port = 0, SecureSocketOptions options = SecureSocketOptions.Auto, CancellationToken cancellationToken = default (CancellationToken)) { return ConnectAsync (host, port, options, true, cancellationToken); } /// /// Asynchronously establish a connection to the specified POP3 or POP3/S server using the provided socket. /// /// /// Establishes a connection to the specified POP3 or POP3/S server using /// the provided socket. /// If the has a value of /// , then the is used /// to determine the default security options. If the has a value /// of 995, then the default options used will be /// . All other values will use /// . /// Once a connection is established, properties such as /// and will be /// populated. /// With the exception of using the to determine the /// default to use when the value /// is , the and /// parameters are only used for logging purposes. /// /// An asynchronous task context. /// The socket to use for the connection. /// The host name to connect to. /// The port to connect to. If the specified port is 0, then the default port will be used. /// The secure socket options to when connecting. /// The cancellation token. /// /// is null. /// -or- /// is null. /// /// /// is not between 0 and 65535. /// /// /// is not connected. /// -or- /// The is a zero-length string. /// /// /// The has been disposed. /// /// /// The is already connected. /// /// /// was set to /// /// and the POP3 server does not support the STLS extension. /// /// /// The operation was canceled via the cancellation token. /// /// /// An error occurred during the SSL/TLS negotiations. /// /// /// An I/O error occurred. /// /// /// A POP3 command failed. /// /// /// A POP3 protocol error occurred. /// public override Task ConnectAsync (Socket socket, string host, int port = 0, SecureSocketOptions options = SecureSocketOptions.Auto, CancellationToken cancellationToken = default (CancellationToken)) { return ConnectAsync (socket, host, port, options, true, cancellationToken); } /// /// Asynchronously establish a connection to the specified POP3 or POP3/S server using the provided stream. /// /// /// Establishes a connection to the specified POP3 or POP3/S server using /// the provided stream. /// If the has a value of /// , then the is used /// to determine the default security options. If the has a value /// of 995, then the default options used will be /// . All other values will use /// . /// Once a connection is established, properties such as /// and will be /// populated. /// With the exception of using the to determine the /// default to use when the value /// is , the and /// parameters are only used for logging purposes. /// /// An asynchronous task context. /// The socket to use for the connection. /// The host name to connect to. /// The port to connect to. If the specified port is 0, then the default port will be used. /// The secure socket options to when connecting. /// The cancellation token. /// /// is null. /// -or- /// is null. /// /// /// is not between 0 and 65535. /// /// /// The is a zero-length string. /// /// /// The has been disposed. /// /// /// The is already connected. /// /// /// was set to /// /// and the POP3 server does not support the STLS extension. /// /// /// The operation was canceled via the cancellation token. /// /// /// An error occurred during the SSL/TLS negotiations. /// /// /// An I/O error occurred. /// /// /// A POP3 command failed. /// /// /// A POP3 protocol error occurred. /// public override Task ConnectAsync (Stream stream, string host, int port = 0, SecureSocketOptions options = SecureSocketOptions.Auto, CancellationToken cancellationToken = default (CancellationToken)) { return ConnectAsync (stream, host, port, options, true, cancellationToken); } /// /// Asynchronously disconnect the service. /// /// /// If is true, a QUIT command will be issued in order to disconnect cleanly. /// /// /// /// /// An asynchronous task context. /// If set to true, a QUIT command will be issued in order to disconnect cleanly. /// The cancellation token. /// /// The has been disposed. /// public override Task DisconnectAsync (bool quit, CancellationToken cancellationToken = default (CancellationToken)) { return DisconnectAsync (quit, true, cancellationToken); } /// /// Asynchronously get the message count. /// /// /// Asynchronously gets the message count. /// /// The message count. /// The cancellation token. /// /// The has been disposed. /// /// /// The is not connected. /// /// /// The is not authenticated. /// /// /// The operation was canceled via the cancellation token. /// /// /// An I/O error occurred. /// /// /// The POP3 command failed. /// /// /// A POP3 protocol error occurred. /// public override async Task GetMessageCountAsync (CancellationToken cancellationToken = default (CancellationToken)) { CheckDisposed (); CheckConnected (); CheckAuthenticated (); await UpdateMessageCountAsync (true, cancellationToken).ConfigureAwait (false); return Count; } /// /// Ping the POP3 server to keep the connection alive. /// /// Mail servers, if left idle for too long, will automatically drop the connection. /// An asynchronous task context. /// The cancellation token. /// /// The has been disposed. /// /// /// The is not connected. /// /// /// The is not authenticated. /// /// /// The operation was canceled via the cancellation token. /// /// /// An I/O error occurred. /// /// /// The POP3 command failed. /// /// /// A POP3 protocol error occurred. /// public override Task NoOpAsync (CancellationToken cancellationToken = default (CancellationToken)) { return NoOpAsync (true, cancellationToken); } /// /// Asynchronously enable UTF8 mode. /// /// /// The POP3 UTF8 extension allows the client to retrieve messages in the UTF-8 encoding and /// may also allow the user to authenticate using a UTF-8 encoded username or password. /// /// An asynchronous task context. /// The cancellation token. /// /// The has been disposed. /// /// /// The is not connected. /// /// /// The has already been authenticated. /// /// /// The operation was canceled via the cancellation token. /// /// /// The POP3 server does not support the UTF8 extension. /// /// /// An I/O error occurred. /// /// /// The POP3 command failed. /// /// /// A POP3 protocol error occurred. /// public Task EnableUTF8Async (CancellationToken cancellationToken = default (CancellationToken)) { return EnableUTF8Async (true, cancellationToken); } /// /// Asynchronously get the list of languages supported by the POP3 server. /// /// /// If the POP3 server supports the LANG extension, it is possible to /// query the list of languages supported by the POP3 server that can /// be used for error messages. /// /// The supported languages. /// The cancellation token. /// /// The has been disposed. /// /// /// The is not connected. /// /// /// The operation was canceled via the cancellation token. /// /// /// The POP3 server does not support the LANG extension. /// /// /// An I/O error occurred. /// /// /// The POP3 command failed. /// /// /// A POP3 protocol error occurred. /// public Task> GetLanguagesAsync (CancellationToken cancellationToken = default (CancellationToken)) { return GetLanguagesAsync (true, cancellationToken); } /// /// Asynchronously set the language used by the POP3 server for error messages. /// /// /// If the POP3 server supports the LANG extension, it is possible to /// set the language used by the POP3 server for error messages. /// /// An asynchronous task context. /// The language code. /// The cancellation token. /// /// is null. /// /// /// is empty. /// /// /// The has been disposed. /// /// /// The is not connected. /// /// /// The operation was canceled via the cancellation token. /// /// /// The POP3 server does not support the LANG extension. /// /// /// An I/O error occurred. /// /// /// The POP3 command failed. /// /// /// A POP3 protocol error occurred. /// public Task SetLanguageAsync (string lang, CancellationToken cancellationToken = default (CancellationToken)) { return SetLanguageAsync (lang, true, cancellationToken); } /// /// Asynchronously get the UID of the message at the specified index. /// /// /// Gets the UID of the message at the specified index. /// Not all servers support UIDs, so you should first check the /// property for the flag or /// the convenience property. /// /// The message UID. /// The message index. /// The cancellation token. /// /// is not a valid message index. /// /// /// The has been disposed. /// /// /// The is not connected. /// /// /// The is not authenticated. /// /// /// The POP3 server does not support the UIDL extension. /// /// /// The operation was canceled via the cancellation token. /// /// /// An I/O error occurred. /// /// /// The POP3 command failed. /// /// /// A POP3 protocol error occurred. /// public override Task GetMessageUidAsync (int index, CancellationToken cancellationToken = default (CancellationToken)) { return GetMessageUidAsync (index, true, cancellationToken); } /// /// Asynchronously get the full list of available message UIDs. /// /// /// Gets the full list of available message UIDs. /// Not all servers support UIDs, so you should first check the /// property for the flag or /// the convenience property. /// /// /// /// /// The message uids. /// The cancellation token. /// /// The has been disposed. /// /// /// The is not connected. /// /// /// The is not authenticated. /// /// /// The POP3 server does not support the UIDL extension. /// /// /// The operation was canceled via the cancellation token. /// /// /// An I/O error occurred. /// /// /// The POP3 command failed. /// /// /// A POP3 protocol error occurred. /// public override Task> GetMessageUidsAsync (CancellationToken cancellationToken = default (CancellationToken)) { return GetMessageUidsAsync (true, cancellationToken); } /// /// Asynchronously get the size of the specified message, in bytes. /// /// /// Gets the size of the specified message, in bytes. /// /// The message size, in bytes. /// The index of the message. /// The cancellation token. /// /// is not a valid message index. /// /// /// The has been disposed. /// /// /// The is not connected. /// /// /// The is not authenticated. /// /// /// The operation was canceled via the cancellation token. /// /// /// An I/O error occurred. /// /// /// The POP3 command failed. /// /// /// A POP3 protocol error occurred. /// public override Task GetMessageSizeAsync (int index, CancellationToken cancellationToken = default (CancellationToken)) { return GetMessageSizeAsync (index, true, cancellationToken); } /// /// Asynchronously get the sizes for all available messages, in bytes. /// /// /// Gets the sizes for all available messages, in bytes. /// /// The message sizes, in bytes. /// The cancellation token. /// /// The has been disposed. /// /// /// The is not connected. /// /// /// The is not authenticated. /// /// /// The operation was canceled via the cancellation token. /// /// /// An I/O error occurred. /// /// /// The POP3 command failed. /// /// /// A POP3 protocol error occurred. /// public override Task> GetMessageSizesAsync (CancellationToken cancellationToken = default (CancellationToken)) { return GetMessageSizesAsync (true, cancellationToken); } /// /// Asynchronously get the headers for the message at the specified index. /// /// /// Gets the headers for the message at the specified index. /// /// The message headers. /// The index of the message. /// The cancellation token. /// /// is not a valid message index. /// /// /// The has been disposed. /// /// /// The is not connected. /// /// /// The is not authenticated. /// /// /// The operation was canceled via the cancellation token. /// /// /// An I/O error occurred. /// /// /// The POP3 command failed. /// /// /// A POP3 protocol error occurred. /// public override Task GetMessageHeadersAsync (int index, CancellationToken cancellationToken = default (CancellationToken)) { CheckDisposed (); CheckConnected (); CheckAuthenticated (); if (index < 0 || index >= total) throw new ArgumentOutOfRangeException (nameof (index)); var ctx = new DownloadHeaderContext (this, parser); return ctx.DownloadAsync (index + 1, true, true, cancellationToken); } /// /// Asynchronously get the headers for the messages at the specified indexes. /// /// /// Gets the headers for the messages at the specified indexes. /// When the POP3 server supports the /// extension, this method will likely be more efficient than using /// for each message because /// it will batch the commands to reduce latency. /// /// The headers for the specified messages. /// The indexes of the messages. /// The cancellation token. /// /// is null. /// /// /// One or more of the are invalid. /// /// /// The has been disposed. /// /// /// The is not connected. /// /// /// The is not authenticated. /// /// /// The POP3 server does not support the UIDL extension. /// /// /// The operation was canceled via the cancellation token. /// /// /// An I/O error occurred. /// /// /// The POP3 command failed. /// /// /// A POP3 protocol error occurred. /// public override Task> GetMessageHeadersAsync (IList indexes, CancellationToken cancellationToken = default (CancellationToken)) { CheckDisposed (); CheckConnected (); CheckAuthenticated (); if (indexes == null) throw new ArgumentNullException (nameof (indexes)); if (indexes.Count == 0) return Task.FromResult ((IList) new HeaderList[0]); var seqids = new int[indexes.Count]; for (int i = 0; i < indexes.Count; i++) { if (indexes[i] < 0 || indexes[i] >= total) throw new ArgumentException ("One or more of the indexes are invalid.", nameof (indexes)); seqids[i] = indexes[i] + 1; } var ctx = new DownloadHeaderContext (this, parser); return ctx.DownloadAsync (seqids, true, true, cancellationToken); } /// /// Asynchronously get the headers of the messages within the specified range. /// /// /// Gets the headers of the messages within the specified range. /// When the POP3 server supports the /// extension, this method will likely be more efficient than using /// for each message because /// it will batch the commands to reduce latency. /// /// The headers of the messages within the specified range. /// The index of the first message to get. /// The number of messages to get. /// The cancellation token. /// /// and do not specify /// a valid range of messages. /// /// /// The has been disposed. /// /// /// The is not connected. /// /// /// The is not authenticated. /// /// /// The POP3 server does not support the UIDL extension. /// /// /// The operation was canceled via the cancellation token. /// /// /// An I/O error occurred. /// /// /// The POP3 command failed. /// /// /// A POP3 protocol error occurred. /// public override Task> GetMessageHeadersAsync (int startIndex, int count, CancellationToken cancellationToken = default (CancellationToken)) { CheckDisposed (); CheckConnected (); CheckAuthenticated (); if (startIndex < 0 || startIndex >= total) throw new ArgumentOutOfRangeException (nameof (startIndex)); if (count < 0 || count > (total - startIndex)) throw new ArgumentOutOfRangeException (nameof (count)); if (count == 0) return Task.FromResult ((IList) new HeaderList[0]); var seqids = new int[count]; for (int i = 0; i < count; i++) seqids[i] = startIndex + i + 1; var ctx = new DownloadHeaderContext (this, parser); return ctx.DownloadAsync (seqids, true, true, cancellationToken); } /// /// Asynchronously get the message at the specified index. /// /// /// Gets the message at the specified index. /// /// /// /// /// The message. /// The index of the message. /// The cancellation token. /// The progress reporting mechanism. /// /// is not a valid message index. /// /// /// The has been disposed. /// /// /// The is not connected. /// /// /// The is not authenticated. /// /// /// The operation was canceled via the cancellation token. /// /// /// An I/O error occurred. /// /// /// The POP3 command failed. /// /// /// A POP3 protocol error occurred. /// public override Task GetMessageAsync (int index, CancellationToken cancellationToken = default (CancellationToken), ITransferProgress progress = null) { CheckDisposed (); CheckConnected (); CheckAuthenticated (); if (index < 0 || index >= total) throw new ArgumentOutOfRangeException (nameof (index)); var ctx = new DownloadMessageContext (this, parser, progress); return ctx.DownloadAsync (index + 1, false, true, cancellationToken); } /// /// Asynchronously get the messages at the specified indexes. /// /// /// Gets the messages at the specified indexes. /// When the POP3 server supports the /// extension, this method will likely be more efficient than using /// for each message /// because it will batch the commands to reduce latency. /// /// The messages. /// The indexes of the messages. /// The cancellation token. /// The progress reporting mechanism. /// /// is null. /// /// /// One or more of the are invalid. /// /// /// The has been disposed. /// /// /// The is not connected. /// /// /// The is not authenticated. /// /// /// The POP3 server does not support the UIDL extension. /// /// /// The operation was canceled via the cancellation token. /// /// /// An I/O error occurred. /// /// /// The POP3 command failed. /// /// /// A POP3 protocol error occurred. /// public override Task> GetMessagesAsync (IList indexes, CancellationToken cancellationToken = default (CancellationToken), ITransferProgress progress = null) { CheckDisposed (); CheckConnected (); CheckAuthenticated (); if (indexes == null) throw new ArgumentNullException (nameof (indexes)); if (indexes.Count == 0) return Task.FromResult ((IList) new MimeMessage[0]); var seqids = new int[indexes.Count]; for (int i = 0; i < indexes.Count; i++) { if (indexes[i] < 0 || indexes[i] >= total) throw new ArgumentException ("One or more of the indexes are invalid.", nameof (indexes)); seqids[i] = indexes[i] + 1; } var ctx = new DownloadMessageContext (this, parser, progress); return ctx.DownloadAsync (seqids, false, true, cancellationToken); } /// /// Asynchronously get the messages within the specified range. /// /// /// Gets the messages within the specified range. /// When the POP3 server supports the /// extension, this method will likely be more efficient than using /// for each message /// because it will batch the commands to reduce latency. /// /// /// /// /// The messages. /// The index of the first message to get. /// The number of messages to get. /// The cancellation token. /// The progress reporting mechanism. /// /// and do not specify /// a valid range of messages. /// /// /// The has been disposed. /// /// /// The is not connected. /// /// /// The is not authenticated. /// /// /// The POP3 server does not support the UIDL extension. /// /// /// The operation was canceled via the cancellation token. /// /// /// An I/O error occurred. /// /// /// The POP3 command failed. /// /// /// A POP3 protocol error occurred. /// public override Task> GetMessagesAsync (int startIndex, int count, CancellationToken cancellationToken = default (CancellationToken), ITransferProgress progress = null) { CheckDisposed (); CheckConnected (); CheckAuthenticated (); if (startIndex < 0 || startIndex >= total) throw new ArgumentOutOfRangeException (nameof (startIndex)); if (count < 0 || count > (total - startIndex)) throw new ArgumentOutOfRangeException (nameof (count)); if (count == 0) return Task.FromResult ((IList) new MimeMessage[0]); var seqids = new int[count]; for (int i = 0; i < count; i++) seqids[i] = startIndex + i + 1; var ctx = new DownloadMessageContext (this, parser, progress); return ctx.DownloadAsync (seqids, false, true, cancellationToken); } /// /// Asynchronously get the message or header stream at the specified index. /// /// /// Gets the message or header stream at the specified index. /// /// The message or header stream. /// The index of the message. /// true if only the headers should be retrieved; otherwise, false. /// The cancellation token. /// The progress reporting mechanism. /// /// is not a valid message index. /// /// /// The has been disposed. /// /// /// The is not connected. /// /// /// The is not authenticated. /// /// /// The operation was canceled via the cancellation token. /// /// /// An I/O error occurred. /// /// /// The POP3 command failed. /// /// /// A POP3 protocol error occurred. /// public override Task GetStreamAsync (int index, bool headersOnly = false, CancellationToken cancellationToken = default (CancellationToken), ITransferProgress progress = null) { CheckDisposed (); CheckConnected (); CheckAuthenticated (); if (index < 0 || index >= total) throw new ArgumentOutOfRangeException (nameof (index)); var ctx = new DownloadStreamContext (this, progress); return ctx.DownloadAsync (index + 1, headersOnly, true, cancellationToken); } /// /// Asynchronously get the message or header streams at the specified indexes. /// /// /// Get the message or header streams at the specified indexes. /// If the POP3 server supports the /// extension, this method will likely be more efficient than using /// for each message /// because it will batch the commands to reduce latency. /// /// The message or header streams. /// The indexes of the messages. /// true if only the headers should be retrieved; otherwise, false. /// The cancellation token. /// The progress reporting mechanism. /// /// is null. /// /// /// One or more of the are invalid. /// /// /// The has been disposed. /// /// /// The is not connected. /// /// /// The is not authenticated. /// /// /// The POP3 server does not support the UIDL extension. /// /// /// The operation was canceled via the cancellation token. /// /// /// An I/O error occurred. /// /// /// The POP3 command failed. /// /// /// A POP3 protocol error occurred. /// public override Task> GetStreamsAsync (IList indexes, bool headersOnly = false, CancellationToken cancellationToken = default (CancellationToken), ITransferProgress progress = null) { CheckDisposed (); CheckConnected (); CheckAuthenticated (); if (indexes == null) throw new ArgumentNullException (nameof (indexes)); if (indexes.Count == 0) return Task.FromResult ((IList) new Stream[0]); var seqids = new int[indexes.Count]; for (int i = 0; i < indexes.Count; i++) { if (indexes[i] < 0 || indexes[i] >= total) throw new ArgumentException ("One or more of the indexes are invalid.", nameof (indexes)); seqids[i] = indexes[i] + 1; } var ctx = new DownloadStreamContext (this, progress); return ctx.DownloadAsync (seqids, headersOnly, true, cancellationToken); } /// /// Asynchronously get the message or header streams within the specified range. /// /// /// Gets the message or header streams within the specified range. /// If the POP3 server supports the /// extension, this method will likely be more efficient than using /// for each message /// because it will batch the commands to reduce latency. /// /// The message or header streams. /// The index of the first stream to get. /// The number of streams to get. /// true if only the headers should be retrieved; otherwise, false. /// The cancellation token. /// The progress reporting mechanism. /// /// and do not specify /// a valid range of messages. /// /// /// The has been disposed. /// /// /// The is not connected. /// /// /// The is not authenticated. /// /// /// The POP3 server does not support the UIDL extension. /// /// /// The operation was canceled via the cancellation token. /// /// /// An I/O error occurred. /// /// /// The POP3 command failed. /// /// /// A POP3 protocol error occurred. /// public override Task> GetStreamsAsync (int startIndex, int count, bool headersOnly = false, CancellationToken cancellationToken = default (CancellationToken), ITransferProgress progress = null) { CheckDisposed (); CheckConnected (); CheckAuthenticated (); if (startIndex < 0 || startIndex >= total) throw new ArgumentOutOfRangeException (nameof (startIndex)); if (count < 0 || count > (total - startIndex)) throw new ArgumentOutOfRangeException (nameof (count)); if (count == 0) return Task.FromResult ((IList) new Stream[0]); var seqids = new int[count]; for (int i = 0; i < count; i++) seqids[i] = startIndex + i + 1; var ctx = new DownloadStreamContext (this, progress); return ctx.DownloadAsync (seqids, headersOnly, true, cancellationToken); } /// /// Asynchronously mark the specified message for deletion. /// /// /// Messages marked for deletion are not actually deleted until the session /// is cleanly disconnected /// (see ). /// /// /// /// /// An asynchronous task context. /// The index of the message. /// The cancellation token. /// /// is not a valid message index. /// /// /// The has been disposed. /// /// /// The is not connected. /// /// /// The is not authenticated. /// /// /// The operation was canceled via the cancellation token. /// /// /// An I/O error occurred. /// /// /// The POP3 command failed. /// /// /// A POP3 protocol error occurred. /// public override Task DeleteMessageAsync (int index, CancellationToken cancellationToken = default (CancellationToken)) { return DeleteMessageAsync (index, true, cancellationToken); } /// /// Asynchronously mark the specified messages for deletion. /// /// /// Messages marked for deletion are not actually deleted until the session /// is cleanly disconnected /// (see ). /// /// An asynchronous task context. /// The indexes of the messages. /// The cancellation token. /// /// is null. /// /// /// One or more of the are invalid. /// /// /// The has been disposed. /// /// /// The is not connected. /// /// /// The is not authenticated. /// /// /// The operation was canceled via the cancellation token. /// /// /// An I/O error occurred. /// /// /// The POP3 command failed. /// /// /// A POP3 protocol error occurred. /// public override Task DeleteMessagesAsync (IList indexes, CancellationToken cancellationToken = default (CancellationToken)) { return DeleteMessagesAsync (indexes, true, cancellationToken); } /// /// Asynchronously mark the specified range of messages for deletion. /// /// /// Messages marked for deletion are not actually deleted until the session /// is cleanly disconnected /// (see ). /// /// /// /// /// An asynchronous task context. /// The index of the first message to mark for deletion. /// The number of messages to mark for deletion. /// The cancellation token. /// /// and do not specify /// a valid range of messages. /// /// /// The has been disposed. /// /// /// The is not connected. /// /// /// The is not authenticated. /// /// /// The operation was canceled via the cancellation token. /// /// /// An I/O error occurred. /// /// /// The POP3 command failed. /// /// /// A POP3 protocol error occurred. /// public override Task DeleteMessagesAsync (int startIndex, int count, CancellationToken cancellationToken = default (CancellationToken)) { return DeleteMessagesAsync (startIndex, count, true, cancellationToken); } /// /// Asynchronously mark all messages for deletion. /// /// /// Messages marked for deletion are not actually deleted until the session /// is cleanly disconnected /// (see ). /// /// An asynchronous task context. /// The cancellation token. /// /// The has been disposed. /// /// /// The is not connected. /// /// /// The is not authenticated. /// /// /// The operation was canceled via the cancellation token. /// /// /// An I/O error occurred. /// /// /// The POP3 command failed. /// /// /// A POP3 protocol error occurred. /// public override async Task DeleteAllMessagesAsync (CancellationToken cancellationToken = default (CancellationToken)) { if (total > 0) await DeleteMessagesAsync (0, total, cancellationToken).ConfigureAwait (false); } /// /// Asynchronously reset the state of all messages marked for deletion. /// /// /// Messages marked for deletion are not actually deleted until the session /// is cleanly disconnected /// (see ). /// /// An awaitable task. /// The cancellation token. /// /// The has been disposed. /// /// /// The is not connected. /// /// /// The is not authenticated. /// /// /// The operation was canceled via the cancellation token. /// /// /// An I/O error occurred. /// /// /// The POP3 command failed. /// /// /// A POP3 protocol error occurred. /// public override Task ResetAsync (CancellationToken cancellationToken = default (CancellationToken)) { return ResetAsync (true, cancellationToken); } } }