NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

Cookie.py (11241B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\stdlib\Cookie.py
      2 import string
      3 try:
      4     from cPickle import dumps, loads
      5 except ImportError:
      6     from pickle import dumps, loads
      7 
      8 import re, warnings
      9 __all__ = ['CookieError',
     10  'BaseCookie',
     11  'SimpleCookie',
     12  'SerialCookie',
     13  'SmartCookie',
     14  'Cookie']
     15 _nulljoin = ''.join
     16 _semispacejoin = '; '.join
     17 _spacejoin = ' '.join
     18 
     19 class CookieError(Exception):
     20     pass
     21 
     22 
     23 _LegalChars = string.ascii_letters + string.digits + "!#$%&'*+-.^_`|~"
     24 _Translator = {'\x00': '\\000',
     25  '\x01': '\\001',
     26  '\x02': '\\002',
     27  '\x03': '\\003',
     28  '\x04': '\\004',
     29  '\x05': '\\005',
     30  '\x06': '\\006',
     31  '\x07': '\\007',
     32  '\x08': '\\010',
     33  '\t': '\\011',
     34  '\n': '\\012',
     35  '\x0b': '\\013',
     36  '\x0c': '\\014',
     37  '\r': '\\015',
     38  '\x0e': '\\016',
     39  '\x0f': '\\017',
     40  '\x10': '\\020',
     41  '\x11': '\\021',
     42  '\x12': '\\022',
     43  '\x13': '\\023',
     44  '\x14': '\\024',
     45  '\x15': '\\025',
     46  '\x16': '\\026',
     47  '\x17': '\\027',
     48  '\x18': '\\030',
     49  '\x19': '\\031',
     50  '\x1a': '\\032',
     51  '\x1b': '\\033',
     52  '\x1c': '\\034',
     53  '\x1d': '\\035',
     54  '\x1e': '\\036',
     55  '\x1f': '\\037',
     56  '"': '\\"',
     57  '\\': '\\\\',
     58  '\x7f': '\\177',
     59  '\x80': '\\200',
     60  '\x81': '\\201',
     61  '\x82': '\\202',
     62  '\x83': '\\203',
     63  '\x84': '\\204',
     64  '\x85': '\\205',
     65  '\x86': '\\206',
     66  '\x87': '\\207',
     67  '\x88': '\\210',
     68  '\x89': '\\211',
     69  '\x8a': '\\212',
     70  '\x8b': '\\213',
     71  '\x8c': '\\214',
     72  '\x8d': '\\215',
     73  '\x8e': '\\216',
     74  '\x8f': '\\217',
     75  '\x90': '\\220',
     76  '\x91': '\\221',
     77  '\x92': '\\222',
     78  '\x93': '\\223',
     79  '\x94': '\\224',
     80  '\x95': '\\225',
     81  '\x96': '\\226',
     82  '\x97': '\\227',
     83  '\x98': '\\230',
     84  '\x99': '\\231',
     85  '\x9a': '\\232',
     86  '\x9b': '\\233',
     87  '\x9c': '\\234',
     88  '\x9d': '\\235',
     89  '\x9e': '\\236',
     90  '\x9f': '\\237',
     91  '\xa0': '\\240',
     92  '\xa1': '\\241',
     93  '\xa2': '\\242',
     94  '\xa3': '\\243',
     95  '\xa4': '\\244',
     96  '\xa5': '\\245',
     97  '\xa6': '\\246',
     98  '\xa7': '\\247',
     99  '\xa8': '\\250',
    100  '\xa9': '\\251',
    101  '\xaa': '\\252',
    102  '\xab': '\\253',
    103  '\xac': '\\254',
    104  '\xad': '\\255',
    105  '\xae': '\\256',
    106  '\xaf': '\\257',
    107  '\xb0': '\\260',
    108  '\xb1': '\\261',
    109  '\xb2': '\\262',
    110  '\xb3': '\\263',
    111  '\xb4': '\\264',
    112  '\xb5': '\\265',
    113  '\xb6': '\\266',
    114  '\xb7': '\\267',
    115  '\xb8': '\\270',
    116  '\xb9': '\\271',
    117  '\xba': '\\272',
    118  '\xbb': '\\273',
    119  '\xbc': '\\274',
    120  '\xbd': '\\275',
    121  '\xbe': '\\276',
    122  '\xbf': '\\277',
    123  '\xc0': '\\300',
    124  '\xc1': '\\301',
    125  '\xc2': '\\302',
    126  '\xc3': '\\303',
    127  '\xc4': '\\304',
    128  '\xc5': '\\305',
    129  '\xc6': '\\306',
    130  '\xc7': '\\307',
    131  '\xc8': '\\310',
    132  '\xc9': '\\311',
    133  '\xca': '\\312',
    134  '\xcb': '\\313',
    135  '\xcc': '\\314',
    136  '\xcd': '\\315',
    137  '\xce': '\\316',
    138  '\xcf': '\\317',
    139  '\xd0': '\\320',
    140  '\xd1': '\\321',
    141  '\xd2': '\\322',
    142  '\xd3': '\\323',
    143  '\xd4': '\\324',
    144  '\xd5': '\\325',
    145  '\xd6': '\\326',
    146  '\xd7': '\\327',
    147  '\xd8': '\\330',
    148  '\xd9': '\\331',
    149  '\xda': '\\332',
    150  '\xdb': '\\333',
    151  '\xdc': '\\334',
    152  '\xdd': '\\335',
    153  '\xde': '\\336',
    154  '\xdf': '\\337',
    155  '\xe0': '\\340',
    156  '\xe1': '\\341',
    157  '\xe2': '\\342',
    158  '\xe3': '\\343',
    159  '\xe4': '\\344',
    160  '\xe5': '\\345',
    161  '\xe6': '\\346',
    162  '\xe7': '\\347',
    163  '\xe8': '\\350',
    164  '\xe9': '\\351',
    165  '\xea': '\\352',
    166  '\xeb': '\\353',
    167  '\xec': '\\354',
    168  '\xed': '\\355',
    169  '\xee': '\\356',
    170  '\xef': '\\357',
    171  '\xf0': '\\360',
    172  '\xf1': '\\361',
    173  '\xf2': '\\362',
    174  '\xf3': '\\363',
    175  '\xf4': '\\364',
    176  '\xf5': '\\365',
    177  '\xf6': '\\366',
    178  '\xf7': '\\367',
    179  '\xf8': '\\370',
    180  '\xf9': '\\371',
    181  '\xfa': '\\372',
    182  '\xfb': '\\373',
    183  '\xfc': '\\374',
    184  '\xfd': '\\375',
    185  '\xfe': '\\376',
    186  '\xff': '\\377'}
    187 _idmap = ''.join((chr(x) for x in xrange(256)))
    188 
    189 def _quote(str, LegalChars = _LegalChars, idmap = _idmap, translate = string.translate):
    190     if '' == translate(str, idmap, LegalChars):
    191         return str
    192     else:
    193         return '"' + _nulljoin(map(_Translator.get, str, str)) + '"'
    194 
    195 
    196 _OctalPatt = re.compile('\\\\[0-3][0-7][0-7]')
    197 _QuotePatt = re.compile('[\\\\].')
    198 
    199 def _unquote(str):
    200     if len(str) < 2:
    201         return str
    202     if str[0] != '"' or str[-1] != '"':
    203         return str
    204     str = str[1:-1]
    205     i = 0
    206     n = len(str)
    207     res = []
    208     while 0 <= i < n:
    209         Omatch = _OctalPatt.search(str, i)
    210         Qmatch = _QuotePatt.search(str, i)
    211         if not Omatch and not Qmatch:
    212             res.append(str[i:])
    213             break
    214         j = k = -1
    215         if Omatch:
    216             j = Omatch.start(0)
    217         if Qmatch:
    218             k = Qmatch.start(0)
    219         if Qmatch and (not Omatch or k < j):
    220             res.append(str[i:k])
    221             res.append(str[k + 1])
    222             i = k + 2
    223         else:
    224             res.append(str[i:j])
    225             res.append(chr(int(str[j + 1:j + 4], 8)))
    226             i = j + 4
    227 
    228     return _nulljoin(res)
    229 
    230 
    231 _weekdayname = ['Mon',
    232  'Tue',
    233  'Wed',
    234  'Thu',
    235  'Fri',
    236  'Sat',
    237  'Sun']
    238 _monthname = [None,
    239  'Jan',
    240  'Feb',
    241  'Mar',
    242  'Apr',
    243  'May',
    244  'Jun',
    245  'Jul',
    246  'Aug',
    247  'Sep',
    248  'Oct',
    249  'Nov',
    250  'Dec']
    251 
    252 def _getdate(future = 0, weekdayname = _weekdayname, monthname = _monthname):
    253     from time import gmtime, time
    254     now = time()
    255     year, month, day, hh, mm, ss, wd, y, z = gmtime(now + future)
    256     return '%s, %02d-%3s-%4d %02d:%02d:%02d GMT' % (weekdayname[wd],
    257      day,
    258      monthname[month],
    259      year,
    260      hh,
    261      mm,
    262      ss)
    263 
    264 
    265 class Morsel(dict):
    266     _reserved = {'expires': 'expires',
    267      'path': 'Path',
    268      'comment': 'Comment',
    269      'domain': 'Domain',
    270      'max-age': 'Max-Age',
    271      'secure': 'secure',
    272      'httponly': 'httponly',
    273      'version': 'Version'}
    274 
    275     def __init__(self):
    276         self.key = self.value = self.coded_value = None
    277         for K in self._reserved:
    278             dict.__setitem__(self, K, '')
    279 
    280     def __setitem__(self, K, V):
    281         K = K.lower()
    282         if K not in self._reserved:
    283             raise CookieError('Invalid Attribute %s' % K)
    284         dict.__setitem__(self, K, V)
    285 
    286     def isReservedKey(self, K):
    287         return K.lower() in self._reserved
    288 
    289     def set(self, key, val, coded_val, LegalChars = _LegalChars, idmap = _idmap, translate = string.translate):
    290         if key.lower() in self._reserved:
    291             raise CookieError('Attempt to set a reserved key: %s' % key)
    292         if '' != translate(key, idmap, LegalChars):
    293             raise CookieError('Illegal key value: %s' % key)
    294         self.key = key
    295         self.value = val
    296         self.coded_value = coded_val
    297 
    298     def output(self, attrs = None, header = 'Set-Cookie:'):
    299         return '%s %s' % (header, self.OutputString(attrs))
    300 
    301     __str__ = output
    302 
    303     def __repr__(self):
    304         return '<%s: %s=%s>' % (self.__class__.__name__, self.key, repr(self.value))
    305 
    306     def js_output(self, attrs = None):
    307         return '\n        <script type="text/javascript">\n        <!-- begin hiding\n        document.cookie = "%s";\n        // end hiding -->\n        </script>\n        ' % (self.OutputString(attrs).replace('"', '\\"'),)
    308 
    309     def OutputString(self, attrs = None):
    310         result = []
    311         RA = result.append
    312         RA('%s=%s' % (self.key, self.coded_value))
    313         if attrs is None:
    314             attrs = self._reserved
    315         items = self.items()
    316         items.sort()
    317         for K, V in items:
    318             if V == '':
    319                 continue
    320             if K not in attrs:
    321                 continue
    322             if K == 'expires' and type(V) == type(1):
    323                 RA('%s=%s' % (self._reserved[K], _getdate(V)))
    324             elif K == 'max-age' and type(V) == type(1):
    325                 RA('%s=%d' % (self._reserved[K], V))
    326             elif K == 'secure':
    327                 RA(str(self._reserved[K]))
    328             elif K == 'httponly':
    329                 RA(str(self._reserved[K]))
    330             else:
    331                 RA('%s=%s' % (self._reserved[K], V))
    332 
    333         return _semispacejoin(result)
    334 
    335 
    336 _LegalCharsPatt = "[\\w\\d!#%&'~_`><@,:/\\$\\*\\+\\-\\.\\^\\|\\)\\(\\?\\}\\{\\=]"
    337 _CookiePattern = re.compile('(?x)(?P<key>' + _LegalCharsPatt + '+?)\\s*=\\s*(?P<val>"(?:[^\\\\"]|\\\\.)*"|\\w{3},\\s[\\w\\d-]{9,11}\\s[\\d:]{8}\\sGMT|' + _LegalCharsPatt + '*)\\s*;?')
    338 
    339 class BaseCookie(dict):
    340 
    341     def value_decode(self, val):
    342         return (val, val)
    343 
    344     def value_encode(self, val):
    345         strval = str(val)
    346         return (strval, strval)
    347 
    348     def __init__(self, input = None):
    349         if input:
    350             self.load(input)
    351 
    352     def __set(self, key, real_value, coded_value):
    353         M = self.get(key, Morsel())
    354         M.set(key, real_value, coded_value)
    355         dict.__setitem__(self, key, M)
    356 
    357     def __setitem__(self, key, value):
    358         rval, cval = self.value_encode(value)
    359         self.__set(key, rval, cval)
    360 
    361     def output(self, attrs = None, header = 'Set-Cookie:', sep = '\r\n'):
    362         result = []
    363         items = self.items()
    364         items.sort()
    365         for K, V in items:
    366             result.append(V.output(attrs, header))
    367 
    368         return sep.join(result)
    369 
    370     __str__ = output
    371 
    372     def __repr__(self):
    373         L = []
    374         items = self.items()
    375         items.sort()
    376         for K, V in items:
    377             L.append('%s=%s' % (K, repr(V.value)))
    378 
    379         return '<%s: %s>' % (self.__class__.__name__, _spacejoin(L))
    380 
    381     def js_output(self, attrs = None):
    382         result = []
    383         items = self.items()
    384         items.sort()
    385         for K, V in items:
    386             result.append(V.js_output(attrs))
    387 
    388         return _nulljoin(result)
    389 
    390     def load(self, rawdata):
    391         if type(rawdata) == type(''):
    392             self.__ParseString(rawdata)
    393         else:
    394             for k, v in rawdata.items():
    395                 self[k] = v
    396 
    397     def __ParseString(self, str, patt = _CookiePattern):
    398         i = 0
    399         n = len(str)
    400         M = None
    401         while 0 <= i < n:
    402             match = patt.search(str, i)
    403             if not match:
    404                 break
    405             K, V = match.group('key'), match.group('val')
    406             i = match.end(0)
    407             if K[0] == '$':
    408                 if M:
    409                     M[K[1:]] = V
    410             elif K.lower() in Morsel._reserved:
    411                 if M:
    412                     M[K] = _unquote(V)
    413             else:
    414                 rval, cval = self.value_decode(V)
    415                 self.__set(K, rval, cval)
    416                 M = self[K]
    417 
    418 
    419 class SimpleCookie(BaseCookie):
    420 
    421     def value_decode(self, val):
    422         return (_unquote(val), val)
    423 
    424     def value_encode(self, val):
    425         strval = str(val)
    426         return (strval, _quote(strval))
    427 
    428 
    429 class SerialCookie(BaseCookie):
    430 
    431     def __init__(self, input = None):
    432         warnings.warn('SerialCookie class is insecure; do not use it', DeprecationWarning)
    433         BaseCookie.__init__(self, input)
    434 
    435     def value_decode(self, val):
    436         return (loads(_unquote(val)), val)
    437 
    438     def value_encode(self, val):
    439         return (val, _quote(dumps(val)))
    440 
    441 
    442 class SmartCookie(BaseCookie):
    443 
    444     def __init__(self, input = None):
    445         warnings.warn('Cookie/SmartCookie class is insecure; do not use it', DeprecationWarning)
    446         BaseCookie.__init__(self, input)
    447 
    448     def value_decode(self, val):
    449         strval = _unquote(val)
    450         try:
    451             return (loads(strval), val)
    452         except:
    453             return (strval, val)
    454 
    455     def value_encode(self, val):
    456         if type(val) == type(''):
    457             return (val, _quote(val))
    458         else:
    459             return (val, _quote(dumps(val)))
    460 
    461 
    462 Cookie = SmartCookie
    463 
    464 def _test():
    465     import doctest, Cookie
    466     return doctest.testmod(Cookie)
    467 
    468 
    469 if __name__ == '__main__':
    470     _test()