Skip to content

Commit cbb7692

Browse files
committed
update
1 parent b6b934e commit cbb7692

1 file changed

Lines changed: 31 additions & 13 deletions

File tree

Mailman/Queue/IncomingRunner.py

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,12 @@
116116
from Mailman import Errors
117117
from Mailman import LockFile
118118
from Mailman.Queue.Runner import Runner
119+
from Mailman.Queue.Switchboard import Switchboard
119120
from Mailman.Logging.Syslog import mailman_log
120121
import Mailman.MailList as MailList
121122
import Mailman.Message
123+
import threading
124+
import email.header
122125

123126

124127
class PipelineError(Exception):
@@ -192,6 +195,14 @@ def _dispose(self, mlist, msg, msgdata):
192195
# Convert Python's Message to Mailman's Message if needed
193196
msg = self._convert_message(msg)
194197

198+
# Check if this is a bounce message
199+
if self._is_bounce(msg):
200+
mailman_log('debug', 'IncomingRunner._dispose: Message %s is a bounce, routing to bounce queue', msgid)
201+
# Route to bounce queue
202+
bounce_queue = Switchboard(mm_cfg.BOUNCEQUEUE_DIR)
203+
bounce_queue.enqueue(msg, msgdata)
204+
return False
205+
195206
# Get the pipeline
196207
pipeline = self._get_pipeline(mlist, msg, msgdata)
197208
if not pipeline:
@@ -282,19 +293,26 @@ def _is_command(self, msg):
282293
return False
283294

284295
def _is_bounce(self, msg):
285-
"""Check if the message is a bounce."""
286-
try:
287-
# Check common bounce headers
288-
bounce_headers = ['X-Failed-Recipients', 'X-Original-To', 'Return-Path']
289-
for header in bounce_headers:
290-
if msg.get(header):
291-
mailman_log('debug', 'IncomingRunner._is_bounce: Message has bounce header %s', header)
292-
return True
293-
return False
294-
except Exception as e:
295-
mailman_log('error', 'IncomingRunner._is_bounce: Error checking bounce: %s\nTraceback:\n%s',
296-
str(e), traceback.format_exc())
297-
return False
296+
"""Check if a message is a bounce message."""
297+
# Check for common bounce headers
298+
if msg.get('x-failed-recipients'):
299+
return True
300+
if msg.get('x-original-to'):
301+
return True
302+
if msg.get('return-path', '').startswith('<>'):
303+
return True
304+
# Check content type for multipart/report
305+
if msg.get('content-type', '').startswith('multipart/report'):
306+
return True
307+
# Check for common bounce subjects
308+
subject = msg.get('subject', '').lower()
309+
bounce_subjects = ['delivery status', 'failure notice', 'mail delivery failed',
310+
'mail delivery system', 'mail system error', 'returned mail',
311+
'undeliverable', 'undelivered mail']
312+
for bounce_subject in bounce_subjects:
313+
if bounce_subject in subject:
314+
return True
315+
return False
298316

299317
def _process_command(self, mlist, msg, msgdata):
300318
"""Process a command message."""

0 commit comments

Comments
 (0)