Skip to content

Commit 4c901d4

Browse files
committed
Code refacoring to reduce ! usage in Pop3/Imap/SmtpClient
1 parent dc03ffc commit 4c901d4

File tree

9 files changed

+111
-94
lines changed

9 files changed

+111
-94
lines changed

MailKit/MailKit.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<AssemblyTitle>MailKit</AssemblyTitle>
66
<VersionPrefix>4.15.0</VersionPrefix>
77
<Authors>Jeffrey Stedfast</Authors>
8-
<LangVersion>10</LangVersion>
8+
<LangVersion>12</LangVersion>
99
<TargetFrameworks>netstandard2.0;netstandard2.1;net462;net47;net48;net8.0;net10.0</TargetFrameworks>
1010
<GenerateDocumentationFile>true</GenerateDocumentationFile>
1111
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>

MailKit/Net/Imap/AsyncImapClient.cs

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -518,17 +518,17 @@ async Task PostConnectAsync (Stream stream, string host, int port, SecureSocketO
518518
ProtocolLogger.LogConnect (engine.Uri!);
519519
} catch {
520520
stream.Dispose ();
521-
secure = false;
522521
throw;
523522
}
524523

525524
connecting = true;
526525

526+
var imap = new ImapStream (stream, ProtocolLogger);
527+
527528
try {
528-
await engine.ConnectAsync (new ImapStream (stream, ProtocolLogger), cancellationToken).ConfigureAwait (false);
529+
await engine.ConnectAsync (imap, cancellationToken).ConfigureAwait (false);
529530
} catch {
530531
connecting = false;
531-
secure = false;
532532
throw;
533533
}
534534

@@ -548,14 +548,14 @@ async Task PostConnectAsync (Stream stream, string host, int port, SecureSocketO
548548
if (ic.Response == ImapCommandResponse.Ok) {
549549
try {
550550
var tls = new SslStream (stream, false, ValidateRemoteCertificate);
551-
engine.Stream!.Stream = tls;
551+
imap.Stream = tls;
552552

553553
await SslHandshakeAsync (tls, host, cancellationToken).ConfigureAwait (false);
554554
} catch (Exception ex) {
555555
throw SslHandshakeException.Create (ref sslValidationInfo, ex, true, "IMAP", host, port, 993, 143);
556556
}
557557

558-
secure = true;
558+
engine.IsSecure = true;
559559

560560
// Query the CAPABILITIES again if the server did not include an
561561
// untagged CAPABILITIES response to the STARTTLS command.
@@ -566,7 +566,6 @@ async Task PostConnectAsync (Stream stream, string host, int port, SecureSocketO
566566
}
567567
}
568568
} catch (Exception ex) {
569-
secure = false;
570569
engine.Disconnect (ex);
571570
throw;
572571
} finally {
@@ -673,10 +672,7 @@ public override async Task ConnectAsync (string host, int port = 0, SecureSocket
673672
throw SslHandshakeException.Create (ref sslValidationInfo, ex, false, "IMAP", host, port, 993, 143);
674673
}
675674

676-
secure = true;
677675
stream = ssl;
678-
} else {
679-
secure = false;
680676
}
681677

682678
await PostConnectAsync (stream, host, port, options, starttls, cancellationToken).ConfigureAwait (false);
@@ -846,10 +842,8 @@ public override async Task ConnectAsync (Stream stream, string host, int port =
846842
}
847843

848844
network = ssl;
849-
secure = true;
850845
} else {
851846
network = stream;
852-
secure = false;
853847
}
854848

