Skip to content

Commit

Permalink
Refactored more IMAP untagged response handlers to split sync/async
Browse files Browse the repository at this point in the history
  • Loading branch information
jstedfast committed Sep 10, 2023
1 parent 25c4add commit 95a602f
Show file tree
Hide file tree
Showing 7 changed files with 1,033 additions and 283 deletions.
6 changes: 3 additions & 3 deletions MailKit/Net/Imap/ImapClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,7 @@ ImapCommand QueueIdentifyCommand (ImapImplementation clientImplementation, Cance
}

var ic = new ImapCommand (engine, cancellationToken, null, command.ToString (), args.ToArray ());
ic.RegisterUntaggedHandler ("ID", ImapUtils.ParseImplementationAsync);
ic.RegisterUntaggedHandler ("ID", ImapUtils.UntaggedIdHandler);

engine.QueueCommand (ic);

Expand Down Expand Up @@ -2523,7 +2523,7 @@ ImapCommand QueueGetMetadataCommand (MetadataTag tag, CancellationToken cancella
throw new NotSupportedException ("The IMAP server does not support the METADATA extension.");

var ic = new ImapCommand (engine, cancellationToken, null, "GETMETADATA \"\" %S\r\n", tag.Id);
ic.RegisterUntaggedHandler ("METADATA", ImapUtils.ParseMetadataAsync);
ic.RegisterUntaggedHandler ("METADATA", ImapUtils.UntaggedMetadataHandler);
var metadata = new MetadataCollection ();
ic.UserData = metadata;

Expand Down Expand Up @@ -2648,7 +2648,7 @@ ImapCommand QueueGetMetadataCommand (MetadataOptions options, IEnumerable<Metada
return null;

var ic = new ImapCommand (engine, cancellationToken, null, command.ToString (), args.ToArray ());
ic.RegisterUntaggedHandler ("METADATA", ImapUtils.ParseMetadataAsync);
ic.RegisterUntaggedHandler ("METADATA", ImapUtils.UntaggedMetadataHandler);
ic.UserData = new MetadataCollection ();
options.LongEntries = 0;

Expand Down
74 changes: 60 additions & 14 deletions MailKit/Net/Imap/ImapEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -981,6 +981,52 @@ public ValueTask<ImapToken> ReadTokenAsync (CancellationToken cancellationToken)
return Stream.ReadTokenAsync (cancellationToken);
}

/// <summary>
/// Reads the next token.
/// </summary>
/// <returns>The token.</returns>
/// <param name="specials">A list of characters that are not legal in bare string tokens.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <exception cref="System.InvalidOperationException">
/// The engine is not connected.
/// </exception>
/// <exception cref="System.OperationCanceledException">
/// The operation was canceled via the cancellation token.
/// </exception>
/// <exception cref="System.IO.IOException">
/// An I/O error occurred.
/// </exception>
/// <exception cref="ImapProtocolException">
/// An IMAP protocol error occurred.
/// </exception>
public ImapToken ReadToken (string specials, CancellationToken cancellationToken)
{
return Stream.ReadToken (specials, cancellationToken);
}

/// <summary>
/// Asynchronously reads the next token.
/// </summary>
/// <returns>The token.</returns>
/// <param name="specials">A list of characters that are not legal in bare string tokens.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <exception cref="System.InvalidOperationException">
/// The engine is not connected.
/// </exception>
/// <exception cref="System.OperationCanceledException">
/// The operation was canceled via the cancellation token.
/// </exception>
/// <exception cref="System.IO.IOException">
/// An I/O error occurred.
/// </exception>
/// <exception cref="ImapProtocolException">
/// An IMAP protocol error occurred.
/// </exception>
public ValueTask<ImapToken> ReadTokenAsync (string specials, CancellationToken cancellationToken)
{
return Stream.ReadTokenAsync (specials, cancellationToken);
}

/// <summary>
/// Peeks at the next token.
/// </summary>
Expand Down Expand Up @@ -2319,7 +2365,7 @@ internal void ProcessUntaggedResponse (CancellationToken cancellationToken)
//if (number == 0)
// throw UnexpectedToken ("Syntax error in untagged FETCH response. Unexpected message index: 0");

folder.OnFetchAsync (this, (int) number - 1, doAsync: false, cancellationToken).GetAwaiter ().GetResult ();
folder.OnUntaggedFetchResponse (this, (int) number - 1, doAsync: false, cancellationToken).GetAwaiter ().GetResult ();
} else if (atom.Equals ("RECENT", StringComparison.OrdinalIgnoreCase)) {
folder.OnRecent ((int) number);
} else {
Expand All @@ -2336,13 +2382,13 @@ internal void ProcessUntaggedResponse (CancellationToken cancellationToken)
SkipLine (cancellationToken);
} else if (atom.Equals ("LIST", StringComparison.OrdinalIgnoreCase)) {
// unsolicited LIST response - probably due to NOTIFY MailboxName or MailboxSubscribe event
ImapUtils.ParseFolderListAsync (this, null, false, true, doAsync: false, cancellationToken).GetAwaiter ().GetResult ();
ImapUtils.ParseFolderList (this, null, false, true, cancellationToken);
token = ReadToken (cancellationToken);
AssertToken (token, ImapTokenType.Eoln, "Syntax error in untagged LIST response. {0}", token);
} else if (atom.Equals ("METADATA", StringComparison.OrdinalIgnoreCase)) {
// unsolicited METADATA response - probably due to NOTIFY MailboxMetadataChange or ServerMetadataChange
var metadata = new MetadataCollection ();
ImapUtils.ParseMetadataAsync (this, metadata, doAsync: false, cancellationToken).GetAwaiter ().GetResult ();
ImapUtils.ParseMetadata (this, metadata, cancellationToken);
ProcessMetadataChanges (metadata);

token = ReadToken (cancellationToken);
Expand Down Expand Up @@ -2472,7 +2518,7 @@ internal async Task ProcessUntaggedResponseAsync (CancellationToken cancellation
//if (number == 0)
// throw UnexpectedToken ("Syntax error in untagged FETCH response. Unexpected message index: 0");

await folder.OnFetchAsync (this, (int) number - 1, doAsync: true, cancellationToken).ConfigureAwait (false);
await folder.OnUntaggedFetchResponse (this, (int) number - 1, doAsync: true, cancellationToken).ConfigureAwait (false);
} else if (atom.Equals ("RECENT", StringComparison.OrdinalIgnoreCase)) {
folder.OnRecent ((int) number);
} else {
Expand All @@ -2489,13 +2535,13 @@ internal async Task ProcessUntaggedResponseAsync (CancellationToken cancellation
await SkipLineAsync (cancellationToken).ConfigureAwait (false);
} else if (atom.Equals ("LIST", StringComparison.OrdinalIgnoreCase)) {
// unsolicited LIST response - probably due to NOTIFY MailboxName or MailboxSubscribe event
await ImapUtils.ParseFolderListAsync (this, null, false, true, doAsync: true, cancellationToken).ConfigureAwait (false);
await ImapUtils.ParseFolderListAsync (this, null, false, true, cancellationToken).ConfigureAwait (false);
token = await ReadTokenAsync (cancellationToken).ConfigureAwait (false);
AssertToken (token, ImapTokenType.Eoln, "Syntax error in untagged LIST response. {0}", token);
} else if (atom.Equals ("METADATA", StringComparison.OrdinalIgnoreCase)) {
// unsolicited METADATA response - probably due to NOTIFY MailboxMetadataChange or ServerMetadataChange
var metadata = new MetadataCollection ();
await ImapUtils.ParseMetadataAsync (this, metadata, doAsync: true, cancellationToken).ConfigureAwait (false);
await ImapUtils.ParseMetadataAsync (this, metadata, cancellationToken).ConfigureAwait (false);
ProcessMetadataChanges (metadata);

token = await ReadTokenAsync (cancellationToken).ConfigureAwait (false);
Expand Down Expand Up @@ -2861,7 +2907,7 @@ ImapCommand QueueLookupParentFolderCommand (string encodedName, CancellationToke
command.Append ("\r\n");

var ic = new ImapCommand (this, cancellationToken, null, command.ToString (), pattern);
ic.RegisterUntaggedHandler ("LIST", ImapUtils.ParseFolderListAsync);
ic.RegisterUntaggedHandler ("LIST", ImapUtils.UntaggedListHandler);
ic.ListReturnsSubscribed = returnsSubscribed;
ic.UserData = new List<ImapFolder> ();

Expand Down Expand Up @@ -2957,7 +3003,7 @@ void ProcessNamespaceResponse (ImapCommand ic)
ImapCommand QueueListNamespaceCommand (List<ImapFolder> list, CancellationToken cancellationToken)
{
var ic = new ImapCommand (this, cancellationToken, null, "LIST \"\" \"\"\r\n");
ic.RegisterUntaggedHandler ("LIST", ImapUtils.ParseFolderListAsync);
ic.RegisterUntaggedHandler ("LIST", ImapUtils.UntaggedListHandler);
ic.UserData = list;

QueueCommand (ic);
Expand Down Expand Up @@ -3109,7 +3155,7 @@ ImapCommand QueueListInboxCommand (CancellationToken cancellationToken, out Stri
command.Append ("\r\n");

var ic = new ImapCommand (this, cancellationToken, null, command.ToString ());
ic.RegisterUntaggedHandler ("LIST", ImapUtils.ParseFolderListAsync);
ic.RegisterUntaggedHandler ("LIST", ImapUtils.UntaggedListHandler);
ic.ListReturnsSubscribed = returnsSubscribed;
ic.UserData = list;

Expand Down Expand Up @@ -3150,7 +3196,7 @@ ImapCommand QueueListSpecialUseCommand (StringBuilder command, List<ImapFolder>
command.Append ("\r\n");

var ic = new ImapCommand (this, cancellationToken, null, command.ToString ());
ic.RegisterUntaggedHandler ("LIST", ImapUtils.ParseFolderListAsync);
ic.RegisterUntaggedHandler ("LIST", ImapUtils.UntaggedListHandler);
ic.ListReturnsSubscribed = returnsSubscribed;
ic.UserData = list;

Expand All @@ -3162,7 +3208,7 @@ ImapCommand QueueListSpecialUseCommand (StringBuilder command, List<ImapFolder>
ImapCommand QueueXListCommand (List<ImapFolder> list, CancellationToken cancellationToken)
{
var ic = new ImapCommand (this, cancellationToken, null, "XLIST \"\" \"*\"\r\n");
ic.RegisterUntaggedHandler ("XLIST", ImapUtils.ParseFolderListAsync);
ic.RegisterUntaggedHandler ("XLIST", ImapUtils.UntaggedListHandler);
ic.UserData = list;

QueueCommand (ic);
Expand Down Expand Up @@ -3256,7 +3302,7 @@ public async Task<ImapFolder> GetQuotaRootFolderAsync (string quotaRoot, bool do
command.Append ("\r\n");

var ic = new ImapCommand (this, cancellationToken, null, command.ToString (), quotaRoot);
ic.RegisterUntaggedHandler ("LIST", ImapUtils.ParseFolderListAsync);
ic.RegisterUntaggedHandler ("LIST", ImapUtils.UntaggedListHandler);
ic.ListReturnsSubscribed = returnsSubscribed;
ic.UserData = list;

Expand Down Expand Up @@ -3292,7 +3338,7 @@ ImapCommand QueueGetFolderCommand (string encodedName, CancellationToken cancell
command.Append ("\r\n");

var ic = new ImapCommand (this, cancellationToken, null, command.ToString (), encodedName);
ic.RegisterUntaggedHandler ("LIST", ImapUtils.ParseFolderListAsync);
ic.RegisterUntaggedHandler ("LIST", ImapUtils.UntaggedListHandler);
ic.ListReturnsSubscribed = returnsSubscribed;
ic.UserData = list;

Expand Down Expand Up @@ -3462,7 +3508,7 @@ ImapCommand QueueGetFoldersCommand (FolderNamespace @namespace, StatusItems item
command.Append ("\r\n");

var ic = new ImapCommand (this, cancellationToken, null, command.ToString (), pattern + "*");
ic.RegisterUntaggedHandler (lsub ? "LSUB" : "LIST", ImapUtils.ParseFolderListAsync);
ic.RegisterUntaggedHandler (lsub ? "LSUB" : "LIST", ImapUtils.UntaggedListHandler);
ic.ListReturnsSubscribed = returnsSubscribed;
ic.UserData = list;
ic.Lsub = lsub;
Expand Down
Loading

0 comments on commit 95a602f

Please sign in to comment.