Edit File by line
/home/barbar84/public_h.../wp-conte.../plugins/sujqvwi/ShExBy/shex_roo.../lib64/python3..../email
File: message.py
# Copyright (C) 2001-2007 Python Software Foundation
[0] Fix | Delete
# Author: Barry Warsaw
[1] Fix | Delete
# Contact: email-sig@python.org
[2] Fix | Delete
[3] Fix | Delete
"""Basic message object for the email package object model."""
[4] Fix | Delete
[5] Fix | Delete
__all__ = ['Message', 'EmailMessage']
[6] Fix | Delete
[7] Fix | Delete
import re
[8] Fix | Delete
import uu
[9] Fix | Delete
import quopri
[10] Fix | Delete
from io import BytesIO, StringIO
[11] Fix | Delete
[12] Fix | Delete
# Intrapackage imports
[13] Fix | Delete
from email import utils
[14] Fix | Delete
from email import errors
[15] Fix | Delete
from email._policybase import Policy, compat32
[16] Fix | Delete
from email import charset as _charset
[17] Fix | Delete
from email._encoded_words import decode_b
[18] Fix | Delete
Charset = _charset.Charset
[19] Fix | Delete
[20] Fix | Delete
SEMISPACE = '; '
[21] Fix | Delete
[22] Fix | Delete
# Regular expression that matches `special' characters in parameters, the
[23] Fix | Delete
# existence of which force quoting of the parameter value.
[24] Fix | Delete
tspecials = re.compile(r'[ \(\)<>@,;:\\"/\[\]\?=]')
[25] Fix | Delete
[26] Fix | Delete
[27] Fix | Delete
def _splitparam(param):
[28] Fix | Delete
# Split header parameters. BAW: this may be too simple. It isn't
[29] Fix | Delete
# strictly RFC 2045 (section 5.1) compliant, but it catches most headers
[30] Fix | Delete
# found in the wild. We may eventually need a full fledged parser.
[31] Fix | Delete
# RDM: we might have a Header here; for now just stringify it.
[32] Fix | Delete
a, sep, b = str(param).partition(';')
[33] Fix | Delete
if not sep:
[34] Fix | Delete
return a.strip(), None
[35] Fix | Delete
return a.strip(), b.strip()
[36] Fix | Delete
[37] Fix | Delete
def _formatparam(param, value=None, quote=True):
[38] Fix | Delete
"""Convenience function to format and return a key=value pair.
[39] Fix | Delete
[40] Fix | Delete
This will quote the value if needed or if quote is true. If value is a
[41] Fix | Delete
three tuple (charset, language, value), it will be encoded according
[42] Fix | Delete
to RFC2231 rules. If it contains non-ascii characters it will likewise
[43] Fix | Delete
be encoded according to RFC2231 rules, using the utf-8 charset and
[44] Fix | Delete
a null language.
[45] Fix | Delete
"""
[46] Fix | Delete
if value is not None and len(value) > 0:
[47] Fix | Delete
# A tuple is used for RFC 2231 encoded parameter values where items
[48] Fix | Delete
# are (charset, language, value). charset is a string, not a Charset
[49] Fix | Delete
# instance. RFC 2231 encoded values are never quoted, per RFC.
[50] Fix | Delete
if isinstance(value, tuple):
[51] Fix | Delete
# Encode as per RFC 2231
[52] Fix | Delete
param += '*'
[53] Fix | Delete
value = utils.encode_rfc2231(value[2], value[0], value[1])
[54] Fix | Delete
return '%s=%s' % (param, value)
[55] Fix | Delete
else:
[56] Fix | Delete
try:
[57] Fix | Delete
value.encode('ascii')
[58] Fix | Delete
except UnicodeEncodeError:
[59] Fix | Delete
param += '*'
[60] Fix | Delete
value = utils.encode_rfc2231(value, 'utf-8', '')
[61] Fix | Delete
return '%s=%s' % (param, value)
[62] Fix | Delete
# BAW: Please check this. I think that if quote is set it should
[63] Fix | Delete
# force quoting even if not necessary.
[64] Fix | Delete
if quote or tspecials.search(value):
[65] Fix | Delete
return '%s="%s"' % (param, utils.quote(value))
[66] Fix | Delete
else:
[67] Fix | Delete
return '%s=%s' % (param, value)
[68] Fix | Delete
else:
[69] Fix | Delete
return param
[70] Fix | Delete
[71] Fix | Delete
def _parseparam(s):
[72] Fix | Delete
# RDM This might be a Header, so for now stringify it.
[73] Fix | Delete
s = ';' + str(s)
[74] Fix | Delete
plist = []
[75] Fix | Delete
while s[:1] == ';':
[76] Fix | Delete
s = s[1:]
[77] Fix | Delete
end = s.find(';')
[78] Fix | Delete
while end > 0 and (s.count('"', 0, end) - s.count('\\"', 0, end)) % 2:
[79] Fix | Delete
end = s.find(';', end + 1)
[80] Fix | Delete
if end < 0:
[81] Fix | Delete
end = len(s)
[82] Fix | Delete
f = s[:end]
[83] Fix | Delete
if '=' in f:
[84] Fix | Delete
i = f.index('=')
[85] Fix | Delete
f = f[:i].strip().lower() + '=' + f[i+1:].strip()
[86] Fix | Delete
plist.append(f.strip())
[87] Fix | Delete
s = s[end:]
[88] Fix | Delete
return plist
[89] Fix | Delete
[90] Fix | Delete
[91] Fix | Delete
def _unquotevalue(value):
[92] Fix | Delete
# This is different than utils.collapse_rfc2231_value() because it doesn't
[93] Fix | Delete
# try to convert the value to a unicode. Message.get_param() and
[94] Fix | Delete
# Message.get_params() are both currently defined to return the tuple in
[95] Fix | Delete
# the face of RFC 2231 parameters.
[96] Fix | Delete
if isinstance(value, tuple):
[97] Fix | Delete
return value[0], value[1], utils.unquote(value[2])
[98] Fix | Delete
else:
[99] Fix | Delete
return utils.unquote(value)
[100] Fix | Delete
[101] Fix | Delete
[102] Fix | Delete
[103] Fix | Delete
class Message:
[104] Fix | Delete
"""Basic message object.
[105] Fix | Delete
[106] Fix | Delete
A message object is defined as something that has a bunch of RFC 2822
[107] Fix | Delete
headers and a payload. It may optionally have an envelope header
[108] Fix | Delete
(a.k.a. Unix-From or From_ header). If the message is a container (i.e. a
[109] Fix | Delete
multipart or a message/rfc822), then the payload is a list of Message
[110] Fix | Delete
objects, otherwise it is a string.
[111] Fix | Delete
[112] Fix | Delete
Message objects implement part of the `mapping' interface, which assumes
[113] Fix | Delete
there is exactly one occurrence of the header per message. Some headers
[114] Fix | Delete
do in fact appear multiple times (e.g. Received) and for those headers,
[115] Fix | Delete
you must use the explicit API to set or get all the headers. Not all of
[116] Fix | Delete
the mapping methods are implemented.
[117] Fix | Delete
"""
[118] Fix | Delete
def __init__(self, policy=compat32):
[119] Fix | Delete
self.policy = policy
[120] Fix | Delete
self._headers = []
[121] Fix | Delete
self._unixfrom = None
[122] Fix | Delete
self._payload = None
[123] Fix | Delete
self._charset = None
[124] Fix | Delete
# Defaults for multipart messages
[125] Fix | Delete
self.preamble = self.epilogue = None
[126] Fix | Delete
self.defects = []
[127] Fix | Delete
# Default content type
[128] Fix | Delete
self._default_type = 'text/plain'
[129] Fix | Delete
[130] Fix | Delete
def __str__(self):
[131] Fix | Delete
"""Return the entire formatted message as a string.
[132] Fix | Delete
"""
[133] Fix | Delete
return self.as_string()
[134] Fix | Delete
[135] Fix | Delete
def as_string(self, unixfrom=False, maxheaderlen=0, policy=None):
[136] Fix | Delete
"""Return the entire formatted message as a string.
[137] Fix | Delete
[138] Fix | Delete
Optional 'unixfrom', when true, means include the Unix From_ envelope
[139] Fix | Delete
header. For backward compatibility reasons, if maxheaderlen is
[140] Fix | Delete
not specified it defaults to 0, so you must override it explicitly
[141] Fix | Delete
if you want a different maxheaderlen. 'policy' is passed to the
[142] Fix | Delete
Generator instance used to serialize the mesasge; if it is not
[143] Fix | Delete
specified the policy associated with the message instance is used.
[144] Fix | Delete
[145] Fix | Delete
If the message object contains binary data that is not encoded
[146] Fix | Delete
according to RFC standards, the non-compliant data will be replaced by
[147] Fix | Delete
unicode "unknown character" code points.
[148] Fix | Delete
"""
[149] Fix | Delete
from email.generator import Generator
[150] Fix | Delete
policy = self.policy if policy is None else policy
[151] Fix | Delete
fp = StringIO()
[152] Fix | Delete
g = Generator(fp,
[153] Fix | Delete
mangle_from_=False,
[154] Fix | Delete
maxheaderlen=maxheaderlen,
[155] Fix | Delete
policy=policy)
[156] Fix | Delete
g.flatten(self, unixfrom=unixfrom)
[157] Fix | Delete
return fp.getvalue()
[158] Fix | Delete
[159] Fix | Delete
def __bytes__(self):
[160] Fix | Delete
"""Return the entire formatted message as a bytes object.
[161] Fix | Delete
"""
[162] Fix | Delete
return self.as_bytes()
[163] Fix | Delete
[164] Fix | Delete
def as_bytes(self, unixfrom=False, policy=None):
[165] Fix | Delete
"""Return the entire formatted message as a bytes object.
[166] Fix | Delete
[167] Fix | Delete
Optional 'unixfrom', when true, means include the Unix From_ envelope
[168] Fix | Delete
header. 'policy' is passed to the BytesGenerator instance used to
[169] Fix | Delete
serialize the message; if not specified the policy associated with
[170] Fix | Delete
the message instance is used.
[171] Fix | Delete
"""
[172] Fix | Delete
from email.generator import BytesGenerator
[173] Fix | Delete
policy = self.policy if policy is None else policy
[174] Fix | Delete
fp = BytesIO()
[175] Fix | Delete
g = BytesGenerator(fp, mangle_from_=False, policy=policy)
[176] Fix | Delete
g.flatten(self, unixfrom=unixfrom)
[177] Fix | Delete
return fp.getvalue()
[178] Fix | Delete
[179] Fix | Delete
def is_multipart(self):
[180] Fix | Delete
"""Return True if the message consists of multiple parts."""
[181] Fix | Delete
return isinstance(self._payload, list)
[182] Fix | Delete
[183] Fix | Delete
#
[184] Fix | Delete
# Unix From_ line
[185] Fix | Delete
#
[186] Fix | Delete
def set_unixfrom(self, unixfrom):
[187] Fix | Delete
self._unixfrom = unixfrom
[188] Fix | Delete
[189] Fix | Delete
def get_unixfrom(self):
[190] Fix | Delete
return self._unixfrom
[191] Fix | Delete
[192] Fix | Delete
#
[193] Fix | Delete
# Payload manipulation.
[194] Fix | Delete
#
[195] Fix | Delete
def attach(self, payload):
[196] Fix | Delete
"""Add the given payload to the current payload.
[197] Fix | Delete
[198] Fix | Delete
The current payload will always be a list of objects after this method
[199] Fix | Delete
is called. If you want to set the payload to a scalar object, use
[200] Fix | Delete
set_payload() instead.
[201] Fix | Delete
"""
[202] Fix | Delete
if self._payload is None:
[203] Fix | Delete
self._payload = [payload]
[204] Fix | Delete
else:
[205] Fix | Delete
try:
[206] Fix | Delete
self._payload.append(payload)
[207] Fix | Delete
except AttributeError:
[208] Fix | Delete
raise TypeError("Attach is not valid on a message with a"
[209] Fix | Delete
" non-multipart payload")
[210] Fix | Delete
[211] Fix | Delete
def get_payload(self, i=None, decode=False):
[212] Fix | Delete
"""Return a reference to the payload.
[213] Fix | Delete
[214] Fix | Delete
The payload will either be a list object or a string. If you mutate
[215] Fix | Delete
the list object, you modify the message's payload in place. Optional
[216] Fix | Delete
i returns that index into the payload.
[217] Fix | Delete
[218] Fix | Delete
Optional decode is a flag indicating whether the payload should be
[219] Fix | Delete
decoded or not, according to the Content-Transfer-Encoding header
[220] Fix | Delete
(default is False).
[221] Fix | Delete
[222] Fix | Delete
When True and the message is not a multipart, the payload will be
[223] Fix | Delete
decoded if this header's value is `quoted-printable' or `base64'. If
[224] Fix | Delete
some other encoding is used, or the header is missing, or if the
[225] Fix | Delete
payload has bogus data (i.e. bogus base64 or uuencoded data), the
[226] Fix | Delete
payload is returned as-is.
[227] Fix | Delete
[228] Fix | Delete
If the message is a multipart and the decode flag is True, then None
[229] Fix | Delete
is returned.
[230] Fix | Delete
"""
[231] Fix | Delete
# Here is the logic table for this code, based on the email5.0.0 code:
[232] Fix | Delete
# i decode is_multipart result
[233] Fix | Delete
# ------ ------ ------------ ------------------------------
[234] Fix | Delete
# None True True None
[235] Fix | Delete
# i True True None
[236] Fix | Delete
# None False True _payload (a list)
[237] Fix | Delete
# i False True _payload element i (a Message)
[238] Fix | Delete
# i False False error (not a list)
[239] Fix | Delete
# i True False error (not a list)
[240] Fix | Delete
# None False False _payload
[241] Fix | Delete
# None True False _payload decoded (bytes)
[242] Fix | Delete
# Note that Barry planned to factor out the 'decode' case, but that
[243] Fix | Delete
# isn't so easy now that we handle the 8 bit data, which needs to be
[244] Fix | Delete
# converted in both the decode and non-decode path.
[245] Fix | Delete
if self.is_multipart():
[246] Fix | Delete
if decode:
[247] Fix | Delete
return None
[248] Fix | Delete
if i is None:
[249] Fix | Delete
return self._payload
[250] Fix | Delete
else:
[251] Fix | Delete
return self._payload[i]
[252] Fix | Delete
# For backward compatibility, Use isinstance and this error message
[253] Fix | Delete
# instead of the more logical is_multipart test.
[254] Fix | Delete
if i is not None and not isinstance(self._payload, list):
[255] Fix | Delete
raise TypeError('Expected list, got %s' % type(self._payload))
[256] Fix | Delete
payload = self._payload
[257] Fix | Delete
# cte might be a Header, so for now stringify it.
[258] Fix | Delete
cte = str(self.get('content-transfer-encoding', '')).lower()
[259] Fix | Delete
# payload may be bytes here.
[260] Fix | Delete
if isinstance(payload, str):
[261] Fix | Delete
if utils._has_surrogates(payload):
[262] Fix | Delete
bpayload = payload.encode('ascii', 'surrogateescape')
[263] Fix | Delete
if not decode:
[264] Fix | Delete
try:
[265] Fix | Delete
payload = bpayload.decode(self.get_param('charset', 'ascii'), 'replace')
[266] Fix | Delete
except LookupError:
[267] Fix | Delete
payload = bpayload.decode('ascii', 'replace')
[268] Fix | Delete
elif decode:
[269] Fix | Delete
try:
[270] Fix | Delete
bpayload = payload.encode('ascii')
[271] Fix | Delete
except UnicodeError:
[272] Fix | Delete
# This won't happen for RFC compliant messages (messages
[273] Fix | Delete
# containing only ASCII code points in the unicode input).
[274] Fix | Delete
# If it does happen, turn the string into bytes in a way
[275] Fix | Delete
# guaranteed not to fail.
[276] Fix | Delete
bpayload = payload.encode('raw-unicode-escape')
[277] Fix | Delete
if not decode:
[278] Fix | Delete
return payload
[279] Fix | Delete
if cte == 'quoted-printable':
[280] Fix | Delete
return quopri.decodestring(bpayload)
[281] Fix | Delete
elif cte == 'base64':
[282] Fix | Delete
# XXX: this is a bit of a hack; decode_b should probably be factored
[283] Fix | Delete
# out somewhere, but I haven't figured out where yet.
[284] Fix | Delete
value, defects = decode_b(b''.join(bpayload.splitlines()))
[285] Fix | Delete
for defect in defects:
[286] Fix | Delete
self.policy.handle_defect(self, defect)
[287] Fix | Delete
return value
[288] Fix | Delete
elif cte in ('x-uuencode', 'uuencode', 'uue', 'x-uue'):
[289] Fix | Delete
in_file = BytesIO(bpayload)
[290] Fix | Delete
out_file = BytesIO()
[291] Fix | Delete
try:
[292] Fix | Delete
uu.decode(in_file, out_file, quiet=True)
[293] Fix | Delete
return out_file.getvalue()
[294] Fix | Delete
except uu.Error:
[295] Fix | Delete
# Some decoding problem
[296] Fix | Delete
return bpayload
[297] Fix | Delete
if isinstance(payload, str):
[298] Fix | Delete
return bpayload
[299] Fix | Delete
return payload
[300] Fix | Delete
[301] Fix | Delete
def set_payload(self, payload, charset=None):
[302] Fix | Delete
"""Set the payload to the given value.
[303] Fix | Delete
[304] Fix | Delete
Optional charset sets the message's default character set. See
[305] Fix | Delete
set_charset() for details.
[306] Fix | Delete
"""
[307] Fix | Delete
if hasattr(payload, 'encode'):
[308] Fix | Delete
if charset is None:
[309] Fix | Delete
self._payload = payload
[310] Fix | Delete
return
[311] Fix | Delete
if not isinstance(charset, Charset):
[312] Fix | Delete
charset = Charset(charset)
[313] Fix | Delete
payload = payload.encode(charset.output_charset)
[314] Fix | Delete
if hasattr(payload, 'decode'):
[315] Fix | Delete
self._payload = payload.decode('ascii', 'surrogateescape')
[316] Fix | Delete
else:
[317] Fix | Delete
self._payload = payload
[318] Fix | Delete
if charset is not None:
[319] Fix | Delete
self.set_charset(charset)
[320] Fix | Delete
[321] Fix | Delete
def set_charset(self, charset):
[322] Fix | Delete
"""Set the charset of the payload to a given character set.
[323] Fix | Delete
[324] Fix | Delete
charset can be a Charset instance, a string naming a character set, or
[325] Fix | Delete
None. If it is a string it will be converted to a Charset instance.
[326] Fix | Delete
If charset is None, the charset parameter will be removed from the
[327] Fix | Delete
Content-Type field. Anything else will generate a TypeError.
[328] Fix | Delete
[329] Fix | Delete
The message will be assumed to be of type text/* encoded with
[330] Fix | Delete
charset.input_charset. It will be converted to charset.output_charset
[331] Fix | Delete
and encoded properly, if needed, when generating the plain text
[332] Fix | Delete
representation of the message. MIME headers (MIME-Version,
[333] Fix | Delete
Content-Type, Content-Transfer-Encoding) will be added as needed.
[334] Fix | Delete
"""
[335] Fix | Delete
if charset is None:
[336] Fix | Delete
self.del_param('charset')
[337] Fix | Delete
self._charset = None
[338] Fix | Delete
return
[339] Fix | Delete
if not isinstance(charset, Charset):
[340] Fix | Delete
charset = Charset(charset)
[341] Fix | Delete
self._charset = charset
[342] Fix | Delete
if 'MIME-Version' not in self:
[343] Fix | Delete
self.add_header('MIME-Version', '1.0')
[344] Fix | Delete
if 'Content-Type' not in self:
[345] Fix | Delete
self.add_header('Content-Type', 'text/plain',
[346] Fix | Delete
charset=charset.get_output_charset())
[347] Fix | Delete
else:
[348] Fix | Delete
self.set_param('charset', charset.get_output_charset())
[349] Fix | Delete
if charset != charset.get_output_charset():
[350] Fix | Delete
self._payload = charset.body_encode(self._payload)
[351] Fix | Delete
if 'Content-Transfer-Encoding' not in self:
[352] Fix | Delete
cte = charset.get_body_encoding()
[353] Fix | Delete
try:
[354] Fix | Delete
cte(self)
[355] Fix | Delete
except TypeError:
[356] Fix | Delete
# This 'if' is for backward compatibility, it allows unicode
[357] Fix | Delete
# through even though that won't work correctly if the
[358] Fix | Delete
# message is serialized.
[359] Fix | Delete
payload = self._payload
[360] Fix | Delete
if payload:
[361] Fix | Delete
try:
[362] Fix | Delete
payload = payload.encode('ascii', 'surrogateescape')
[363] Fix | Delete
except UnicodeError:
[364] Fix | Delete
payload = payload.encode(charset.output_charset)
[365] Fix | Delete
self._payload = charset.body_encode(payload)
[366] Fix | Delete
self.add_header('Content-Transfer-Encoding', cte)
[367] Fix | Delete
[368] Fix | Delete
def get_charset(self):
[369] Fix | Delete
"""Return the Charset instance associated with the message's payload.
[370] Fix | Delete
"""
[371] Fix | Delete
return self._charset
[372] Fix | Delete
[373] Fix | Delete
#
[374] Fix | Delete
# MAPPING INTERFACE (partial)
[375] Fix | Delete
#
[376] Fix | Delete
def __len__(self):
[377] Fix | Delete
"""Return the total number of headers, including duplicates."""
[378] Fix | Delete
return len(self._headers)
[379] Fix | Delete
[380] Fix | Delete
def __getitem__(self, name):
[381] Fix | Delete
"""Get a header value.
[382] Fix | Delete
[383] Fix | Delete
Return None if the header is missing instead of raising an exception.
[384] Fix | Delete
[385] Fix | Delete
Note that if the header appeared multiple times, exactly which
[386] Fix | Delete
occurrence gets returned is undefined. Use get_all() to get all
[387] Fix | Delete
the values matching a header field name.
[388] Fix | Delete
"""
[389] Fix | Delete
return self.get(name)
[390] Fix | Delete
[391] Fix | Delete
def __setitem__(self, name, val):
[392] Fix | Delete
"""Set the value of a header.
[393] Fix | Delete
[394] Fix | Delete
Note: this does not overwrite an existing header with the same field
[395] Fix | Delete
name. Use __delitem__() first to delete any existing headers.
[396] Fix | Delete
"""
[397] Fix | Delete
max_count = self.policy.header_max_count(name)
[398] Fix | Delete
if max_count:
[399] Fix | Delete
lname = name.lower()
[400] Fix | Delete
found = 0
[401] Fix | Delete
for k, v in self._headers:
[402] Fix | Delete
if k.lower() == lname:
[403] Fix | Delete
found += 1
[404] Fix | Delete
if found >= max_count:
[405] Fix | Delete
raise ValueError("There may be at most {} {} headers "
[406] Fix | Delete
"in a message".format(max_count, name))
[407] Fix | Delete
self._headers.append(self.policy.header_store_parse(name, val))
[408] Fix | Delete
[409] Fix | Delete
def __delitem__(self, name):
[410] Fix | Delete
"""Delete all occurrences of a header, if present.
[411] Fix | Delete
[412] Fix | Delete
Does not raise an exception if the header is missing.
[413] Fix | Delete
"""
[414] Fix | Delete
name = name.lower()
[415] Fix | Delete
newheaders = []
[416] Fix | Delete
for k, v in self._headers:
[417] Fix | Delete
if k.lower() != name:
[418] Fix | Delete
newheaders.append((k, v))
[419] Fix | Delete
self._headers = newheaders
[420] Fix | Delete
[421] Fix | Delete
def __contains__(self, name):
[422] Fix | Delete
return name.lower() in [k.lower() for k, v in self._headers]
[423] Fix | Delete
[424] Fix | Delete
def __iter__(self):
[425] Fix | Delete
for field, value in self._headers:
[426] Fix | Delete
yield field
[427] Fix | Delete
[428] Fix | Delete
def keys(self):
[429] Fix | Delete
"""Return a list of all the message's header field names.
[430] Fix | Delete
[431] Fix | Delete
These will be sorted in the order they appeared in the original
[432] Fix | Delete
message, or were added to the message, and may contain duplicates.
[433] Fix | Delete
Any fields deleted and re-inserted are always appended to the header
[434] Fix | Delete
list.
[435] Fix | Delete
"""
[436] Fix | Delete
return [k for k, v in self._headers]
[437] Fix | Delete
[438] Fix | Delete
def values(self):
[439] Fix | Delete
"""Return a list of all the message's header values.
[440] Fix | Delete
[441] Fix | Delete
These will be sorted in the order they appeared in the original
[442] Fix | Delete
message, or were added to the message, and may contain duplicates.
[443] Fix | Delete
Any fields deleted and re-inserted are always appended to the header
[444] Fix | Delete
list.
[445] Fix | Delete
"""
[446] Fix | Delete
return [self.policy.header_fetch_parse(k, v)
[447] Fix | Delete
for k, v in self._headers]
[448] Fix | Delete
[449] Fix | Delete
def items(self):
[450] Fix | Delete
"""Get all the message's header fields and values.
[451] Fix | Delete
[452] Fix | Delete
These will be sorted in the order they appeared in the original
[453] Fix | Delete
message, or were added to the message, and may contain duplicates.
[454] Fix | Delete
Any fields deleted and re-inserted are always appended to the header
[455] Fix | Delete
list.
[456] Fix | Delete
"""
[457] Fix | Delete
return [(k, self.policy.header_fetch_parse(k, v))
[458] Fix | Delete
for k, v in self._headers]
[459] Fix | Delete
[460] Fix | Delete
def get(self, name, failobj=None):
[461] Fix | Delete
"""Get a header value.
[462] Fix | Delete
[463] Fix | Delete
Like __getitem__() but return failobj instead of None when the field
[464] Fix | Delete
is missing.
[465] Fix | Delete
"""
[466] Fix | Delete
name = name.lower()
[467] Fix | Delete
for k, v in self._headers:
[468] Fix | Delete
if k.lower() == name:
[469] Fix | Delete
return self.policy.header_fetch_parse(k, v)
[470] Fix | Delete
return failobj
[471] Fix | Delete
[472] Fix | Delete
#
[473] Fix | Delete
# "Internal" methods (public API, but only intended for use by a parser
[474] Fix | Delete
# or generator, not normal application code.
[475] Fix | Delete
#
[476] Fix | Delete
[477] Fix | Delete
def set_raw(self, name, value):
[478] Fix | Delete
"""Store name and value in the model without modification.
[479] Fix | Delete
[480] Fix | Delete
This is an "internal" API, intended only for use by a parser.
[481] Fix | Delete
"""
[482] Fix | Delete
self._headers.append((name, value))
[483] Fix | Delete
[484] Fix | Delete
def raw_items(self):
[485] Fix | Delete
"""Return the (name, value) header pairs without modification.
[486] Fix | Delete
[487] Fix | Delete
This is an "internal" API, intended only for use by a generator.
[488] Fix | Delete
"""
[489] Fix | Delete
return iter(self._headers.copy())
[490] Fix | Delete
[491] Fix | Delete
#
[492] Fix | Delete
# Additional useful stuff
[493] Fix | Delete
#
[494] Fix | Delete
[495] Fix | Delete
def get_all(self, name, failobj=None):
[496] Fix | Delete
"""Return a list of all the values for the named field.
[497] Fix | Delete
[498] Fix | Delete
These will be sorted in the order they appeared in the original
[499] Fix | Delete
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function