Skip to content


Subversion checkout URL

You can clone with
Download ZIP


Fix SMTP server behaviour to reset mail transaction state after sending message #351

merged 1 commit into from

3 participants


The RFC in fact does mandate that multiple messages may be sent on a connection without calling RSET or similar. For example, Gmail's outgoing SMTP servers try to do this.

Without this fix, the provided SMTP server will break when trying to reset multiple messages without RSET in between.


This pull request fails (merged 5c07d82 into 9473a1b).

@tmm1 tmm1 merged commit 3535f3a into eventmachine:master

1 check failed

Details default The Travis build failed
@sodabrew sodabrew referenced this pull request from a commit in sodabrew/eventmachine
@ibc ibc Fix SMTP server behaviour to reset mail transaction state after sendi…
…ng message (eventmachine#351).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
Showing with 9 additions and 6 deletions.
  1. +9 −6 lib/em/protocols/smtpserver.rb
15 lib/em/protocols/smtpserver.rb
@@ -506,11 +506,13 @@ def process_rcpt_to rcpt
# Since we clear the chunk array every time we submit it, the caller needs to be
# aware to do things like dup it if he wants to keep it around across calls.
- # DON'T reset the transaction upon disposition of the incoming message.
- # This means another DATA command can be accepted with the same sender and recipients.
- # If the client wants to reset, he can call RSET.
- # Not sure whether the standard requires a transaction-reset at this point, but it
- # appears not to.
+ # Resets the transaction upon disposition of the incoming message.
+ # RFC5321 says this about the MAIL FROM command:
+ # "This command tells the SMTP-receiver that a new mail transaction is
+ # starting and to reset all its state tables and buffers, including any
+ # recipients or mail data."
+ #
+ # Equivalent behaviour is implemented by resetting after a completed transaction.
# User-written code can return a Deferrable as a response from receive_message.
@@ -524,11 +526,12 @@ def process_data_line ln
succeeded = proc {
send_data "250 Message accepted\r\n"
+ reset_protocol_state
failed = proc {
send_data "550 Message rejected\r\n"
+ reset_protocol_state
d = receive_message
if d.respond_to?(:set_deferred_status)
Something went wrong with that request. Please try again.