<s> import collections <EOL> from datetime import ( <EOL> date , <EOL> datetime , <EOL> timedelta , <EOL> ) <EOL> import re <EOL> import string <EOL> import time <EOL> from webob . compat import ( <EOL> PY3 , <EOL> text_type , <EOL> bytes_ , <EOL> text_ , <EOL> native_ , <EOL> string_types , <EOL> ) <EOL> __all__ = [ '<STR_LIT>' ] <EOL> _marker = object ( ) <EOL> class RequestCookies ( collections . MutableMapping ) : <EOL> _cache_key = '<STR_LIT>' <EOL> def __init__ ( self , environ ) : <EOL> self . _environ = environ <EOL> @ property <EOL> def _cache ( self ) : <EOL> env = self . _environ <EOL> header = env . get ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> cache , cache_header = env . get ( self . _cache_key , ( { } , None ) ) <EOL> if cache_header == header : <EOL> return cache <EOL> d = lambda b : b . decode ( '<STR_LIT:utf8>' ) <EOL> cache = dict ( ( d ( k ) , d ( v ) ) for k , v in parse_cookie ( header ) ) <EOL> env [ self . _cache_key ] = ( cache , header ) <EOL> return cache <EOL> def _mutate_header ( self , name , value ) : <EOL> header = self . _environ . get ( '<STR_LIT>' ) <EOL> had_header = header is not None <EOL> header = header or '<STR_LIT>' <EOL> if PY3 : <EOL> header = header . encode ( '<STR_LIT>' ) <EOL> bytes_name = bytes_ ( name , '<STR_LIT:ascii>' ) <EOL> if value is None : <EOL> replacement = None <EOL> else : <EOL> bytes_val = _quote ( bytes_ ( value , '<STR_LIT:utf-8>' ) ) <EOL> replacement = bytes_name + b'<STR_LIT:=>' + bytes_val <EOL> matches = _rx_cookie . finditer ( header ) <EOL> found = False <EOL> for match in matches : <EOL> start , end = match . span ( ) <EOL> match_name = match . group ( <NUM_LIT:1> ) <EOL> if match_name == bytes_name : <EOL> found = True <EOL> if replacement is None : <EOL> header = header [ : start ] . rstrip ( b'<STR_LIT>' ) + header [ end : ] <EOL> else : <EOL> header = header [ : start ] + replacement + header [ end : ] <EOL> break <EOL> else : <EOL> if replacement is not None : <EOL> if header : <EOL> header += b'<STR_LIT>' + replacement <EOL> else : <EOL> header = replacement <EOL> if header : <EOL> self . _environ [ '<STR_LIT>' ] = native_ ( header , '<STR_LIT>' ) <EOL> elif had_header : <EOL> self . _environ [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> return found <EOL> def _valid_cookie_name ( self , name ) : <EOL> if not isinstance ( name , string_types ) : <EOL> raise TypeError ( name , '<STR_LIT>' ) <EOL> if not isinstance ( name , text_type ) : <EOL> name = text_ ( name , '<STR_LIT:utf-8>' ) <EOL> try : <EOL> bytes_cookie_name = bytes_ ( name , '<STR_LIT:ascii>' ) <EOL> except UnicodeEncodeError : <EOL> raise TypeError ( '<STR_LIT>' ) <EOL> if not _valid_cookie_name ( bytes_cookie_name ) : <EOL> raise TypeError ( '<STR_LIT>' ) <EOL> return name <EOL> def __setitem__ ( self , name , value ) : <EOL> name = self . _valid_cookie_name ( name ) <EOL> if not isinstance ( value , string_types ) : <EOL> raise ValueError ( value , '<STR_LIT>' ) <EOL> if not isinstance ( value , text_type ) : <EOL> try : <EOL> value = text_ ( value , '<STR_LIT:utf-8>' ) <EOL> except UnicodeDecodeError : <EOL> raise ValueError ( <EOL> value , '<STR_LIT>' ) <EOL> self . _mutate_header ( name , value ) <EOL> def __getitem__ ( self , name ) : <EOL> return self . _cache [ name ] <EOL> def get ( self , name , default = None ) : <EOL> return self . _cache . get ( name , default ) <EOL> def __delitem__ ( self , name ) : <EOL> name = self . _valid_cookie_name ( name ) <EOL> found = self . _mutate_header ( name , None ) <EOL> if not found : <EOL> raise KeyError ( name ) <EOL> def keys ( self ) : <EOL> return self . _cache . keys ( ) <EOL> def values ( self ) : <EOL> return self . _cache . values ( ) <EOL> def items ( self ) : <EOL> return self . _cache . items ( ) <EOL> if not PY3 : <EOL> def iterkeys ( self ) : <EOL> return self . _cache . iterkeys ( ) <EOL> def itervalues ( self ) : <EOL> return self . _cache . itervalues ( ) <EOL> def iteritems ( self ) : <EOL> return self . _cache . iteritems ( ) <EOL> def __contains__ ( self , name ) : <EOL> return name in self . _cache <EOL> def __iter__ ( self ) : <EOL> return self . _cache . __iter__ ( ) <EOL> def __len__ ( self ) : <EOL> return len ( self . _cache ) <EOL> def clear ( self ) : <EOL> self . _environ [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> def __repr__ ( self ) : <EOL> return '<STR_LIT>' % ( self . _cache , ) <EOL> class Cookie ( dict ) : <EOL> def __init__ ( self , input = None ) : <EOL> if input : <EOL> self . load ( input ) <EOL> def load ( self , data ) : <EOL> morsel = { } <EOL> for key , val in _parse_cookie ( data ) : <EOL> if key . lower ( ) in _c_keys : <EOL> morsel [ key ] = val <EOL> else : <EOL> morsel = self . add ( key , val ) <EOL> def add ( self , key , val ) : <EOL> if not isinstance ( key , bytes ) : <EOL> key = key . encode ( '<STR_LIT:ascii>' , '<STR_LIT:replace>' ) <EOL> if not _valid_cookie_name ( key ) : <EOL> return { } <EOL> r = Morsel ( key , val ) <EOL> dict . __setitem__ ( self , key , r ) <EOL> return r <EOL> __setitem__ = add <EOL> def serialize ( self , full = True ) : <EOL> return '<STR_LIT>' . join ( m . serialize ( full ) for m in self . values ( ) ) <EOL> def values ( self ) : <EOL> return [ m for _ , m in sorted ( self . items ( ) ) ] <EOL> __str__ = serialize <EOL> def __repr__ ( self ) : <EOL> return '<STR_LIT>' % ( self . __class__ . __name__ , <EOL> '<STR_LIT:U+002CU+0020>' . join ( map ( repr , self . values ( ) ) ) ) <EOL> def _parse_cookie ( data ) : <EOL> if PY3 : <EOL> data = data . encode ( '<STR_LIT>' ) <EOL> for key , val in _rx_cookie . findall ( data ) : <EOL> yield key , _unquote ( val ) <EOL> def parse_cookie ( data ) : <EOL> """<STR_LIT>""" <EOL> return ( ( k , v ) for k , v in _parse_cookie ( data ) if _valid_cookie_name ( k ) ) <EOL> def cookie_property ( key , serialize = lambda v : v ) : <EOL> def fset ( self , v ) : <EOL> self [ key ] = serialize ( v ) <EOL> return property ( lambda self : self [ key ] , fset ) <EOL> def serialize_max_age ( v ) : <EOL> if isinstance ( v , timedelta ) : <EOL> v = str ( v . seconds + v . days * <NUM_LIT> * <NUM_LIT> * <NUM_LIT> ) <EOL> elif isinstance ( v , int ) : <EOL> v = str ( v ) <EOL> return bytes_ ( v ) <EOL> def serialize_cookie_date ( v ) : <EOL> if v is None : <EOL> return None <EOL> elif isinstance ( v , bytes ) : <EOL> return v <EOL> elif isinstance ( v , text_type ) : <EOL> return v . encode ( '<STR_LIT:ascii>' ) <EOL> elif isinstance ( v , int ) : <EOL> v = timedelta ( seconds = v ) <EOL> if isinstance ( v , timedelta ) : <EOL> v = datetime . utcnow ( ) + v <EOL> if isinstance ( v , ( datetime , date ) ) : <EOL> v = v . timetuple ( ) <EOL> r = time . strftime ( '<STR_LIT>' , v ) <EOL> return bytes_ ( r % ( weekdays [ v [ <NUM_LIT:6> ] ] , months [ v [ <NUM_LIT:1> ] ] ) , '<STR_LIT:ascii>' ) <EOL> class Morsel ( dict ) : <EOL> __slots__ = ( '<STR_LIT:name>' , '<STR_LIT:value>' ) <EOL> def __init__ ( self , name , value ) : <EOL> assert _valid_cookie_name ( name ) <EOL> assert isinstance ( value , bytes ) <EOL> self . name = name <EOL> self . value = value <EOL> self . update ( dict . fromkeys ( _c_keys , None ) ) <EOL> path = cookie_property ( b'<STR_LIT:path>' ) <EOL> domain = cookie_property ( b'<STR_LIT>' ) <EOL> comment = cookie_property ( b'<STR_LIT>' ) <EOL> expires = cookie_property ( b'<STR_LIT>' , serialize_cookie_date ) <EOL> max_age = cookie_property ( b'<STR_LIT>' , serialize_max_age ) <EOL> httponly = cookie_property ( b'<STR_LIT>' , bool ) <EOL> secure = cookie_property ( b'<STR_LIT>' , bool ) <EOL> def __setitem__ ( self , k , v ) : <EOL> k = bytes_ ( k . lower ( ) , '<STR_LIT:ascii>' ) <EOL> if k in _c_keys : <EOL> dict . __setitem__ ( self , k , v ) <EOL> def serialize ( self , full = True ) : <EOL> result = [ ] <EOL> add = result . append <EOL> add ( self . name + b'<STR_LIT:=>' + _quote ( self . value ) ) <EOL> if full : <EOL> for k in _c_valkeys : <EOL> v = self [ k ] <EOL> if v : <EOL> add ( _c_renames [ k ] + b'<STR_LIT:=>' + _quote ( v ) ) <EOL> expires = self [ b'<STR_LIT>' ] <EOL> if expires : <EOL> add ( b'<STR_LIT>' + expires ) <EOL> if self . secure : <EOL> add ( b'<STR_LIT>' ) <EOL> if self . httponly : <EOL> add ( b'<STR_LIT>' ) <EOL> return native_ ( b'<STR_LIT>' . join ( result ) , '<STR_LIT:ascii>' ) <EOL> __str__ = serialize <EOL> def __repr__ ( self ) : <EOL> return '<STR_LIT>' % ( self . __class__ . __name__ , <EOL> native_ ( self . name ) , <EOL> native_ ( self . value ) <EOL> ) <EOL> _c_renames = { <EOL> b"<STR_LIT:path>" : b"<STR_LIT>" , <EOL> b"<STR_LIT>" : b"<STR_LIT>" , <EOL> b"<STR_LIT>" : b"<STR_LIT>" , <EOL> b"<STR_LIT>" : b"<STR_LIT>" , <EOL> } <EOL> _c_valkeys = sorted ( _c_renames ) <EOL> _c_keys = set ( _c_renames ) <EOL> _c_keys . update ( [ b'<STR_LIT>' , b'<STR_LIT>' , b'<STR_LIT>' ] ) <EOL> _re_quoted = r'<STR_LIT>' <EOL> _legal_special_chars = "<STR_LIT>" <EOL> _re_legal_char = r"<STR_LIT>" % re . escape ( _legal_special_chars ) <EOL> _re_expires_val = r"<STR_LIT>" <EOL> _re_cookie_str_key = r"<STR_LIT>" % _re_legal_char <EOL> _re_cookie_str_equal = r"<STR_LIT>" <EOL> _re_unquoted_val = r"<STR_LIT>" % _re_legal_char <EOL> _re_cookie_str_val = r"<STR_LIT>" % ( _re_quoted , _re_expires_val , <EOL> _re_unquoted_val ) <EOL> _re_cookie_str = _re_cookie_str_key + _re_cookie_str_equal + _re_cookie_str_val <EOL> _rx_cookie = re . compile ( bytes_ ( _re_cookie_str , '<STR_LIT:ascii>' ) ) <EOL> _rx_unquote = re . compile ( bytes_ ( r'<STR_LIT>' , '<STR_LIT:ascii>' ) ) <EOL> _bchr = ( lambda i : bytes ( [ i ] ) ) if PY3 else chr <EOL> _ch_unquote_map = dict ( ( bytes_ ( '<STR_LIT>' % i ) , _bchr ( i ) ) <EOL> for i in range ( <NUM_LIT> ) <EOL> ) <EOL> _ch_unquote_map . update ( ( v , v ) for v in list ( _ch_unquote_map . values ( ) ) ) <EOL> _b_dollar_sign = <NUM_LIT> if PY3 else '<STR_LIT:$>' <EOL> _b_quote_mark = <NUM_LIT> if PY3 else '<STR_LIT:">' <EOL> def _unquote ( v ) : <EOL> if v and v [ <NUM_LIT:0> ] == v [ - <NUM_LIT:1> ] == _b_quote_mark : <EOL> v = v [ <NUM_LIT:1> : - <NUM_LIT:1> ] <EOL> return _rx_unquote . sub ( _ch_unquote , v ) <EOL> def _ch_unquote ( m ) : <EOL> return _ch_unquote_map [ m . group ( <NUM_LIT:1> ) ] <EOL> _no_escape_special_chars = "<STR_LIT>" <EOL> _no_escape_chars = ( string . ascii_letters + string . digits + <EOL> _no_escape_special_chars ) <EOL> _no_escape_bytes = bytes_ ( _no_escape_chars ) <EOL> _escape_noop_chars = _no_escape_chars + '<STR_LIT>' <EOL> _escape_map = dict ( ( chr ( i ) , '<STR_LIT>' % i ) for i in range ( <NUM_LIT> ) ) <EOL> _escape_map . update ( zip ( _escape_noop_chars , _escape_noop_chars ) ) <EOL> _escape_map [ '<STR_LIT:">' ] = r'<STR_LIT>' <EOL> _escape_map [ '<STR_LIT:\\>' ] = r'<STR_LIT:\\>' <EOL> if PY3 : <EOL> _escape_map = dict ( ( ord ( k ) , bytes_ ( v , '<STR_LIT:ascii>' ) ) for k , v in _escape_map . items ( ) ) <EOL> _escape_char = _escape_map . __getitem__ <EOL> weekdays = ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) <EOL> months = ( None , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) <EOL> _notrans_binary = b'<STR_LIT:U+0020>' * <NUM_LIT> <EOL> def _needs_quoting ( v ) : <EOL> return v . translate ( _notrans_binary , _no_escape_bytes ) <EOL> def _quote ( v ) : <EOL> if _needs_quoting ( v ) : <EOL> return b'<STR_LIT:">' + b'<STR_LIT>' . join ( map ( _escape_char , v ) ) + b'<STR_LIT:">' <EOL> return v <EOL> def _valid_cookie_name ( key ) : <EOL> return isinstance ( key , bytes ) and not ( <EOL> _needs_quoting ( key ) <EOL> or key [ <NUM_LIT:0> ] == _b_dollar_sign <EOL> or key . lower ( ) in _c_keys <EOL> ) </s>
