1*cda5da8dSAndroid Build Coastguard Worker"""Policy framework for the email package. 2*cda5da8dSAndroid Build Coastguard Worker 3*cda5da8dSAndroid Build Coastguard WorkerAllows fine grained feature control of how the package parses and emits data. 4*cda5da8dSAndroid Build Coastguard Worker""" 5*cda5da8dSAndroid Build Coastguard Worker 6*cda5da8dSAndroid Build Coastguard Workerimport abc 7*cda5da8dSAndroid Build Coastguard Workerfrom email import header 8*cda5da8dSAndroid Build Coastguard Workerfrom email import charset as _charset 9*cda5da8dSAndroid Build Coastguard Workerfrom email.utils import _has_surrogates 10*cda5da8dSAndroid Build Coastguard Worker 11*cda5da8dSAndroid Build Coastguard Worker__all__ = [ 12*cda5da8dSAndroid Build Coastguard Worker 'Policy', 13*cda5da8dSAndroid Build Coastguard Worker 'Compat32', 14*cda5da8dSAndroid Build Coastguard Worker 'compat32', 15*cda5da8dSAndroid Build Coastguard Worker ] 16*cda5da8dSAndroid Build Coastguard Worker 17*cda5da8dSAndroid Build Coastguard Worker 18*cda5da8dSAndroid Build Coastguard Workerclass _PolicyBase: 19*cda5da8dSAndroid Build Coastguard Worker 20*cda5da8dSAndroid Build Coastguard Worker """Policy Object basic framework. 21*cda5da8dSAndroid Build Coastguard Worker 22*cda5da8dSAndroid Build Coastguard Worker This class is useless unless subclassed. A subclass should define 23*cda5da8dSAndroid Build Coastguard Worker class attributes with defaults for any values that are to be 24*cda5da8dSAndroid Build Coastguard Worker managed by the Policy object. The constructor will then allow 25*cda5da8dSAndroid Build Coastguard Worker non-default values to be set for these attributes at instance 26*cda5da8dSAndroid Build Coastguard Worker creation time. The instance will be callable, taking these same 27*cda5da8dSAndroid Build Coastguard Worker attributes keyword arguments, and returning a new instance 28*cda5da8dSAndroid Build Coastguard Worker identical to the called instance except for those values changed 29*cda5da8dSAndroid Build Coastguard Worker by the keyword arguments. Instances may be added, yielding new 30*cda5da8dSAndroid Build Coastguard Worker instances with any non-default values from the right hand 31*cda5da8dSAndroid Build Coastguard Worker operand overriding those in the left hand operand. That is, 32*cda5da8dSAndroid Build Coastguard Worker 33*cda5da8dSAndroid Build Coastguard Worker A + B == A(<non-default values of B>) 34*cda5da8dSAndroid Build Coastguard Worker 35*cda5da8dSAndroid Build Coastguard Worker The repr of an instance can be used to reconstruct the object 36*cda5da8dSAndroid Build Coastguard Worker if and only if the repr of the values can be used to reconstruct 37*cda5da8dSAndroid Build Coastguard Worker those values. 38*cda5da8dSAndroid Build Coastguard Worker 39*cda5da8dSAndroid Build Coastguard Worker """ 40*cda5da8dSAndroid Build Coastguard Worker 41*cda5da8dSAndroid Build Coastguard Worker def __init__(self, **kw): 42*cda5da8dSAndroid Build Coastguard Worker """Create new Policy, possibly overriding some defaults. 43*cda5da8dSAndroid Build Coastguard Worker 44*cda5da8dSAndroid Build Coastguard Worker See class docstring for a list of overridable attributes. 45*cda5da8dSAndroid Build Coastguard Worker 46*cda5da8dSAndroid Build Coastguard Worker """ 47*cda5da8dSAndroid Build Coastguard Worker for name, value in kw.items(): 48*cda5da8dSAndroid Build Coastguard Worker if hasattr(self, name): 49*cda5da8dSAndroid Build Coastguard Worker super(_PolicyBase,self).__setattr__(name, value) 50*cda5da8dSAndroid Build Coastguard Worker else: 51*cda5da8dSAndroid Build Coastguard Worker raise TypeError( 52*cda5da8dSAndroid Build Coastguard Worker "{!r} is an invalid keyword argument for {}".format( 53*cda5da8dSAndroid Build Coastguard Worker name, self.__class__.__name__)) 54*cda5da8dSAndroid Build Coastguard Worker 55*cda5da8dSAndroid Build Coastguard Worker def __repr__(self): 56*cda5da8dSAndroid Build Coastguard Worker args = [ "{}={!r}".format(name, value) 57*cda5da8dSAndroid Build Coastguard Worker for name, value in self.__dict__.items() ] 58*cda5da8dSAndroid Build Coastguard Worker return "{}({})".format(self.__class__.__name__, ', '.join(args)) 59*cda5da8dSAndroid Build Coastguard Worker 60*cda5da8dSAndroid Build Coastguard Worker def clone(self, **kw): 61*cda5da8dSAndroid Build Coastguard Worker """Return a new instance with specified attributes changed. 62*cda5da8dSAndroid Build Coastguard Worker 63*cda5da8dSAndroid Build Coastguard Worker The new instance has the same attribute values as the current object, 64*cda5da8dSAndroid Build Coastguard Worker except for the changes passed in as keyword arguments. 65*cda5da8dSAndroid Build Coastguard Worker 66*cda5da8dSAndroid Build Coastguard Worker """ 67*cda5da8dSAndroid Build Coastguard Worker newpolicy = self.__class__.__new__(self.__class__) 68*cda5da8dSAndroid Build Coastguard Worker for attr, value in self.__dict__.items(): 69*cda5da8dSAndroid Build Coastguard Worker object.__setattr__(newpolicy, attr, value) 70*cda5da8dSAndroid Build Coastguard Worker for attr, value in kw.items(): 71*cda5da8dSAndroid Build Coastguard Worker if not hasattr(self, attr): 72*cda5da8dSAndroid Build Coastguard Worker raise TypeError( 73*cda5da8dSAndroid Build Coastguard Worker "{!r} is an invalid keyword argument for {}".format( 74*cda5da8dSAndroid Build Coastguard Worker attr, self.__class__.__name__)) 75*cda5da8dSAndroid Build Coastguard Worker object.__setattr__(newpolicy, attr, value) 76*cda5da8dSAndroid Build Coastguard Worker return newpolicy 77*cda5da8dSAndroid Build Coastguard Worker 78*cda5da8dSAndroid Build Coastguard Worker def __setattr__(self, name, value): 79*cda5da8dSAndroid Build Coastguard Worker if hasattr(self, name): 80*cda5da8dSAndroid Build Coastguard Worker msg = "{!r} object attribute {!r} is read-only" 81*cda5da8dSAndroid Build Coastguard Worker else: 82*cda5da8dSAndroid Build Coastguard Worker msg = "{!r} object has no attribute {!r}" 83*cda5da8dSAndroid Build Coastguard Worker raise AttributeError(msg.format(self.__class__.__name__, name)) 84*cda5da8dSAndroid Build Coastguard Worker 85*cda5da8dSAndroid Build Coastguard Worker def __add__(self, other): 86*cda5da8dSAndroid Build Coastguard Worker """Non-default values from right operand override those from left. 87*cda5da8dSAndroid Build Coastguard Worker 88*cda5da8dSAndroid Build Coastguard Worker The object returned is a new instance of the subclass. 89*cda5da8dSAndroid Build Coastguard Worker 90*cda5da8dSAndroid Build Coastguard Worker """ 91*cda5da8dSAndroid Build Coastguard Worker return self.clone(**other.__dict__) 92*cda5da8dSAndroid Build Coastguard Worker 93*cda5da8dSAndroid Build Coastguard Worker 94*cda5da8dSAndroid Build Coastguard Workerdef _append_doc(doc, added_doc): 95*cda5da8dSAndroid Build Coastguard Worker doc = doc.rsplit('\n', 1)[0] 96*cda5da8dSAndroid Build Coastguard Worker added_doc = added_doc.split('\n', 1)[1] 97*cda5da8dSAndroid Build Coastguard Worker return doc + '\n' + added_doc 98*cda5da8dSAndroid Build Coastguard Worker 99*cda5da8dSAndroid Build Coastguard Workerdef _extend_docstrings(cls): 100*cda5da8dSAndroid Build Coastguard Worker if cls.__doc__ and cls.__doc__.startswith('+'): 101*cda5da8dSAndroid Build Coastguard Worker cls.__doc__ = _append_doc(cls.__bases__[0].__doc__, cls.__doc__) 102*cda5da8dSAndroid Build Coastguard Worker for name, attr in cls.__dict__.items(): 103*cda5da8dSAndroid Build Coastguard Worker if attr.__doc__ and attr.__doc__.startswith('+'): 104*cda5da8dSAndroid Build Coastguard Worker for c in (c for base in cls.__bases__ for c in base.mro()): 105*cda5da8dSAndroid Build Coastguard Worker doc = getattr(getattr(c, name), '__doc__') 106*cda5da8dSAndroid Build Coastguard Worker if doc: 107*cda5da8dSAndroid Build Coastguard Worker attr.__doc__ = _append_doc(doc, attr.__doc__) 108*cda5da8dSAndroid Build Coastguard Worker break 109*cda5da8dSAndroid Build Coastguard Worker return cls 110*cda5da8dSAndroid Build Coastguard Worker 111*cda5da8dSAndroid Build Coastguard Worker 112*cda5da8dSAndroid Build Coastguard Workerclass Policy(_PolicyBase, metaclass=abc.ABCMeta): 113*cda5da8dSAndroid Build Coastguard Worker 114*cda5da8dSAndroid Build Coastguard Worker r"""Controls for how messages are interpreted and formatted. 115*cda5da8dSAndroid Build Coastguard Worker 116*cda5da8dSAndroid Build Coastguard Worker Most of the classes and many of the methods in the email package accept 117*cda5da8dSAndroid Build Coastguard Worker Policy objects as parameters. A Policy object contains a set of values and 118*cda5da8dSAndroid Build Coastguard Worker functions that control how input is interpreted and how output is rendered. 119*cda5da8dSAndroid Build Coastguard Worker For example, the parameter 'raise_on_defect' controls whether or not an RFC 120*cda5da8dSAndroid Build Coastguard Worker violation results in an error being raised or not, while 'max_line_length' 121*cda5da8dSAndroid Build Coastguard Worker controls the maximum length of output lines when a Message is serialized. 122*cda5da8dSAndroid Build Coastguard Worker 123*cda5da8dSAndroid Build Coastguard Worker Any valid attribute may be overridden when a Policy is created by passing 124*cda5da8dSAndroid Build Coastguard Worker it as a keyword argument to the constructor. Policy objects are immutable, 125*cda5da8dSAndroid Build Coastguard Worker but a new Policy object can be created with only certain values changed by 126*cda5da8dSAndroid Build Coastguard Worker calling the Policy instance with keyword arguments. Policy objects can 127*cda5da8dSAndroid Build Coastguard Worker also be added, producing a new Policy object in which the non-default 128*cda5da8dSAndroid Build Coastguard Worker attributes set in the right hand operand overwrite those specified in the 129*cda5da8dSAndroid Build Coastguard Worker left operand. 130*cda5da8dSAndroid Build Coastguard Worker 131*cda5da8dSAndroid Build Coastguard Worker Settable attributes: 132*cda5da8dSAndroid Build Coastguard Worker 133*cda5da8dSAndroid Build Coastguard Worker raise_on_defect -- If true, then defects should be raised as errors. 134*cda5da8dSAndroid Build Coastguard Worker Default: False. 135*cda5da8dSAndroid Build Coastguard Worker 136*cda5da8dSAndroid Build Coastguard Worker linesep -- string containing the value to use as separation 137*cda5da8dSAndroid Build Coastguard Worker between output lines. Default '\n'. 138*cda5da8dSAndroid Build Coastguard Worker 139*cda5da8dSAndroid Build Coastguard Worker cte_type -- Type of allowed content transfer encodings 140*cda5da8dSAndroid Build Coastguard Worker 141*cda5da8dSAndroid Build Coastguard Worker 7bit -- ASCII only 142*cda5da8dSAndroid Build Coastguard Worker 8bit -- Content-Transfer-Encoding: 8bit is allowed 143*cda5da8dSAndroid Build Coastguard Worker 144*cda5da8dSAndroid Build Coastguard Worker Default: 8bit. Also controls the disposition of 145*cda5da8dSAndroid Build Coastguard Worker (RFC invalid) binary data in headers; see the 146*cda5da8dSAndroid Build Coastguard Worker documentation of the binary_fold method. 147*cda5da8dSAndroid Build Coastguard Worker 148*cda5da8dSAndroid Build Coastguard Worker max_line_length -- maximum length of lines, excluding 'linesep', 149*cda5da8dSAndroid Build Coastguard Worker during serialization. None or 0 means no line 150*cda5da8dSAndroid Build Coastguard Worker wrapping is done. Default is 78. 151*cda5da8dSAndroid Build Coastguard Worker 152*cda5da8dSAndroid Build Coastguard Worker mangle_from_ -- a flag that, when True escapes From_ lines in the 153*cda5da8dSAndroid Build Coastguard Worker body of the message by putting a `>' in front of 154*cda5da8dSAndroid Build Coastguard Worker them. This is used when the message is being 155*cda5da8dSAndroid Build Coastguard Worker serialized by a generator. Default: True. 156*cda5da8dSAndroid Build Coastguard Worker 157*cda5da8dSAndroid Build Coastguard Worker message_factory -- the class to use to create new message objects. 158*cda5da8dSAndroid Build Coastguard Worker If the value is None, the default is Message. 159*cda5da8dSAndroid Build Coastguard Worker 160*cda5da8dSAndroid Build Coastguard Worker """ 161*cda5da8dSAndroid Build Coastguard Worker 162*cda5da8dSAndroid Build Coastguard Worker raise_on_defect = False 163*cda5da8dSAndroid Build Coastguard Worker linesep = '\n' 164*cda5da8dSAndroid Build Coastguard Worker cte_type = '8bit' 165*cda5da8dSAndroid Build Coastguard Worker max_line_length = 78 166*cda5da8dSAndroid Build Coastguard Worker mangle_from_ = False 167*cda5da8dSAndroid Build Coastguard Worker message_factory = None 168*cda5da8dSAndroid Build Coastguard Worker 169*cda5da8dSAndroid Build Coastguard Worker def handle_defect(self, obj, defect): 170*cda5da8dSAndroid Build Coastguard Worker """Based on policy, either raise defect or call register_defect. 171*cda5da8dSAndroid Build Coastguard Worker 172*cda5da8dSAndroid Build Coastguard Worker handle_defect(obj, defect) 173*cda5da8dSAndroid Build Coastguard Worker 174*cda5da8dSAndroid Build Coastguard Worker defect should be a Defect subclass, but in any case must be an 175*cda5da8dSAndroid Build Coastguard Worker Exception subclass. obj is the object on which the defect should be 176*cda5da8dSAndroid Build Coastguard Worker registered if it is not raised. If the raise_on_defect is True, the 177*cda5da8dSAndroid Build Coastguard Worker defect is raised as an error, otherwise the object and the defect are 178*cda5da8dSAndroid Build Coastguard Worker passed to register_defect. 179*cda5da8dSAndroid Build Coastguard Worker 180*cda5da8dSAndroid Build Coastguard Worker This method is intended to be called by parsers that discover defects. 181*cda5da8dSAndroid Build Coastguard Worker The email package parsers always call it with Defect instances. 182*cda5da8dSAndroid Build Coastguard Worker 183*cda5da8dSAndroid Build Coastguard Worker """ 184*cda5da8dSAndroid Build Coastguard Worker if self.raise_on_defect: 185*cda5da8dSAndroid Build Coastguard Worker raise defect 186*cda5da8dSAndroid Build Coastguard Worker self.register_defect(obj, defect) 187*cda5da8dSAndroid Build Coastguard Worker 188*cda5da8dSAndroid Build Coastguard Worker def register_defect(self, obj, defect): 189*cda5da8dSAndroid Build Coastguard Worker """Record 'defect' on 'obj'. 190*cda5da8dSAndroid Build Coastguard Worker 191*cda5da8dSAndroid Build Coastguard Worker Called by handle_defect if raise_on_defect is False. This method is 192*cda5da8dSAndroid Build Coastguard Worker part of the Policy API so that Policy subclasses can implement custom 193*cda5da8dSAndroid Build Coastguard Worker defect handling. The default implementation calls the append method of 194*cda5da8dSAndroid Build Coastguard Worker the defects attribute of obj. The objects used by the email package by 195*cda5da8dSAndroid Build Coastguard Worker default that get passed to this method will always have a defects 196*cda5da8dSAndroid Build Coastguard Worker attribute with an append method. 197*cda5da8dSAndroid Build Coastguard Worker 198*cda5da8dSAndroid Build Coastguard Worker """ 199*cda5da8dSAndroid Build Coastguard Worker obj.defects.append(defect) 200*cda5da8dSAndroid Build Coastguard Worker 201*cda5da8dSAndroid Build Coastguard Worker def header_max_count(self, name): 202*cda5da8dSAndroid Build Coastguard Worker """Return the maximum allowed number of headers named 'name'. 203*cda5da8dSAndroid Build Coastguard Worker 204*cda5da8dSAndroid Build Coastguard Worker Called when a header is added to a Message object. If the returned 205*cda5da8dSAndroid Build Coastguard Worker value is not 0 or None, and there are already a number of headers with 206*cda5da8dSAndroid Build Coastguard Worker the name 'name' equal to the value returned, a ValueError is raised. 207*cda5da8dSAndroid Build Coastguard Worker 208*cda5da8dSAndroid Build Coastguard Worker Because the default behavior of Message's __setitem__ is to append the 209*cda5da8dSAndroid Build Coastguard Worker value to the list of headers, it is easy to create duplicate headers 210*cda5da8dSAndroid Build Coastguard Worker without realizing it. This method allows certain headers to be limited 211*cda5da8dSAndroid Build Coastguard Worker in the number of instances of that header that may be added to a 212*cda5da8dSAndroid Build Coastguard Worker Message programmatically. (The limit is not observed by the parser, 213*cda5da8dSAndroid Build Coastguard Worker which will faithfully produce as many headers as exist in the message 214*cda5da8dSAndroid Build Coastguard Worker being parsed.) 215*cda5da8dSAndroid Build Coastguard Worker 216*cda5da8dSAndroid Build Coastguard Worker The default implementation returns None for all header names. 217*cda5da8dSAndroid Build Coastguard Worker """ 218*cda5da8dSAndroid Build Coastguard Worker return None 219*cda5da8dSAndroid Build Coastguard Worker 220*cda5da8dSAndroid Build Coastguard Worker @abc.abstractmethod 221*cda5da8dSAndroid Build Coastguard Worker def header_source_parse(self, sourcelines): 222*cda5da8dSAndroid Build Coastguard Worker """Given a list of linesep terminated strings constituting the lines of 223*cda5da8dSAndroid Build Coastguard Worker a single header, return the (name, value) tuple that should be stored 224*cda5da8dSAndroid Build Coastguard Worker in the model. The input lines should retain their terminating linesep 225*cda5da8dSAndroid Build Coastguard Worker characters. The lines passed in by the email package may contain 226*cda5da8dSAndroid Build Coastguard Worker surrogateescaped binary data. 227*cda5da8dSAndroid Build Coastguard Worker """ 228*cda5da8dSAndroid Build Coastguard Worker raise NotImplementedError 229*cda5da8dSAndroid Build Coastguard Worker 230*cda5da8dSAndroid Build Coastguard Worker @abc.abstractmethod 231*cda5da8dSAndroid Build Coastguard Worker def header_store_parse(self, name, value): 232*cda5da8dSAndroid Build Coastguard Worker """Given the header name and the value provided by the application 233*cda5da8dSAndroid Build Coastguard Worker program, return the (name, value) that should be stored in the model. 234*cda5da8dSAndroid Build Coastguard Worker """ 235*cda5da8dSAndroid Build Coastguard Worker raise NotImplementedError 236*cda5da8dSAndroid Build Coastguard Worker 237*cda5da8dSAndroid Build Coastguard Worker @abc.abstractmethod 238*cda5da8dSAndroid Build Coastguard Worker def header_fetch_parse(self, name, value): 239*cda5da8dSAndroid Build Coastguard Worker """Given the header name and the value from the model, return the value 240*cda5da8dSAndroid Build Coastguard Worker to be returned to the application program that is requesting that 241*cda5da8dSAndroid Build Coastguard Worker header. The value passed in by the email package may contain 242*cda5da8dSAndroid Build Coastguard Worker surrogateescaped binary data if the lines were parsed by a BytesParser. 243*cda5da8dSAndroid Build Coastguard Worker The returned value should not contain any surrogateescaped data. 244*cda5da8dSAndroid Build Coastguard Worker 245*cda5da8dSAndroid Build Coastguard Worker """ 246*cda5da8dSAndroid Build Coastguard Worker raise NotImplementedError 247*cda5da8dSAndroid Build Coastguard Worker 248*cda5da8dSAndroid Build Coastguard Worker @abc.abstractmethod 249*cda5da8dSAndroid Build Coastguard Worker def fold(self, name, value): 250*cda5da8dSAndroid Build Coastguard Worker """Given the header name and the value from the model, return a string 251*cda5da8dSAndroid Build Coastguard Worker containing linesep characters that implement the folding of the header 252*cda5da8dSAndroid Build Coastguard Worker according to the policy controls. The value passed in by the email 253*cda5da8dSAndroid Build Coastguard Worker package may contain surrogateescaped binary data if the lines were 254*cda5da8dSAndroid Build Coastguard Worker parsed by a BytesParser. The returned value should not contain any 255*cda5da8dSAndroid Build Coastguard Worker surrogateescaped data. 256*cda5da8dSAndroid Build Coastguard Worker 257*cda5da8dSAndroid Build Coastguard Worker """ 258*cda5da8dSAndroid Build Coastguard Worker raise NotImplementedError 259*cda5da8dSAndroid Build Coastguard Worker 260*cda5da8dSAndroid Build Coastguard Worker @abc.abstractmethod 261*cda5da8dSAndroid Build Coastguard Worker def fold_binary(self, name, value): 262*cda5da8dSAndroid Build Coastguard Worker """Given the header name and the value from the model, return binary 263*cda5da8dSAndroid Build Coastguard Worker data containing linesep characters that implement the folding of the 264*cda5da8dSAndroid Build Coastguard Worker header according to the policy controls. The value passed in by the 265*cda5da8dSAndroid Build Coastguard Worker email package may contain surrogateescaped binary data. 266*cda5da8dSAndroid Build Coastguard Worker 267*cda5da8dSAndroid Build Coastguard Worker """ 268*cda5da8dSAndroid Build Coastguard Worker raise NotImplementedError 269*cda5da8dSAndroid Build Coastguard Worker 270*cda5da8dSAndroid Build Coastguard Worker 271*cda5da8dSAndroid Build Coastguard Worker@_extend_docstrings 272*cda5da8dSAndroid Build Coastguard Workerclass Compat32(Policy): 273*cda5da8dSAndroid Build Coastguard Worker 274*cda5da8dSAndroid Build Coastguard Worker """+ 275*cda5da8dSAndroid Build Coastguard Worker This particular policy is the backward compatibility Policy. It 276*cda5da8dSAndroid Build Coastguard Worker replicates the behavior of the email package version 5.1. 277*cda5da8dSAndroid Build Coastguard Worker """ 278*cda5da8dSAndroid Build Coastguard Worker 279*cda5da8dSAndroid Build Coastguard Worker mangle_from_ = True 280*cda5da8dSAndroid Build Coastguard Worker 281*cda5da8dSAndroid Build Coastguard Worker def _sanitize_header(self, name, value): 282*cda5da8dSAndroid Build Coastguard Worker # If the header value contains surrogates, return a Header using 283*cda5da8dSAndroid Build Coastguard Worker # the unknown-8bit charset to encode the bytes as encoded words. 284*cda5da8dSAndroid Build Coastguard Worker if not isinstance(value, str): 285*cda5da8dSAndroid Build Coastguard Worker # Assume it is already a header object 286*cda5da8dSAndroid Build Coastguard Worker return value 287*cda5da8dSAndroid Build Coastguard Worker if _has_surrogates(value): 288*cda5da8dSAndroid Build Coastguard Worker return header.Header(value, charset=_charset.UNKNOWN8BIT, 289*cda5da8dSAndroid Build Coastguard Worker header_name=name) 290*cda5da8dSAndroid Build Coastguard Worker else: 291*cda5da8dSAndroid Build Coastguard Worker return value 292*cda5da8dSAndroid Build Coastguard Worker 293*cda5da8dSAndroid Build Coastguard Worker def header_source_parse(self, sourcelines): 294*cda5da8dSAndroid Build Coastguard Worker """+ 295*cda5da8dSAndroid Build Coastguard Worker The name is parsed as everything up to the ':' and returned unmodified. 296*cda5da8dSAndroid Build Coastguard Worker The value is determined by stripping leading whitespace off the 297*cda5da8dSAndroid Build Coastguard Worker remainder of the first line, joining all subsequent lines together, and 298*cda5da8dSAndroid Build Coastguard Worker stripping any trailing carriage return or linefeed characters. 299*cda5da8dSAndroid Build Coastguard Worker 300*cda5da8dSAndroid Build Coastguard Worker """ 301*cda5da8dSAndroid Build Coastguard Worker name, value = sourcelines[0].split(':', 1) 302*cda5da8dSAndroid Build Coastguard Worker value = value.lstrip(' \t') + ''.join(sourcelines[1:]) 303*cda5da8dSAndroid Build Coastguard Worker return (name, value.rstrip('\r\n')) 304*cda5da8dSAndroid Build Coastguard Worker 305*cda5da8dSAndroid Build Coastguard Worker def header_store_parse(self, name, value): 306*cda5da8dSAndroid Build Coastguard Worker """+ 307*cda5da8dSAndroid Build Coastguard Worker The name and value are returned unmodified. 308*cda5da8dSAndroid Build Coastguard Worker """ 309*cda5da8dSAndroid Build Coastguard Worker return (name, value) 310*cda5da8dSAndroid Build Coastguard Worker 311*cda5da8dSAndroid Build Coastguard Worker def header_fetch_parse(self, name, value): 312*cda5da8dSAndroid Build Coastguard Worker """+ 313*cda5da8dSAndroid Build Coastguard Worker If the value contains binary data, it is converted into a Header object 314*cda5da8dSAndroid Build Coastguard Worker using the unknown-8bit charset. Otherwise it is returned unmodified. 315*cda5da8dSAndroid Build Coastguard Worker """ 316*cda5da8dSAndroid Build Coastguard Worker return self._sanitize_header(name, value) 317*cda5da8dSAndroid Build Coastguard Worker 318*cda5da8dSAndroid Build Coastguard Worker def fold(self, name, value): 319*cda5da8dSAndroid Build Coastguard Worker """+ 320*cda5da8dSAndroid Build Coastguard Worker Headers are folded using the Header folding algorithm, which preserves 321*cda5da8dSAndroid Build Coastguard Worker existing line breaks in the value, and wraps each resulting line to the 322*cda5da8dSAndroid Build Coastguard Worker max_line_length. Non-ASCII binary data are CTE encoded using the 323*cda5da8dSAndroid Build Coastguard Worker unknown-8bit charset. 324*cda5da8dSAndroid Build Coastguard Worker 325*cda5da8dSAndroid Build Coastguard Worker """ 326*cda5da8dSAndroid Build Coastguard Worker return self._fold(name, value, sanitize=True) 327*cda5da8dSAndroid Build Coastguard Worker 328*cda5da8dSAndroid Build Coastguard Worker def fold_binary(self, name, value): 329*cda5da8dSAndroid Build Coastguard Worker """+ 330*cda5da8dSAndroid Build Coastguard Worker Headers are folded using the Header folding algorithm, which preserves 331*cda5da8dSAndroid Build Coastguard Worker existing line breaks in the value, and wraps each resulting line to the 332*cda5da8dSAndroid Build Coastguard Worker max_line_length. If cte_type is 7bit, non-ascii binary data is CTE 333*cda5da8dSAndroid Build Coastguard Worker encoded using the unknown-8bit charset. Otherwise the original source 334*cda5da8dSAndroid Build Coastguard Worker header is used, with its existing line breaks and/or binary data. 335*cda5da8dSAndroid Build Coastguard Worker 336*cda5da8dSAndroid Build Coastguard Worker """ 337*cda5da8dSAndroid Build Coastguard Worker folded = self._fold(name, value, sanitize=self.cte_type=='7bit') 338*cda5da8dSAndroid Build Coastguard Worker return folded.encode('ascii', 'surrogateescape') 339*cda5da8dSAndroid Build Coastguard Worker 340*cda5da8dSAndroid Build Coastguard Worker def _fold(self, name, value, sanitize): 341*cda5da8dSAndroid Build Coastguard Worker parts = [] 342*cda5da8dSAndroid Build Coastguard Worker parts.append('%s: ' % name) 343*cda5da8dSAndroid Build Coastguard Worker if isinstance(value, str): 344*cda5da8dSAndroid Build Coastguard Worker if _has_surrogates(value): 345*cda5da8dSAndroid Build Coastguard Worker if sanitize: 346*cda5da8dSAndroid Build Coastguard Worker h = header.Header(value, 347*cda5da8dSAndroid Build Coastguard Worker charset=_charset.UNKNOWN8BIT, 348*cda5da8dSAndroid Build Coastguard Worker header_name=name) 349*cda5da8dSAndroid Build Coastguard Worker else: 350*cda5da8dSAndroid Build Coastguard Worker # If we have raw 8bit data in a byte string, we have no idea 351*cda5da8dSAndroid Build Coastguard Worker # what the encoding is. There is no safe way to split this 352*cda5da8dSAndroid Build Coastguard Worker # string. If it's ascii-subset, then we could do a normal 353*cda5da8dSAndroid Build Coastguard Worker # ascii split, but if it's multibyte then we could break the 354*cda5da8dSAndroid Build Coastguard Worker # string. There's no way to know so the least harm seems to 355*cda5da8dSAndroid Build Coastguard Worker # be to not split the string and risk it being too long. 356*cda5da8dSAndroid Build Coastguard Worker parts.append(value) 357*cda5da8dSAndroid Build Coastguard Worker h = None 358*cda5da8dSAndroid Build Coastguard Worker else: 359*cda5da8dSAndroid Build Coastguard Worker h = header.Header(value, header_name=name) 360*cda5da8dSAndroid Build Coastguard Worker else: 361*cda5da8dSAndroid Build Coastguard Worker # Assume it is a Header-like object. 362*cda5da8dSAndroid Build Coastguard Worker h = value 363*cda5da8dSAndroid Build Coastguard Worker if h is not None: 364*cda5da8dSAndroid Build Coastguard Worker # The Header class interprets a value of None for maxlinelen as the 365*cda5da8dSAndroid Build Coastguard Worker # default value of 78, as recommended by RFC 2822. 366*cda5da8dSAndroid Build Coastguard Worker maxlinelen = 0 367*cda5da8dSAndroid Build Coastguard Worker if self.max_line_length is not None: 368*cda5da8dSAndroid Build Coastguard Worker maxlinelen = self.max_line_length 369*cda5da8dSAndroid Build Coastguard Worker parts.append(h.encode(linesep=self.linesep, maxlinelen=maxlinelen)) 370*cda5da8dSAndroid Build Coastguard Worker parts.append(self.linesep) 371*cda5da8dSAndroid Build Coastguard Worker return ''.join(parts) 372*cda5da8dSAndroid Build Coastguard Worker 373*cda5da8dSAndroid Build Coastguard Worker 374*cda5da8dSAndroid Build Coastguard Workercompat32 = Compat32() 375