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(
+            'a...@example.com', ['b...@example.com'], self.msg_text)
+        self.connection.sendmail(
+            'c...@example.com', ['d...@example.com'], self.msg_text)
+        self.connection.quit()
+        self.assertEqual(SMTPLayer.smtpd.get_connection_count(), 1)
+
     def test_count_reset(self):
         self.connection.sendmail(
             'a...@example.com', ['b...@example.com'], 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('t...@example.com')
+        # Set personalized delivery.
+        self._mlist.personalize = Personalization.individual
+        # Make Anne a member of this mailing list.
+        self._anne = subscribe(self._mlist, 'Anne', email='a...@example.org')
+        self._msg = mfs("""\
+From: a...@example.org
+To: t...@example.com
+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=['a...@example.org'])
+        # 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=['b...@example.org'])
+        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=['a...@example.org', 'b...@example.org'])
+        # 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=['a...@example.org',
+                                   'b...@example.org',
+                                   'c...@example.com',
+                                   'd...@example.com'])
+        # 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
Mailman-checkins@python.org
Unsubscribe: 
https://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org

Reply via email to