Ticket #6918: mail-header-encoding.diff
File mail-header-encoding.diff, 6.8 KB (added by , 16 years ago) |
---|
-
django/core/mail.py
old new 69 69 class BadHeaderError(ValueError): 70 70 pass 71 71 72 def forbid_multi_line_headers(name, val ):72 def forbid_multi_line_headers(name, val, header_encoding): 73 73 """Forbids multi-line headers, to prevent header injection.""" 74 74 if '\n' in val or '\r' in val: 75 75 raise BadHeaderError("Header values can't contain newlines (got %r for header %r)" % (val, name)) … … 80 80 result = [] 81 81 for item in val.split(', '): 82 82 nm, addr = parseaddr(item) 83 nm = str(Header(nm, settings.DEFAULT_CHARSET))83 nm = str(Header(nm, header_encoding)) 84 84 result.append(formataddr((nm, str(addr)))) 85 85 val = ', '.join(result) 86 86 else: 87 val = Header(force_unicode(val), settings.DEFAULT_CHARSET)87 val = Header(force_unicode(val), header_encoding) 88 88 return name, val 89 89 90 90 class SafeMIMEText(MIMEText): 91 def __init__(self, text, subtype, charset, header_encoding=None): 92 self.header_encoding = header_encoding or settings.DEFAULT_CHARSET 93 MIMEText.__init__(self, text, subtype, charset) 91 94 def __setitem__(self, name, val): 92 name, val = forbid_multi_line_headers(name, val )95 name, val = forbid_multi_line_headers(name, val, self.header_encoding) 93 96 MIMEText.__setitem__(self, name, val) 94 97 95 98 class SafeMIMEMultipart(MIMEMultipart): 99 def __init__(self, _subtype='mixed', boundary=None, _subparts=None, header_encoding=None, **_params): 100 self.header_encoding = header_encoding or settings.DEFAULT_CHARSET 101 MIMEMultipart.__init__(self, _subtype, boundary, _subparts, **_params) 96 102 def __setitem__(self, name, val): 97 name, val = forbid_multi_line_headers(name, val )103 name, val = forbid_multi_line_headers(name, val, self.header_encoding) 98 104 MIMEMultipart.__setitem__(self, name, val) 99 105 100 106 class SMTPConnection(object): … … 195 201 encoding = None # None => use settings default 196 202 197 203 def __init__(self, subject='', body='', from_email=None, to=None, bcc=None, 198 connection=None, attachments=None, headers=None ):204 connection=None, attachments=None, headers=None, header_encoding=None): 199 205 """ 200 206 Initialize a single email message (which can be sent to multiple 201 207 recipients). … … 220 226 self.attachments = attachments or [] 221 227 self.extra_headers = headers or {} 222 228 self.connection = connection 229 self.header_encoding = header_encoding 223 230 224 231 def get_connection(self, fail_silently=False): 225 232 if not self.connection: … … 228 235 229 236 def message(self): 230 237 encoding = self.encoding or settings.DEFAULT_CHARSET 238 header_encoding = self.header_encoding or settings.DEFAULT_CHARSET 231 239 msg = SafeMIMEText(smart_str(self.body, settings.DEFAULT_CHARSET), 232 self.content_subtype, encoding )240 self.content_subtype, encoding, header_encoding) 233 241 if self.attachments: 234 242 body_msg = msg 235 msg = SafeMIMEMultipart(_subtype=self.multipart_subtype )243 msg = SafeMIMEMultipart(_subtype=self.multipart_subtype, header_encoding=header_encoding) 236 244 if self.body: 237 245 msg.attach(body_msg) 238 246 for attachment in self.attachments: … … 318 326 self.attach(content=content, mimetype=mimetype) 319 327 320 328 def send_mail(subject, message, from_email, recipient_list, 321 fail_silently=False, auth_user=None, auth_password=None): 329 fail_silently=False, auth_user=None, auth_password=None, 330 header_encoding=None): 322 331 """ 323 332 Easy wrapper for sending a single message to a recipient list. All members 324 333 of the recipient list will see the other recipients in the 'To' field. 325 334 326 335 If auth_user is None, the EMAIL_HOST_USER setting is used. 327 336 If auth_password is None, the EMAIL_HOST_PASSWORD setting is used. 337 If header_encoding is None, the DEFAULT_CHARSET setting is used. 328 338 329 339 Note: The API for this method is frozen. New code wanting to extend the 330 340 functionality should use the EmailMessage class directly. … … 332 342 connection = SMTPConnection(username=auth_user, password=auth_password, 333 343 fail_silently=fail_silently) 334 344 return EmailMessage(subject, message, from_email, recipient_list, 335 connection=connection ).send()345 connection=connection, header_encoding=header_encoding).send() 336 346 337 347 def send_mass_mail(datatuple, fail_silently=False, auth_user=None, 338 auth_password=None ):348 auth_password=None, header_encoding=None): 339 349 """ 340 350 Given a datatuple of (subject, message, from_email, recipient_list), sends 341 351 each message to each recipient list. Returns the number of e-mails sent. … … 344 354 If auth_user and auth_password are set, they're used to log in. 345 355 If auth_user is None, the EMAIL_HOST_USER setting is used. 346 356 If auth_password is None, the EMAIL_HOST_PASSWORD setting is used. 357 If header_encoding is None, the DEFAULT_CHARSET setting is used. 347 358 348 359 Note: The API for this method is frozen. New code wanting to extend the 349 360 functionality should use the EmailMessage class directly. 350 361 """ 351 362 connection = SMTPConnection(username=auth_user, password=auth_password, 352 363 fail_silently=fail_silently) 353 messages = [EmailMessage(subject, message, sender, recipient )364 messages = [EmailMessage(subject, message, sender, recipient, header_encoding=header_encoding) 354 365 for subject, message, sender, recipient in datatuple] 355 366 return connection.send_messages(messages) 356 367 -
docs/email.txt
old new 245 245 caller to ensure header names and values are in the correct format for 246 246 an e-mail message. 247 247 248 * ``header_encoding``: The encoding of the email header. Defaults to DEFAULT_CHARSET 249 setting. 250 248 251 For example:: 249 252 250 253 email = EmailMessage('Hello', 'Body goes here', 'from@example.com', 251 254 ['to1@example.com', 'to2@example.com'], ['bcc@example.com'], 252 headers = {'Reply-To': 'another@example.com'}) 255 headers = {'Reply-To': 'another@example.com'}, 256 header_encoding = 'utf-8') 253 257 254 258 The class has the following methods: 255 259