diff options
| author | Barry Warsaw | 2009-10-24 16:49:33 -0400 |
|---|---|---|
| committer | Barry Warsaw | 2009-10-24 16:49:33 -0400 |
| commit | 19e6548e3df4719455ab1ed2a242acbc3e38d9e9 (patch) | |
| tree | ffae2472bb9c49ee53b5cba37213c74c33284b4c | |
| parent | 7f5818a6c2356211c41c9fcd7dd8fa3b5c4ac6f6 (diff) | |
| download | mailman-19e6548e3df4719455ab1ed2a242acbc3e38d9e9.tar.gz mailman-19e6548e3df4719455ab1ed2a242acbc3e38d9e9.tar.zst mailman-19e6548e3df4719455ab1ed2a242acbc3e38d9e9.zip | |
| -rw-r--r-- | src/mailman/mta/bulk.py | 19 | ||||
| -rw-r--r-- | src/mailman/mta/docs/bulk.txt | 118 |
2 files changed, 135 insertions, 2 deletions
diff --git a/src/mailman/mta/bulk.py b/src/mailman/mta/bulk.py index 2b400e8b5..ff00f3d20 100644 --- a/src/mailman/mta/bulk.py +++ b/src/mailman/mta/bulk.py @@ -115,6 +115,25 @@ class BulkDelivery: recipients = msgdata.get('recipients') if recipients is None: return + # Blow away any existing Sender and Errors-To headers and substitute + # our own. Our interpretation of RFC 5322 $3.6.2 is that Mailman is + # the "agent responsible for actual transmission of the message" + # because what we send to list members is different than what the + # original author sent. RFC 2076 says Errors-To is "non-standard, + # discouraged" but we include it for historical purposes. + del msg['sender'] + del msg['errors-to'] + # The message metadata can override the calculation of the sender, but + # otherwise it falls to the list's -bounces robot. If this message is + # not intended for any specific mailing list, the site owner's address + # is used. + sender = msgdata.get('sender') + if sender is None: + sender = (config.mailman.site_owner + if mlist is None + else mlist.bounces_address) + msg['Sender'] = sender + msg['Errors-To'] = sender for recipients in self.chunkify(msgdata['recipients']): self._connection.sendmail( 'foo@example.com', recipients, msg.as_string()) diff --git a/src/mailman/mta/docs/bulk.txt b/src/mailman/mta/docs/bulk.txt index 42c9e386a..a612e8ac9 100644 --- a/src/mailman/mta/docs/bulk.txt +++ b/src/mailman/mta/docs/bulk.txt @@ -173,8 +173,7 @@ message sent, with all the recipients packed into the envelope recipients To: test@example.com Subject: test one Message-ID: <aardvark> - X-Peer: ... - X-MailFrom: ... + ... X-RcptTo: person_... person_... ... @@ -202,3 +201,118 @@ each with 20 addresses in the RCPT TO header. Number of recipients: 20 Number of recipients: 20 Number of recipients: 20 + + +Delivery headers +================ + +The message delivered to bulk recipients has its Sender and Errors-To headers +set to some Mailman-responsible agent that can handle such errors, for example +the -bounces robot for the list or the site owner's address. The relevant +RFCs are 5321, 5322, and 2076. + +It is arguably incorrect for Mailman to touch the Sender header, if the +interpretation is such that the original author's agent is considered the +"agent responsible for actual transmission of the message" (RFC 5322 $3.6.2). +On the other hand, a reasonable argument can be made that Mailman is the +responsible agent since the message being received by list members is +different than the message sent by the original author. We make the latter +interpretation, and thus Mailman removes all existing Sender headers and +inserts its own. + +RFC 2076 states that Errors-To is "non-standard, discouraged". We treat it +the same as Sender for historical de-facto purposes. + +The bulk delivery module calculates the sending agent address first from the +message metadata... + + >>> bulk = BulkDelivery() + >>> recipients = set(['aperson@example.com']) + >>> msgdata = dict(recipients=recipients, + ... sender='asender@example.org') + >>> bulk.deliver(mlist, msg, msgdata) + >>> message = list(smtpd.messages)[0] + >>> print message.as_string() + From: aperson@example.org + To: test@example.com + Subject: test one + Message-ID: <aardvark> + Sender: asender@example.org + Errors-To: asender@example.org + X-Peer: ... + X-MailFrom: foo@example.com + X-RcptTo: aperson@example.com + <BLANKLINE> + This is a test. + +...followed by the mailing list's bounces robot address... + + >>> del msgdata['sender'] + >>> bulk.deliver(mlist, msg, msgdata) + >>> message = list(smtpd.messages)[0] + >>> print message.as_string() + From: aperson@example.org + To: test@example.com + Subject: test one + Message-ID: <aardvark> + Sender: test-bounces@example.com + Errors-To: test-bounces@example.com + X-Peer: ... + X-MailFrom: foo@example.com + X-RcptTo: aperson@example.com + <BLANKLINE> + This is a test. + +...and finally the site owner, if there is no mailing list target for this +message. + + >>> config.push('site-owner', """\ + ... [mailman] + ... site_owner: site-owner@example.com + ... """) + + >>> bulk.deliver(None, msg, msgdata) + >>> message = list(smtpd.messages)[0] + >>> print message.as_string() + From: aperson@example.org + To: test@example.com + Subject: test one + Message-ID: <aardvark> + Sender: site-owner@example.com + Errors-To: site-owner@example.com + X-Peer: ... + X-MailFrom: foo@example.com + X-RcptTo: aperson@example.com + <BLANKLINE> + This is a test. + +Any existing Sender or Errors-To headers in the original message are always +deleted first. + + >>> msg = message_from_string("""\ + ... From: bperson@example.org + ... To: test@example.com + ... Subject: test two + ... Message-ID: <badger> + ... Sender: robot@example.org + ... Errors-To: robot@example.org + ... + ... This is a test. + ... """) + + >>> bulk.deliver(mlist, msg, msgdata) + >>> message = list(smtpd.messages)[0] + >>> print message.as_string() + From: bperson@example.org + To: test@example.com + Subject: test two + Message-ID: <badger> + Sender: test-bounces@example.com + Errors-To: test-bounces@example.com + X-Peer: ... + X-MailFrom: foo@example.com + X-RcptTo: aperson@example.com + <BLANKLINE> + This is a test. + + >>> config.pop('site-owner') |
