Mark Sapiro pushed to branch master at GNU Mailman / Mailman Core
Commits:
00ea75ea by Mark Sapiro at 2019-01-12T18:52:31Z
Outgoing delivery closes the smtp connection after each message.
- - - - -
25e22287 by Mark Sapiro at 2019-01-12T20:09:15Z
Merge branch 'smtp_quit' into 'master'
Outgoing delivery closes the smtp connection after each message.
Closes #529
See merge request mailman/mailman!432
- - - - -
4 changed files:
- src/mailman/docs/NEWS.rst
- src/mailman/mta/deliver.py
- src/mailman/mta/tests/test_connection.py
- src/mailman/mta/tests/test_delivery.py
Changes:
=====================================
src/mailman/docs/NEWS.rst
=====================================
@@ -29,6 +29,8 @@ Bugs
(Closes #504)
* Message parts are now properly decoded when trying to remove an Approved:
header. (Closes #518)
+* Outgoing SMTP connections are now closed following message delivery
+ regardless of the max_sessions_per_connection setting. (Closes #529)
REST
----
=====================================
src/mailman/mta/deliver.py
=====================================
@@ -84,6 +84,15 @@ def deliver(mlist, msg, msgdata):
# for re-delivery later.
t0 = time.time()
refused = agent.deliver(mlist, msg, msgdata)
+ # At this point we have completed the initial SMTP for this message.
+ # We should close the SMTP connection regardless of the
+ # sessions_per_connection setting because otherwise if there are no more
+ # messages in the queue, the connection is left open until it times out
+ # which can cause problems in the MTA.
+ # XXX It would arguably be better to close only if the queue is empty, but
+ # this means examining the queue here or closing from the outgoing runner,
+ # either of which requires more information than should be available.
+ agent._connection.quit()
t1 = time.time()
# Log this posting.
size = getattr(msg, 'original_size', msgdata.get('original_size'))
=====================================
src/mailman/mta/tests/test_connection.py
=====================================
@@ -90,6 +90,14 @@ Subject: aardvarks
self.connection.quit()
self.assertEqual(SMTPLayer.smtpd.get_connection_count(), 2)
+ def test_count_2_no_quit(self):
+ self.connection.sendmail(
+ '[email protected]', ['[email protected]'], self.msg_text)
+ self.connection.sendmail(
+ '[email protected]', ['[email protected]'], self.msg_text)
+ self.connection.quit()
+ self.assertEqual(SMTPLayer.smtpd.get_connection_count(), 1)
+
def test_count_reset(self):
self.connection.sendmail(
'[email protected]', ['[email protected]'], self.msg_text)
=====================================
src/mailman/mta/tests/test_delivery.py
=====================================
@@ -30,7 +30,8 @@ from mailman.mta.bulk import BulkDelivery
from mailman.mta.deliver import Deliver
from mailman.testing.helpers import (
specialized_message_from_string as mfs, subscribe)
-from mailman.testing.layers import ConfigLayer
+from mailman.testing.layers import ConfigLayer, SMTPLayer
+from mailman.utilities.modules import find_name
from zope.component import getUtility
@@ -200,3 +201,61 @@ list: Test
Footer
""")
+
+
+class TestCloseAfterDelivery(unittest.TestCase):
+ """Test that connections close after delivery."""
+
+ layer = SMTPLayer
+
+ def setUp(self):
+ self._mlist = create_list('[email protected]')
+ # Set personalized delivery.
+ self._mlist.personalize = Personalization.individual
+ # Make Anne a member of this mailing list.
+ self._anne = subscribe(self._mlist, 'Anne', email='[email protected]')
+ self._msg = mfs("""\
+From: [email protected]
+To: [email protected]
+Subject: test
+
+""")
+ self._deliverer = find_name(config.mta.outgoing)
+ # Set the maximum transactions per connection.
+ config.push('maxtrans', """
+ [mta]
+ max_sessions_per_connection: 3
+ """)
+ self.addCleanup(config.pop, 'maxtrans')
+
+ def test_two_messages(self):
+ msgdata = dict(recipients=['[email protected]'])
+ # Send a message.
+ self._deliverer(self._mlist, self._msg, msgdata)
+ # We should have made one SMTP connection.
+ self.assertEqual(SMTPLayer.smtpd.get_connection_count(), 1)
+ # Send a second message.
+ msgdata = dict(recipients=['[email protected]'])
+ self._deliverer(self._mlist, self._msg, msgdata)
+ # This should result in a second connection.
+ self.assertEqual(SMTPLayer.smtpd.get_connection_count(), 2)
+
+ def test_one_message_two_recip(self):
+ msgdata = dict(recipients=['[email protected]', '[email protected]'])
+ # Send the message.
+ self._deliverer(self._mlist, self._msg, msgdata)
+ # Sending to 2 recips sends 2 messages because of personalization.
+ # That's fewer than max_sessions_per_connection so there's only
+ # one connection.
+ self.assertEqual(SMTPLayer.smtpd.get_connection_count(), 1)
+
+ def test_one_message_four_recip(self):
+ msgdata = dict(recipients=['[email protected]',
+ '[email protected]',
+ '[email protected]',
+ '[email protected]'])
+ # Send the message.
+ self._deliverer(self._mlist, self._msg, msgdata)
+ # Since max_sessions_per_connection is 3, sending 4 personalized
+ # messages creates 2 connections.
+ self.assertEqual(SMTPLayer.smtpd.get_connection_count(), 2)
View it on GitLab:
https://gitlab.com/mailman/mailman/compare/1e9597487a199f8b69bb9cf5de33e14ae7ab444e...25e2228723e878ab1fba751db349ef363d213e65
--
View it on GitLab:
https://gitlab.com/mailman/mailman/compare/1e9597487a199f8b69bb9cf5de33e14ae7ab444e...25e2228723e878ab1fba751db349ef363d213e65
You're receiving this email because of your account on gitlab.com.
_______________________________________________
Mailman-checkins mailing list
[email protected]
Unsubscribe:
https://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org