-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Send QUIT on SmtpClient.Dispose() #683
Conversation
It is related to |
How does this handle the case when SmtpClient is in the middle of sending the Body when DIspose is called (as mentioned in https://github.com/dotnet/corefx/issues/34868#issuecomment-523087400)? I assume this would corrupt the stream? |
Same as netfx https://referencesource.microsoft.com/#System/net/System/Net/mail/SmtpClient.cs,967 |
/azp run |
Azure Pipelines successfully started running 10 pipeline(s). |
See latest discussion on https://github.com/dotnet/corefx/issues/34868. We might end up adding a new API for SmtpClient instead of trying to force the 'QUIT' in Dispose(). |
Based on latest discussion, I'm fine with the design approach in this PR for implementing QUIT in Dispose(). |
src/libraries/System.Net.Mail/src/System/Net/Mail/SmtpCommands.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Mail/src/System/Net/Mail/SmtpConnection.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Mail/src/System/Net/Mail/SmtpConnection.cs
Outdated
Show resolved
Hide resolved
/azp list |
Commenter does not have sufficient privileges for PR 683 in repo dotnet/runtime |
/azp list |
Commenter does not have sufficient privileges for PR 683 in repo dotnet/runtime |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, small changes requested and then we'll find out why /azp isn't working for you.
src/libraries/System.Net.Mail/src/System/Net/Mail/SmtpCommands.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Mail/src/System/Net/Mail/SmtpCommands.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Mail/src/System/Net/Mail/SmtpCommands.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Mail/src/System/Net/Mail/SmtpConnection.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Mail/src/System/Net/Mail/SmtpConnection.cs
Outdated
Show resolved
Hide resolved
Would be great 😍 |
/azp run runtime-libraries outerloop |
Azure Pipelines successfully started running 1 pipeline(s). |
src/libraries/System.Net.Mail/src/System/Net/Mail/SmtpConnection.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Mail/src/System/Net/Mail/SmtpConnection.cs
Outdated
Show resolved
Hide resolved
_transport?.ReleaseConnection(); | ||
else | ||
{ | ||
_transport?.ReleaseConnection(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@scalablecory @tmds in this way the path should be clear, if we're incall we'll abort without quit otherwise cleanup with quit.
@@ -160,7 +160,7 @@ private void ShutdownConnection(bool isAbort) | |||
} | |||
} | |||
catch (IOException) { } | |||
catch (InvalidOperationException) | |||
catch (ObjectDisposedException) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@scalablecory @tmat I added ObjectDisposedException
because we throw InvalidOperationException
from quit command and we could hide a bug.
IOException
for possible network failure.
/azp list |
Commenter does not have sufficient privileges for PR 683 in repo dotnet/runtime |
/azp list |
/azp run runtime-libraries outerloop |
Azure Pipelines successfully started running 1 pipeline(s). |
@MarcoRossignoli I think this PR is close to being merged. But there is a conflict now. Can you please re-base this PR against current 'master'? |
Will do asap |
@davidsh rebased! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR!
@scalablecory Can you confirm that your requested changes/feedback was addressed? If so, please approve PR. Thx. |
/azp run runtime-libraries outerloop |
Azure Pipelines successfully started running 1 pipeline(s). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me. Thanks for the PR.
Fixes https://github.com/dotnet/corefx/issues/34868
When code was ported
SmtpConnection
pooling present on old code base was removed but seem that semantic wasn't correctly updated.On netfx code base the call to
ReleaseConnection()
ends to place where the connection is cached for future use(creation callback)When we call
SmtpClient.Dispose()
we end calling pool manager cleanup that calls real dispose on pooled stream with the result of send QUIT message on all opened network streamOn core this mechanism is not present, so until today every
ReleaseConnection()
called after send messages closes socket/stream violating RFC https://tools.ietf.org/html/rfc5321#section-4.1.1.10If users forget to dispose network stream will be closed in a "bad" way(like today) by finalizer
I didn't found any finalizer on pool on netfx code base, btw it's a bit hard navigate without "Go to" vs feature(it doesn't work), so I could have missed some place where
PooledStream
are released thank's to some finalizer.However the guide is clear
Sends a QUIT message to the SMTP server, gracefully ends the TCP connection, and releases all resources used by the current instance of the SmtpClient class.
so we should always call Dispose()(missing in the main example https://docs.microsoft.com/en-us/dotnet/api/system.net.mail.smtpclient?view=netframework-4.8#examples).cc: @davidsh @wfurt
Bonus: during test I found that if we call 2 time one after another async send, test hang, I don't know if it's related to
LoopbackSmtpServer
, this issue it's not related to this PR the behaviour is already present.