Reworked IMAP setup flow. Implemented easy way to share protocol log on failure if possible.
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MailKit;
|
||||
using MailKit.Net.Imap;
|
||||
using MailKit.Net.Proxy;
|
||||
using MailKit.Security;
|
||||
@@ -20,7 +23,7 @@ namespace Wino.Core.Integration
|
||||
/// TODO: Listens to the Inbox folder for new messages.
|
||||
/// </summary>
|
||||
/// <param name="customServerInformation">Connection/Authentication info to be used to configure ImapClient.</param>
|
||||
public class ImapClientPool
|
||||
public class ImapClientPool : IDisposable
|
||||
{
|
||||
// Hardcoded implementation details for ID extension if the server supports.
|
||||
// Some providers like Chinese 126 require Id to be sent before authentication.
|
||||
@@ -40,11 +43,13 @@ namespace Wino.Core.Integration
|
||||
private readonly ConcurrentBag<ImapClient> _clients = [];
|
||||
private readonly SemaphoreSlim _semaphore = new(MaxPoolSize);
|
||||
private readonly CustomServerInformation _customServerInformation;
|
||||
private readonly Stream _protocolLogStream;
|
||||
private readonly ILogger _logger = Log.ForContext<ImapClientPool>();
|
||||
|
||||
public ImapClientPool(CustomServerInformation customServerInformation)
|
||||
public ImapClientPool(CustomServerInformation customServerInformation, Stream protocolLogStream = null)
|
||||
{
|
||||
_customServerInformation = customServerInformation;
|
||||
_protocolLogStream = protocolLogStream;
|
||||
}
|
||||
|
||||
private async Task EnsureConnectivityAsync(ImapClient client, bool isCreatedNew)
|
||||
@@ -75,7 +80,7 @@ namespace Wino.Core.Integration
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new ImapClientPoolException(ex);
|
||||
throw new ImapClientPoolException(ex, GetProtocolLogContent());
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -84,6 +89,18 @@ namespace Wino.Core.Integration
|
||||
}
|
||||
}
|
||||
|
||||
public string GetProtocolLogContent()
|
||||
{
|
||||
if (_protocolLogStream == null) return default;
|
||||
|
||||
// Set the position to the beginning of the stream in case it is not already at the start
|
||||
if (_protocolLogStream.CanSeek)
|
||||
_protocolLogStream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
using var reader = new StreamReader(_protocolLogStream, Encoding.UTF8, true, 1024, leaveOpen: true);
|
||||
return reader.ReadToEnd();
|
||||
}
|
||||
|
||||
public async Task<ImapClient> GetClientAsync()
|
||||
{
|
||||
await _semaphore.WaitAsync();
|
||||
@@ -113,7 +130,17 @@ namespace Wino.Core.Integration
|
||||
|
||||
public ImapClient CreateNewClient()
|
||||
{
|
||||
var client = new ImapClient();
|
||||
ImapClient client = null;
|
||||
|
||||
// Make sure to create a ImapClient with a protocol logger if enabled.
|
||||
if (_protocolLogStream != null)
|
||||
{
|
||||
client = new ImapClient(new ProtocolLogger(_protocolLogStream));
|
||||
}
|
||||
else
|
||||
{
|
||||
client = new ImapClient();
|
||||
}
|
||||
|
||||
HttpProxyClient proxyClient = null;
|
||||
|
||||
@@ -175,5 +202,20 @@ namespace Wino.Core.Integration
|
||||
|
||||
await client.AuthenticateAsync(_customServerInformation.IncomingServerUsername, _customServerInformation.IncomingServerPassword);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
foreach (var client in _clients)
|
||||
{
|
||||
client.Disconnect(true);
|
||||
client.Dispose();
|
||||
}
|
||||
|
||||
if (_protocolLogStream != null)
|
||||
{
|
||||
_protocolLogStream.Flush();
|
||||
_protocolLogStream.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user