diff options
| author | bwarsaw | 2001-10-20 20:59:05 +0000 |
|---|---|---|
| committer | bwarsaw | 2001-10-20 20:59:05 +0000 |
| commit | 20ef78e10ae2cb1397759566dbea2b4b43a931a5 (patch) | |
| tree | e4f2071e20521ea18095dba37d51dcea18a55eaf | |
| parent | 15a8efbbda4bb5de8bc4edef18dd2d8e678c56ab (diff) | |
| download | mailman-20ef78e10ae2cb1397759566dbea2b4b43a931a5.tar.gz mailman-20ef78e10ae2cb1397759566dbea2b4b43a931a5.tar.zst mailman-20ef78e10ae2cb1397759566dbea2b4b43a931a5.zip | |
process(): Reworked Reply-To: munging so list owners can establish
their own policies. Specifically, added first_strip_reply_to which
will control whether any additional Reply-To: headers override or
extend an existing such field.
Also, we no longer save the old Reply-To: header on X-Reply-To:
| -rw-r--r-- | Mailman/Handlers/CookHeaders.py | 43 |
1 files changed, 31 insertions, 12 deletions
diff --git a/Mailman/Handlers/CookHeaders.py b/Mailman/Handlers/CookHeaders.py index 94d133d65..aaf264511 100644 --- a/Mailman/Handlers/CookHeaders.py +++ b/Mailman/Handlers/CookHeaders.py @@ -20,12 +20,15 @@ import re import urlparse +import email.Utils + from Mailman import mm_cfg from Mailman import Utils from Mailman import Errors from Mailman.i18n import _ CONTINUATION = ',\n\t' +COMMASPACE = ', ' @@ -86,14 +89,16 @@ def process(mlist, msg, msgdata): # Reply-To: munging. Do not do this if the message is "fast tracked", # meaning it is internally crafted and delivered to a specific user. BAW: # Yuck, I really hate this feature but I've caved under the sheer pressure - # of the (very vocal) folks want it. + # of the (very vocal) folks want it. OTOH, RFC 2822 allows Reply-To: to + # be a list of addresses, so instead of replacing the original, simply + # augment it. RFC 2822 allows max one Reply-To: header so collapse them + # if we're adding a value, otherwise don't touch it. (Should we collapse + # in all cases?) if not fasttrack: - xreplyto = None # Set Reply-To: header to point back to this list + replyto = [] if mlist.reply_goes_to_list == 1: - xreplyto = msg.get('reply-to') - del msg['reply-to'] - msg['Reply-To'] = mlist.GetListEmail() + replyto.append(('', mlist.GetListEmail())) # Set Reply-To: an explicit address, but only if reply_to_address is a # valid email address. BAW: this really should be validated on input. elif mlist.reply_goes_to_list == 2: @@ -102,13 +107,27 @@ def process(mlist, msg, msgdata): except Errors.EmailAddressError: pass else: - xreplyto = msg.get('reply-to') - del msg['reply-to'] - msg['Reply-To'] = mlist.reply_to_address - # Give the recipient some ability to un-munge things. - if xreplyto: - del msg['x-reply-to'] - msg['X-Reply-To'] = xreplyto + replyto.append(('', mlist.reply_to_address)) + # If we're not first stripping existing Reply-To: then we need to add + # the original Reply-To:'s to the list we're building up. In both + # cases we'll zap the existing field because RFC 2822 says max one is + # allowed. + if not mlist.first_strip_reply_to: + orig = msg.get_all('reply-to', []) + replyto.extend(email.Utils.getaddresses(orig)) + del msg['reply-to'] + # Get rid of duplicates. BAW: does order matter? It might, because + # not all MUAs respect Reply-To: as a list of addresses. Also, note + # duplicates are based on case folded email address, which means in + # the case of dupes, the last one wins (will mostly affect the real + # name clobbering). + d = {} + for name, addr in replyto: + d[addr.lower()] = (name, addr) + if d: + # Don't add one back if there's nothing to add! + msg['Reply-To'] = COMMASPACE.join( + [email.Utils.dump_address_pair(pair) for pair in d.values()]) # Add list-specific headers as defined in RFC 2369 and RFC 2919, but only # if the message is being crafted for a specific list (e.g. not for the # password reminders). |
