summaryrefslogtreecommitdiff
path: root/src/mailman/bouncers
diff options
context:
space:
mode:
authorBarry Warsaw2011-04-27 21:34:28 -0400
committerBarry Warsaw2011-04-27 21:34:28 -0400
commitdbe88c1d0a08999c5209b3a1bc70c458dbe270b4 (patch)
tree3a2b6f6cd1e4688089cff14841044947a8eb102b /src/mailman/bouncers
parent7181a4d6638605595b043f66eb3cd01dd93a0ff2 (diff)
downloadmailman-dbe88c1d0a08999c5209b3a1bc70c458dbe270b4.tar.gz
mailman-dbe88c1d0a08999c5209b3a1bc70c458dbe270b4.tar.zst
mailman-dbe88c1d0a08999c5209b3a1bc70c458dbe270b4.zip
Remove the redundant src/mailman/tests/test_bounces.py file and ensure all the
other bounce detector pass.
Diffstat (limited to 'src/mailman/bouncers')
-rw-r--r--src/mailman/bouncers/dsn.py54
-rw-r--r--src/mailman/bouncers/llnl.py2
-rw-r--r--src/mailman/bouncers/qmail.py5
-rw-r--r--src/mailman/bouncers/simplewarning.py12
4 files changed, 47 insertions, 26 deletions
diff --git a/src/mailman/bouncers/dsn.py b/src/mailman/bouncers/dsn.py
index 7b3021939..49803ef88 100644
--- a/src/mailman/bouncers/dsn.py
+++ b/src/mailman/bouncers/dsn.py
@@ -33,13 +33,14 @@ from email.iterators import typed_subpart_iterator
from email.utils import parseaddr
from zope.interface import implements
-from mailman.interfaces.bounce import BounceStatus, IBounceDetector
+from mailman.interfaces.bounce import IBounceDetector, Stop
def check(msg):
# Iterate over each message/delivery-status subpart.
- addresses = []
+ failed_addresses = []
+ delayed_addresses = []
for part in typed_subpart_iterator(msg, 'message', 'delivery-status'):
if not part.is_multipart():
# Huh?
@@ -47,6 +48,7 @@ def check(msg):
# Each message/delivery-status contains a list of Message objects
# which are the header blocks. Iterate over those too.
for msgblock in part.get_payload():
+ address_set = None
# We try to dig out the Original-Recipient (which is optional) and
# Final-Recipient (which is mandatory, but may not exactly match
# an address on our list). Some MTA's also use X-Actual-Recipient
@@ -57,8 +59,10 @@ def check(msg):
action = msgblock.get('action', '').lower()
# Some MTAs have been observed that put comments on the action.
if action.startswith('delayed'):
- return BounceStatus.non_fatal
- if not action.startswith('fail'):
+ address_set = delayed_addresses
+ elif action.startswith('fail'):
+ address_set = failed_addresses
+ else:
# Some non-permanent failure, so ignore this block.
continue
params = []
@@ -71,7 +75,7 @@ def check(msg):
params.append(k)
if foundp:
# Note that params should already be unquoted.
- addresses.extend(params)
+ address_set.extend(params)
break
else:
# MAS: This is a kludge, but SMTP-GATEWAY01.intra.home.dk
@@ -79,8 +83,15 @@ def check(msg):
# address-type parameter at all. Non-compliant, but ...
for param in params:
if param.startswith('<') and param.endswith('>'):
- addresses.append(param[1:-1])
- return set(parseaddr(address)[1] for address in addresses
+ address_set.append(param[1:-1])
+ # There may be both delayed and failed addresses. If there are any failed
+ # addresses, return those, otherwise just stop processing.
+ if len(failed_addresses) == 0:
+ if len(delayed_addresses) == 0:
+ return set()
+ else:
+ return Stop
+ return set(parseaddr(address)[1] for address in failed_addresses
if address is not None)
@@ -91,18 +102,19 @@ class DSN:
implements(IBounceDetector)
def process(self, msg):
- # A DSN has been seen wrapped with a "legal disclaimer" by an outgoing
- # MTA in a multipart/mixed outer part.
- if msg.is_multipart() and msg.get_content_subtype() == 'mixed':
- msg = msg.get_payload()[0]
- # The above will suffice if the original message 'parts' were wrapped
- # with the disclaimer added, but the original DSN can be wrapped as a
- # message/rfc822 part. We need to test that too.
- if msg.is_multipart() and msg.get_content_type() == 'message/rfc822':
- msg = msg.get_payload()[0]
- # The report-type parameter should be "delivery-status", but it seems
- # that some DSN generating MTAs don't include this on the
- # Content-Type: header, so let's relax the test a bit.
- if not msg.is_multipart() or msg.get_content_subtype() <> 'report':
- return set()
return check(msg)
+ ## # A DSN has been seen wrapped with a "legal disclaimer" by an outgoing
+ ## # MTA in a multipart/mixed outer part.
+ ## if msg.is_multipart() and msg.get_content_subtype() == 'mixed':
+ ## msg = msg.get_payload()[0]
+ ## # The above will suffice if the original message 'parts' were wrapped
+ ## # with the disclaimer added, but the original DSN can be wrapped as a
+ ## # message/rfc822 part. We need to test that too.
+ ## if msg.is_multipart() and msg.get_content_type() == 'message/rfc822':
+ ## msg = msg.get_payload()[0]
+ ## # The report-type parameter should be "delivery-status", but it seems
+ ## # that some DSN generating MTAs don't include this on the
+ ## # Content-Type: header, so let's relax the test a bit.
+ ## if not msg.is_multipart() or msg.get_content_subtype() <> 'report':
+ ## return set()
+ ## return check(msg)
diff --git a/src/mailman/bouncers/llnl.py b/src/mailman/bouncers/llnl.py
index 1d54faf10..bd255d7c2 100644
--- a/src/mailman/bouncers/llnl.py
+++ b/src/mailman/bouncers/llnl.py
@@ -48,5 +48,5 @@ class LLNL:
for line in body_line_iterator(msg):
mo = acre.search(line)
if mo:
- return set(mo.group('addr'))
+ return set([mo.group('addr')])
return set()
diff --git a/src/mailman/bouncers/qmail.py b/src/mailman/bouncers/qmail.py
index 94ea33181..a8063aa46 100644
--- a/src/mailman/bouncers/qmail.py
+++ b/src/mailman/bouncers/qmail.py
@@ -45,11 +45,12 @@ from mailman.interfaces.bounce import IBounceDetector
# Other (non-standard?) intros have been observed in the wild.
introtags = [
- 'Hi. This is the',
"We're sorry. There's a problem",
'Check your send e-mail address.',
+ 'Hi. The MTA program at',
+ 'Hi. This is the',
'This is the mail delivery agent at',
- 'Unfortunately, your mail was not delivered'
+ 'Unfortunately, your mail was not delivered',
]
acre = re.compile(r'<(?P<addr>[^>]*)>:')
diff --git a/src/mailman/bouncers/simplewarning.py b/src/mailman/bouncers/simplewarning.py
index 79173cb21..4da7550fc 100644
--- a/src/mailman/bouncers/simplewarning.py
+++ b/src/mailman/bouncers/simplewarning.py
@@ -25,7 +25,7 @@ __all__ = [
from mailman.bouncers.simplematch import _c
from mailman.bouncers.simplematch import SimpleMatch
-from mailman.interfaces.bounce import BounceStatus
+from mailman.interfaces.bounce import Stop
@@ -55,6 +55,14 @@ PATTERNS = [
(_c('Delivery attempts will continue to be made'),
_c('.+'),
_c('(?P<addr>.+)')),
+ # googlemail.com warning
+ (_c('Delivery to the following recipient has been delayed'),
+ _c('.+'),
+ _c('\s*(?P<addr>.+)')),
+ # Exchange warning message.
+ (_c('This is an advisory-only email'),
+ _c('has been postponed'),
+ _c('"(?P<addr>[^"]+)"')),
# Next one goes here...
]
@@ -69,6 +77,6 @@ class SimpleWarning(SimpleMatch):
"""See `SimpleMatch`."""
if super(SimpleWarning, self).process(msg):
# It's a recognized warning so stop now.
- return BounceStatus.non_fatal
+ return Stop
else:
return set()