855849
if (network.CanTimeout) {

MailKit/Net/Imap/ImapClient.cs

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ public partial class ImapClient : MailStore, IImapClient
7474
bool disconnecting;
7575
bool connecting;
7676
bool disposed;
77-
bool secure;
7877

7978
/// <summary>
8079
/// Initializes a new instance of the <see cref="MailKit.Net.Imap.ImapClient"/> class.
@@ -666,7 +665,7 @@ public override HashSet<ThreadingAlgorithm> ThreadingAlgorithms {
666665
public override int Timeout {
667666
get { return timeout; }
668667
set {
669-
if (IsConnected && engine.Stream!.CanTimeout) {
668+
if (engine.IsConnected && engine.Stream.CanTimeout) {
670669
engine.Stream.WriteTimeout = value;
671670
engine.Stream.ReadTimeout = value;
672671
}
@@ -701,7 +700,7 @@ public override bool IsConnected {
701700
/// </remarks>
702701
/// <value><see langword="true" /> if the connection is secure; otherwise, <see langword="false" />.</value>
703702
public override bool IsSecure {
704-
get { return IsConnected && secure; }
703+
get { return engine.IsSecure; }
705704
}
706705

707706
/// <summary>
@@ -712,7 +711,7 @@ public override bool IsSecure {
712711
/// </remarks>
713712
/// <value><see langword="true" /> if the connection is encrypted; otherwise, <see langword="false" />.</value>
714713
public override bool IsEncrypted {
715-
get { return IsSecure && (engine.Stream!.Stream is SslStream sslStream) && sslStream.IsEncrypted; }
714+
get { return engine.IsSecure && (engine.Stream.Stream is SslStream sslStream) && sslStream.IsEncrypted; }
716715
}
717716

718717
/// <summary>
@@ -723,7 +722,7 @@ public override bool IsEncrypted {
723722
/// </remarks>
724723
/// <value><see langword="true" /> if the connection is signed; otherwise, <see langword="false" />.</value>
725724
public override bool IsSigned {
726-
get { return IsSecure && (engine.Stream!.Stream is SslStream sslStream) && sslStream.IsSigned; }
725+
get { return engine.IsSecure && (engine.Stream.Stream is SslStream sslStream) && sslStream.IsSigned; }
727726
}
728727

729728
/// <summary>
@@ -738,7 +737,7 @@ public override bool IsSigned {
738737
/// <value>The negotiated SSL or TLS protocol version.</value>
739738
public override SslProtocols SslProtocol {
740739
get {
741-
if (IsSecure && (engine.Stream!.Stream is SslStream sslStream))
740+
if (engine.IsSecure && (engine.Stream.Stream is SslStream sslStream))
742741
return sslStream.SslProtocol;
743742

744743
return SslProtocols.None;
@@ -760,7 +759,7 @@ public override SslProtocols SslProtocol {
760759
#endif
761760
public override CipherAlgorithmType? SslCipherAlgorithm {
762761
get {
763-
if (IsSecure && (engine.Stream!.Stream is SslStream sslStream))
762+
if (engine.IsSecure && (engine.Stream.Stream is SslStream sslStream))
764763
return sslStream.CipherAlgorithm;
765764

766765
return null;
@@ -782,7 +781,7 @@ public override CipherAlgorithmType? SslCipherAlgorithm {
782781
#endif
783782
public override int? SslCipherStrength {
784783
get {
785-
if (IsSecure && (engine.Stream!.Stream is SslStream sslStream))
784+
if (engine.IsSecure && (engine.Stream.Stream is SslStream sslStream))
786785
return sslStream.CipherStrength;
787786

788787
return null;
@@ -799,7 +798,7 @@ public override int? SslCipherStrength {
799798
/// <value>The negotiated SSL or TLS cipher suite.</value>
800799
public override TlsCipherSuite? SslCipherSuite {
801800
get {
802-
if (IsSecure && (engine.Stream!.Stream is SslStream sslStream))
801+
if (engine.IsSecure && (engine.Stream.Stream is SslStream sslStream))
803802
return sslStream.NegotiatedCipherSuite;
804803

805804
return null;
@@ -822,7 +821,7 @@ public override TlsCipherSuite? SslCipherSuite {
822821
#endif
823822
public override HashAlgorithmType? SslHashAlgorithm {
824823
get {
825-
if (IsSecure && (engine.Stream!.Stream is SslStream sslStream))
824+
if (engine.IsSecure && (engine.Stream.Stream is SslStream sslStream))
826825
return sslStream.HashAlgorithm;
827826

828827
return null;
@@ -844,7 +843,7 @@ public override HashAlgorithmType? SslHashAlgorithm {
844843
#endif
845844
public override int? SslHashStrength {
846845
get {
847-
if (IsSecure && (engine.Stream!.Stream is SslStream sslStream))
846+
if (engine.IsSecure && (engine.Stream.Stream is SslStream sslStream))
848847
return sslStream.HashStrength;
849848

850849
return null;
@@ -866,7 +865,7 @@ public override int? SslHashStrength {
866865
#endif
867866
public override ExchangeAlgorithmType? SslKeyExchangeAlgorithm {
868867
get {
869-
if (IsSecure && (engine.Stream!.Stream is SslStream sslStream))
868+
if (engine.IsSecure && (engine.Stream.Stream is SslStream sslStream))
870869
return sslStream.KeyExchangeAlgorithm;
871870

872871
return null;
@@ -888,7 +887,7 @@ public override ExchangeAlgorithmType? SslKeyExchangeAlgorithm {
888887
#endif
889888
public override int? SslKeyExchangeStrength {
890889
get {
891-
if (IsSecure && (engine.Stream!.Stream is SslStream sslStream))
890+
if (engine.IsSecure && (engine.Stream.Stream is SslStream sslStream))
892891
return sslStream.KeyExchangeStrength;
893892

894893
return null;
@@ -1460,17 +1459,17 @@ void PostConnect (Stream stream, string host, int port, SecureSocketOptions opti
14601459
ProtocolLogger.LogConnect (engine.Uri!);
14611460
} catch {
14621461
stream.Dispose ();
1463-
secure = false;
14641462
throw;
14651463
}
14661464

14671465
connecting = true;
14681466

1467+
var imap = new ImapStream (stream, ProtocolLogger);
1468+
14691469
try {
1470-
engine.Connect (new ImapStream (stream, ProtocolLogger), cancellationToken);
1470+
engine.Connect (imap, cancellationToken);
14711471
} catch {
14721472
connecting = false;
1473-
secure = false;
14741473
throw;
14751474
}
14761475

@@ -1490,14 +1489,14 @@ void PostConnect (Stream stream, string host, int port, SecureSocketOptions opti
14901489
if (ic.Response == ImapCommandResponse.Ok) {
14911490
try {
14921491
var tls = new SslStream (stream, false, ValidateRemoteCertificate);
1493-
engine.Stream!.Stream = tls;
1492+
imap.Stream = tls;
14941493

14951494
SslHandshake (tls, host, cancellationToken);
14961495
} catch (Exception ex) {
14971496
throw SslHandshakeException.Create (ref sslValidationInfo, ex, true, "IMAP", host, port, 993, 143);
14981497
}
14991498

1500-
secure = true;
1499+
engine.IsSecure = true;
15011500

15021501
// Query the CAPABILITIES again if the server did not include an
15031502
// untagged CAPABILITIES response to the STARTTLS command.
@@ -1508,7 +1507,6 @@ void PostConnect (Stream stream, string host, int port, SecureSocketOptions opti
15081507
}
15091508
}
15101509
} catch (Exception ex) {
1511-
secure = false;
15121510
engine.Disconnect (ex);
15131511
throw;
15141512
} finally {
@@ -1611,10 +1609,7 @@ public override void Connect (string host, int port = 0, SecureSocketOptions opt
16111609
throw SslHandshakeException.Create (ref sslValidationInfo, ex, false, "IMAP", host, port, 993, 143);
16121610
}
16131611

1614-
secure = true;
16151612
stream = ssl;
1616-
} else {
1617-
secure = false;
16181613
}
16191614

16201615
PostConnect (stream, host, port, options, starttls, cancellationToken);
@@ -1795,10 +1790,8 @@ public override void Connect (Stream stream, string host, int port = 0, SecureSo
17951790
}
17961791

17971792
network = ssl;
1798-
secure = true;
17991793
} else {
18001794
network = stream;
1801-
secure = false;
18021795
}
18031796

18041797
if (network.CanTimeout) {
@@ -2810,7 +2803,6 @@ void OnEngineDisconnected (object? sender, EventArgs e)
28102803
var uri = engine.Uri;
28112804

28122805
disconnecting = false;
2813-
secure = false;
28142806

28152807
OnDisconnected (uri!.Host, uri.Port, GetSecureSocketOptions (uri), requested);
28162808
}

MailKit/Net/Imap/ImapEngine.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ class ImapEngine : IDisposable
163163
MimeParser? parser;
164164
internal int Tag;
165165
bool disposed;
166+
bool secure;
166167

167168
public ImapEngine (CreateImapFolderDelegate createImapFolderDelegate)
168169
{
@@ -395,10 +396,24 @@ public ImapEngineState State {
395396
/// Gets whether or not the engine is currently connected to a IMAP server.
396397
/// </remarks>
397398
/// <value><see langword="true" /> if the engine is connected; otherwise, <see langword="false" />.</value>
399+
[MemberNotNullWhen (true, nameof (Stream))]
398400
public bool IsConnected {
399401
get { return Stream != null && Stream.IsConnected; }
400402
}
401403

404+
/// <summary>
405+
/// Get whether or not the connection is secure (typically via SSL or TLS).
406+
/// </summary>
407+
/// <remarks>
408+
/// Gets whether or not the connection is secure (typically via SSL or TLS).
409+
/// </remarks>
410+
/// <value><see langword="true" /> if the connection is secure; otherwise, <see langword="false" />.</value>
411+
[MemberNotNullWhen (true, nameof (Stream))]
412+
public bool IsSecure {
413+
get { return IsConnected && secure; }
414+
set { secure = value; }
415+
}
416+
402417
/// <summary>
403418
/// Gets the personal folder namespaces.
404419
/// </summary>
@@ -633,6 +648,7 @@ public NetworkOperation StartNetworkOperation (NetworkOperationKind kind, Uri? u
633648
#endif
634649
}
635650

651+
[MemberNotNull (nameof (Stream))]
636652
void Initialize (ImapStream stream)
637653
{
638654
clientConnectedTimestamp = Stopwatch.GetTimestamp ();
@@ -645,6 +661,7 @@ void Initialize (ImapStream stream)
645661
SupportedContexts.Clear ();
646662
Rights.Clear ();
647663

664+
secure = stream.Stream is SslStream;
648665
State = ImapEngineState.Connecting;
649666
QuirksMode = ImapQuirksMode.None;
650667
SupportedCharsets.Add ("US-ASCII");
@@ -864,6 +881,8 @@ public void Disconnect (Exception? ex)
864881
Stream = null;
865882
}
866883

884+
secure = false;
885+
867886
if (State != ImapEngineState.Disconnected) {
868887
State = ImapEngineState.Disconnected;
869888
OnDisconnected ();

MailKit/Net/Pop3/AsyncPop3Client.cs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,6 @@ async Task PostConnectAsync (Stream stream, string host, int port, SecureSocketO
316316
ProtocolLogger.LogConnect (engine.Uri!);
317317
} catch {
318318
stream.Dispose ();
319-
secure = false;
320319
throw;
321320
}
322321

@@ -335,21 +334,20 @@ async Task PostConnectAsync (Stream stream, string host, int port, SecureSocketO
335334

336335
try {
337336
var tls = new SslStream (stream, false, ValidateRemoteCertificate);
338-
engine.Stream!.Stream = tls;
337+
pop3.Stream = tls;
339338

340339
await SslHandshakeAsync (tls, host, cancellationToken).ConfigureAwait (false);
341340
} catch (Exception ex) {
342341
throw SslHandshakeException.Create (ref sslValidationInfo, ex, true, "POP3", host, port, 995, 110);
343342
}
344343

345-
secure = true;
344+
engine.IsSecure = true;
346345

347346
// re-issue a CAPA command
348347
await engine.QueryCapabilitiesAsync (cancellationToken).ConfigureAwait (false);
349348
}
350349
} catch (Exception ex) {
351350
engine.Disconnect (ex);
352-
secure = false;
353351
throw;
354352
}
355353

@@ -448,10 +446,7 @@ public override async Task ConnectAsync (string host, int port = 0, SecureSocket
448446
throw SslHandshakeException.Create (ref sslValidationInfo, ex, false, "POP3", host, port, 995, 110);
449447
}
450448

451-
secure = true;
452449
stream = ssl;
453-
} else {
454-
secure = false;
455450
}
456451

457452
await PostConnectAsync (stream, host, port, options, starttls, cancellationToken).ConfigureAwait (false);
@@ -621,10 +616,8 @@ public override async Task ConnectAsync (Stream stream, string host, int port =
621616
}
622617

623618
network = ssl;
624-
secure = true;
625619
} else {
626620
network = stream;
627-
secure = false;
628621
}
629622

630623
if (network.CanTimeout) {

0 commit comments

Comments
 (0)