home *** CD-ROM | disk | FTP | other *** search
/ Freelog 116 / FreelogNo116-JuilletSeptembre2013.iso / GestionFichiers / metamorphose / metamorphose2_0.8.2_setup.exe / metamorphose2.exe / cookielib.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2011-01-12  |  39KB  |  1,394 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.6)
  3.  
  4. __all__ = [
  5.     'Cookie',
  6.     'CookieJar',
  7.     'CookiePolicy',
  8.     'DefaultCookiePolicy',
  9.     'FileCookieJar',
  10.     'LWPCookieJar',
  11.     'lwp_cookie_str',
  12.     'LoadError',
  13.     'MozillaCookieJar']
  14. import re
  15. import urlparse
  16. import copy
  17. import time
  18. import urllib
  19.  
  20. try:
  21.     import threading as _threading
  22. except ImportError:
  23.     import dummy_threading as _threading
  24.  
  25. import httplib
  26. from calendar import timegm
  27. debug = False
  28. logger = None
  29.  
  30. def _debug(*args):
  31.     global logger
  32.     if not debug:
  33.         return None
  34.     if not logger:
  35.         import logging as logging
  36.         logger = logging.getLogger('cookielib')
  37.     
  38.     return logger.debug(*args)
  39.  
  40. DEFAULT_HTTP_PORT = str(httplib.HTTP_PORT)
  41. MISSING_FILENAME_TEXT = 'a filename was not supplied (nor was the CookieJar instance initialised with one)'
  42.  
  43. def _warn_unhandled_exception():
  44.     import warnings as warnings
  45.     import traceback as traceback
  46.     import StringIO as StringIO
  47.     f = StringIO.StringIO()
  48.     traceback.print_exc(None, f)
  49.     msg = f.getvalue()
  50.     warnings.warn('cookielib bug!\n%s' % msg, stacklevel = 2)
  51.  
  52. EPOCH_YEAR = 1970
  53.  
  54. def _timegm(tt):
  55.     (year, month, mday, hour, min, sec) = tt[:6]
  56.     if year >= EPOCH_YEAR:
  57.         if month <= month:
  58.             pass
  59.         elif month <= 12:
  60.             if mday <= mday:
  61.                 pass
  62.             elif mday <= 31:
  63.                 if hour <= hour:
  64.                     pass
  65.                 elif hour <= 24:
  66.                     if min <= min:
  67.                         pass
  68.                     elif min <= 59:
  69.                         if sec <= sec:
  70.                             pass
  71.                         elif sec <= 61:
  72.                             return timegm(tt)
  73.     return None
  74.  
  75. DAYS = [
  76.     'Mon',
  77.     'Tue',
  78.     'Wed',
  79.     'Thu',
  80.     'Fri',
  81.     'Sat',
  82.     'Sun']
  83. MONTHS = [
  84.     'Jan',
  85.     'Feb',
  86.     'Mar',
  87.     'Apr',
  88.     'May',
  89.     'Jun',
  90.     'Jul',
  91.     'Aug',
  92.     'Sep',
  93.     'Oct',
  94.     'Nov',
  95.     'Dec']
  96. MONTHS_LOWER = []
  97. for month in MONTHS:
  98.     MONTHS_LOWER.append(month.lower())
  99.  
  100.  
  101. def time2isoz(t = None):
  102.     if t is None:
  103.         t = time.time()
  104.     
  105.     (year, mon, mday, hour, min, sec) = time.gmtime(t)[:6]
  106.     return '%04d-%02d-%02d %02d:%02d:%02dZ' % (year, mon, mday, hour, min, sec)
  107.  
  108.  
  109. def time2netscape(t = None):
  110.     if t is None:
  111.         t = time.time()
  112.     
  113.     (year, mon, mday, hour, min, sec, wday) = time.gmtime(t)[:7]
  114.     return '%s %02d-%s-%04d %02d:%02d:%02d GMT' % (DAYS[wday], mday, MONTHS[mon - 1], year, hour, min, sec)
  115.  
  116. UTC_ZONES = {
  117.     'GMT': None,
  118.     'UTC': None,
  119.     'UT': None,
  120.     'Z': None }
  121. TIMEZONE_RE = re.compile('^([-+])?(\\d\\d?):?(\\d\\d)?$')
  122.  
  123. def offset_from_tz_string(tz):
  124.     offset = None
  125.     if tz in UTC_ZONES:
  126.         offset = 0
  127.     else:
  128.         m = TIMEZONE_RE.search(tz)
  129.         if m:
  130.             offset = 3600 * int(m.group(2))
  131.             if m.group(3):
  132.                 offset = offset + 60 * int(m.group(3))
  133.             
  134.             if m.group(1) == '-':
  135.                 offset = -offset
  136.             
  137.         
  138.     return offset
  139.  
  140.  
  141. def _str2time(day, mon, yr, hr, min, sec, tz):
  142.     
  143.     try:
  144.         mon = MONTHS_LOWER.index(mon.lower()) + 1
  145.     except ValueError:
  146.         
  147.         try:
  148.             imon = int(mon)
  149.         except ValueError:
  150.             return None
  151.  
  152.         if imon <= imon:
  153.             pass
  154.         elif imon <= 12:
  155.             mon = imon
  156.         else:
  157.             return None
  158.         imon <= 12
  159.  
  160.     if hr is None:
  161.         hr = 0
  162.     
  163.     if min is None:
  164.         min = 0
  165.     
  166.     if sec is None:
  167.         sec = 0
  168.     
  169.     yr = int(yr)
  170.     day = int(day)
  171.     hr = int(hr)
  172.     min = int(min)
  173.     sec = int(sec)
  174.     if yr < 1000:
  175.         cur_yr = time.localtime(time.time())[0]
  176.         m = cur_yr % 100
  177.         tmp = yr
  178.         yr = yr + cur_yr - m
  179.         m = m - tmp
  180.         if abs(m) > 50:
  181.             if m > 0:
  182.                 yr = yr + 100
  183.             else:
  184.                 yr = yr - 100
  185.         
  186.     
  187.     t = _timegm((yr, mon, day, hr, min, sec, tz))
  188.     if t is not None:
  189.         if tz is None:
  190.             tz = 'UTC'
  191.         
  192.         tz = tz.upper()
  193.         offset = offset_from_tz_string(tz)
  194.         if offset is None:
  195.             return None
  196.         t = t - offset
  197.     
  198.     return t
  199.  
  200. STRICT_DATE_RE = re.compile('^[SMTWF][a-z][a-z], (\\d\\d) ([JFMASOND][a-z][a-z]) (\\d\\d\\d\\d) (\\d\\d):(\\d\\d):(\\d\\d) GMT$')
  201. WEEKDAY_RE = re.compile('^(?:Sun|Mon|Tue|Wed|Thu|Fri|Sat)[a-z]*,?\\s*', re.I)
  202. LOOSE_HTTP_DATE_RE = re.compile('^\n    (\\d\\d?)            # day\n       (?:\\s+|[-\\/])\n    (\\w+)              # month\n        (?:\\s+|[-\\/])\n    (\\d+)              # year\n    (?:\n          (?:\\s+|:)    # separator before clock\n       (\\d\\d?):(\\d\\d)  # hour:min\n       (?::(\\d\\d))?    # optional seconds\n    )?                 # optional clock\n       \\s*\n    ([-+]?\\d{2,4}|(?![APap][Mm]\\b)[A-Za-z]+)? # timezone\n       \\s*\n    (?:\\(\\w+\\))?       # ASCII representation of timezone in parens.\n       \\s*$', re.X)
  203.  
  204. def http2time(text):
  205.     m = STRICT_DATE_RE.search(text)
  206.     if m:
  207.         g = m.groups()
  208.         mon = MONTHS_LOWER.index(g[1].lower()) + 1
  209.         tt = (int(g[2]), mon, int(g[0]), int(g[3]), int(g[4]), float(g[5]))
  210.         return _timegm(tt)
  211.     text = text.lstrip()
  212.     text = WEEKDAY_RE.sub('', text, 1)
  213.     (day, mon, yr, hr, min, sec, tz) = [
  214.         None] * 7
  215.     m = LOOSE_HTTP_DATE_RE.search(text)
  216.     if m is not None:
  217.         (day, mon, yr, hr, min, sec, tz) = m.groups()
  218.     else:
  219.         return None
  220.     return m(day, mon, yr, hr, min, sec, tz)
  221.  
  222. ISO_DATE_RE = re.compile('^\n    (\\d{4})              # year\n       [-\\/]?\n    (\\d\\d?)              # numerical month\n       [-\\/]?\n    (\\d\\d?)              # day\n   (?:\n         (?:\\s+|[-:Tt])  # separator before clock\n      (\\d\\d?):?(\\d\\d)    # hour:min\n      (?::?(\\d\\d(?:\\.\\d*)?))?  # optional seconds (and fractional)\n   )?                    # optional clock\n      \\s*\n   ([-+]?\\d\\d?:?(:?\\d\\d)?\n    |Z|z)?               # timezone  (Z is "zero meridian", i.e. GMT)\n      \\s*$', re.X)
  223.  
  224. def iso2time(text):
  225.     text = text.lstrip()
  226.     (day, mon, yr, hr, min, sec, tz) = [
  227.         None] * 7
  228.     m = ISO_DATE_RE.search(text)
  229.     if m is not None:
  230.         (yr, mon, day, hr, min, sec, tz, _) = m.groups()
  231.     else:
  232.         return None
  233.     return m is not None(day, mon, yr, hr, min, sec, tz)
  234.  
  235.  
  236. def unmatched(match):
  237.     (start, end) = match.span(0)
  238.     return match.string[:start] + match.string[end:]
  239.  
  240. HEADER_TOKEN_RE = re.compile('^\\s*([^=\\s;,]+)')
  241. HEADER_QUOTED_VALUE_RE = re.compile('^\\s*=\\s*\\"([^\\"\\\\]*(?:\\\\.[^\\"\\\\]*)*)\\"')
  242. HEADER_VALUE_RE = re.compile('^\\s*=\\s*([^\\s;,]*)')
  243. HEADER_ESCAPE_RE = re.compile('\\\\(.)')
  244.  
  245. def split_header_words(header_values):
  246.     result = []
  247.     for text in header_values:
  248.         orig_text = text
  249.         pairs = []
  250.         while text:
  251.             m = HEADER_TOKEN_RE.search(text)
  252.             if m:
  253.                 text = unmatched(m)
  254.                 name = m.group(1)
  255.                 m = HEADER_QUOTED_VALUE_RE.search(text)
  256.                 if m:
  257.                     text = unmatched(m)
  258.                     value = m.group(1)
  259.                     value = HEADER_ESCAPE_RE.sub('\\1', value)
  260.                 else:
  261.                     m = HEADER_VALUE_RE.search(text)
  262.                     if m:
  263.                         text = unmatched(m)
  264.                         value = m.group(1)
  265.                         value = value.rstrip()
  266.                     else:
  267.                         value = None
  268.                 pairs.append((name, value))
  269.                 continue
  270.             if text.lstrip().startswith(','):
  271.                 text = text.lstrip()[1:]
  272.                 if pairs:
  273.                     result.append(pairs)
  274.                 
  275.                 pairs = []
  276.                 continue
  277.             (non_junk, nr_junk_chars) = re.subn('^[=\\s;]*', '', text)
  278.             text = non_junk
  279.         if pairs:
  280.             result.append(pairs)
  281.             continue
  282.     
  283.     return result
  284.  
  285. HEADER_JOIN_ESCAPE_RE = re.compile('([\\"\\\\])')
  286.  
  287. def join_header_words(lists):
  288.     headers = []
  289.     for pairs in lists:
  290.         attr = []
  291.         for k, v in pairs:
  292.             if v is not None:
  293.                 if not re.search('^\\w+$', v):
  294.                     v = HEADER_JOIN_ESCAPE_RE.sub('\\\\\\1', v)
  295.                     v = '"%s"' % v
  296.                 
  297.                 k = '%s=%s' % (k, v)
  298.             
  299.             attr.append(k)
  300.         
  301.         if attr:
  302.             headers.append('; '.join(attr))
  303.             continue
  304.     
  305.     return ', '.join(headers)
  306.  
  307.  
  308. def parse_ns_headers(ns_headers):
  309.     known_attrs = ('expires', 'domain', 'path', 'secure', 'port', 'max-age')
  310.     result = []
  311.     for ns_header in ns_headers:
  312.         pairs = []
  313.         version_set = False
  314.         for ii, param in enumerate(re.split(';\\s*', ns_header)):
  315.             param = param.rstrip()
  316.             if param == '':
  317.                 continue
  318.             
  319.             if '=' not in param:
  320.                 k = param
  321.                 v = None
  322.             else:
  323.                 (k, v) = re.split('\\s*=\\s*', param, 1)
  324.                 k = k.lstrip()
  325.             if ii != 0:
  326.                 lc = k.lower()
  327.                 if lc in known_attrs:
  328.                     k = lc
  329.                 
  330.                 if k == 'version':
  331.                     version_set = True
  332.                 
  333.                 if k == 'expires':
  334.                     if v.startswith('"'):
  335.                         v = v[1:]
  336.                     
  337.                     if v.endswith('"'):
  338.                         v = v[:-1]
  339.                     
  340.                     v = http2time(v)
  341.                 
  342.             
  343.             pairs.append((k, v))
  344.         
  345.         if pairs:
  346.             if not version_set:
  347.                 pairs.append(('version', '0'))
  348.             
  349.             result.append(pairs)
  350.             continue
  351.     
  352.     return result
  353.  
  354. IPV4_RE = re.compile('\\.\\d+$')
  355.  
  356. def is_HDN(text):
  357.     if IPV4_RE.search(text):
  358.         return False
  359.     if text == '':
  360.         return False
  361.     if text[0] == '.' or text[-1] == '.':
  362.         return False
  363.     return True
  364.  
  365.  
  366. def domain_match(A, B):
  367.     A = A.lower()
  368.     B = B.lower()
  369.     if A == B:
  370.         return True
  371.     if not is_HDN(A):
  372.         return False
  373.     i = A.rfind(B)
  374.     if i == -1 or i == 0:
  375.         return False
  376.     if not B.startswith('.'):
  377.         return False
  378.     if not is_HDN(B[1:]):
  379.         return False
  380.     return True
  381.  
  382.  
  383. def liberal_is_HDN(text):
  384.     if IPV4_RE.search(text):
  385.         return False
  386.     return True
  387.  
  388.  
  389. def user_domain_match(A, B):
  390.     A = A.lower()
  391.     B = B.lower()
  392.     if not liberal_is_HDN(A) and liberal_is_HDN(B):
  393.         if A == B:
  394.             return True
  395.         return False
  396.     initial_dot = B.startswith('.')
  397.     if initial_dot and A.endswith(B):
  398.         return True
  399.     if not initial_dot and A == B:
  400.         return True
  401.     return False
  402.  
  403. cut_port_re = re.compile(':\\d+$')
  404.  
  405. def request_host(request):
  406.     url = request.get_full_url()
  407.     host = urlparse.urlparse(url)[1]
  408.     if host == '':
  409.         host = request.get_header('Host', '')
  410.     
  411.     host = cut_port_re.sub('', host, 1)
  412.     return host.lower()
  413.  
  414.  
  415. def eff_request_host(request):
  416.     erhn = req_host = request_host(request)
  417.     if req_host.find('.') == -1 and not IPV4_RE.search(req_host):
  418.         erhn = req_host + '.local'
  419.     
  420.     return (req_host, erhn)
  421.  
  422.  
  423. def request_path(request):
  424.     url = request.get_full_url()
  425.     (path, parameters, query, frag) = urlparse.urlparse(url)[2:]
  426.     if parameters:
  427.         path = '%s;%s' % (path, parameters)
  428.     
  429.     path = escape_path(path)
  430.     req_path = urlparse.urlunparse(('', '', path, '', query, frag))
  431.     if not req_path.startswith('/'):
  432.         req_path = '/' + req_path
  433.     
  434.     return req_path
  435.  
  436.  
  437. def request_port(request):
  438.     host = request.get_host()
  439.     i = host.find(':')
  440.     if i >= 0:
  441.         port = host[i + 1:]
  442.         
  443.         try:
  444.             int(port)
  445.         except ValueError:
  446.             _debug("nonnumeric port: '%s'", port)
  447.             return None
  448.         
  449.  
  450.     None<EXCEPTION MATCH>ValueError
  451.     port = DEFAULT_HTTP_PORT
  452.     return port
  453.  
  454. HTTP_PATH_SAFE = "%/;:@&=+$,!~*'()"
  455. ESCAPED_CHAR_RE = re.compile('%([0-9a-fA-F][0-9a-fA-F])')
  456.  
  457. def uppercase_escaped_char(match):
  458.     return '%%%s' % match.group(1).upper()
  459.  
  460.  
  461. def escape_path(path):
  462.     if isinstance(path, unicode):
  463.         path = path.encode('utf-8')
  464.     
  465.     path = urllib.quote(path, HTTP_PATH_SAFE)
  466.     path = ESCAPED_CHAR_RE.sub(uppercase_escaped_char, path)
  467.     return path
  468.  
  469.  
  470. def reach(h):
  471.     i = h.find('.')
  472.     if i >= 0:
  473.         b = h[i + 1:]
  474.         i = b.find('.')
  475.         if is_HDN(h):
  476.             if i >= 0 or b == 'local':
  477.                 return '.' + b
  478.         
  479.     return h
  480.  
  481.  
  482. def is_third_party(request):
  483.     req_host = request_host(request)
  484.     if not domain_match(req_host, reach(request.get_origin_req_host())):
  485.         return True
  486.     return False
  487.  
  488.  
  489. class Cookie:
  490.     
  491.     def __init__(self, version, name, value, port, port_specified, domain, domain_specified, domain_initial_dot, path, path_specified, secure, expires, discard, comment, comment_url, rest, rfc2109 = False):
  492.         if version is not None:
  493.             version = int(version)
  494.         
  495.         if expires is not None:
  496.             expires = int(expires)
  497.         
  498.         if port is None and port_specified is True:
  499.             raise ValueError('if port is None, port_specified must be false')
  500.         port_specified is True
  501.         self.version = version
  502.         self.name = name
  503.         self.value = value
  504.         self.port = port
  505.         self.port_specified = port_specified
  506.         self.domain = domain.lower()
  507.         self.domain_specified = domain_specified
  508.         self.domain_initial_dot = domain_initial_dot
  509.         self.path = path
  510.         self.path_specified = path_specified
  511.         self.secure = secure
  512.         self.expires = expires
  513.         self.discard = discard
  514.         self.comment = comment
  515.         self.comment_url = comment_url
  516.         self.rfc2109 = rfc2109
  517.         self._rest = copy.copy(rest)
  518.  
  519.     
  520.     def has_nonstandard_attr(self, name):
  521.         return name in self._rest
  522.  
  523.     
  524.     def get_nonstandard_attr(self, name, default = None):
  525.         return self._rest.get(name, default)
  526.  
  527.     
  528.     def set_nonstandard_attr(self, name, value):
  529.         self._rest[name] = value
  530.  
  531.     
  532.     def is_expired(self, now = None):
  533.         if now is None:
  534.             now = time.time()
  535.         
  536.         if self.expires is not None and self.expires <= now:
  537.             return True
  538.         return False
  539.  
  540.     
  541.     def __str__(self):
  542.         if self.port is None:
  543.             p = ''
  544.         else:
  545.             p = ':' + self.port
  546.         limit = self.domain + p + self.path
  547.         if self.value is not None:
  548.             namevalue = '%s=%s' % (self.name, self.value)
  549.         else:
  550.             namevalue = self.name
  551.         return '<Cookie %s for %s>' % (namevalue, limit)
  552.  
  553.     
  554.     def __repr__(self):
  555.         args = []
  556.         for name in ('version', 'name', 'value', 'port', 'port_specified', 'domain', 'domain_specified', 'domain_initial_dot', 'path', 'path_specified', 'secure', 'expires', 'discard', 'comment', 'comment_url'):
  557.             attr = getattr(self, name)
  558.             args.append('%s=%s' % (name, repr(attr)))
  559.         
  560.         args.append('rest=%s' % repr(self._rest))
  561.         args.append('rfc2109=%s' % repr(self.rfc2109))
  562.         return 'Cookie(%s)' % ', '.join(args)
  563.  
  564.  
  565.  
  566. class CookiePolicy:
  567.     
  568.     def set_ok(self, cookie, request):
  569.         raise NotImplementedError()
  570.  
  571.     
  572.     def return_ok(self, cookie, request):
  573.         raise NotImplementedError()
  574.  
  575.     
  576.     def domain_return_ok(self, domain, request):
  577.         return True
  578.  
  579.     
  580.     def path_return_ok(self, path, request):
  581.         return True
  582.  
  583.  
  584.  
  585. class DefaultCookiePolicy(CookiePolicy):
  586.     DomainStrictNoDots = 1
  587.     DomainStrictNonDomain = 2
  588.     DomainRFC2965Match = 4
  589.     DomainLiberal = 0
  590.     DomainStrict = DomainStrictNoDots | DomainStrictNonDomain
  591.     
  592.     def __init__(self, blocked_domains = None, allowed_domains = None, netscape = True, rfc2965 = False, rfc2109_as_netscape = None, hide_cookie2 = False, strict_domain = False, strict_rfc2965_unverifiable = True, strict_ns_unverifiable = False, strict_ns_domain = DomainLiberal, strict_ns_set_initial_dollar = False, strict_ns_set_path = False):
  593.         self.netscape = netscape
  594.         self.rfc2965 = rfc2965
  595.         self.rfc2109_as_netscape = rfc2109_as_netscape
  596.         self.hide_cookie2 = hide_cookie2
  597.         self.strict_domain = strict_domain
  598.         self.strict_rfc2965_unverifiable = strict_rfc2965_unverifiable
  599.         self.strict_ns_unverifiable = strict_ns_unverifiable
  600.         self.strict_ns_domain = strict_ns_domain
  601.         self.strict_ns_set_initial_dollar = strict_ns_set_initial_dollar
  602.         self.strict_ns_set_path = strict_ns_set_path
  603.         if blocked_domains is not None:
  604.             self._blocked_domains = tuple(blocked_domains)
  605.         else:
  606.             self._blocked_domains = ()
  607.         if allowed_domains is not None:
  608.             allowed_domains = tuple(allowed_domains)
  609.         
  610.         self._allowed_domains = allowed_domains
  611.  
  612.     
  613.     def blocked_domains(self):
  614.         return self._blocked_domains
  615.  
  616.     
  617.     def set_blocked_domains(self, blocked_domains):
  618.         self._blocked_domains = tuple(blocked_domains)
  619.  
  620.     
  621.     def is_blocked(self, domain):
  622.         for blocked_domain in self._blocked_domains:
  623.             if user_domain_match(domain, blocked_domain):
  624.                 return True
  625.         
  626.         return False
  627.  
  628.     
  629.     def allowed_domains(self):
  630.         return self._allowed_domains
  631.  
  632.     
  633.     def set_allowed_domains(self, allowed_domains):
  634.         if allowed_domains is not None:
  635.             allowed_domains = tuple(allowed_domains)
  636.         
  637.         self._allowed_domains = allowed_domains
  638.  
  639.     
  640.     def is_not_allowed(self, domain):
  641.         if self._allowed_domains is None:
  642.             return False
  643.         for allowed_domain in self._allowed_domains:
  644.             if user_domain_match(domain, allowed_domain):
  645.                 return False
  646.         
  647.         return True
  648.  
  649.     
  650.     def set_ok(self, cookie, request):
  651.         _debug(' - checking cookie %s=%s', cookie.name, cookie.value)
  652.         for n in ('version', 'verifiability', 'name', 'path', 'domain', 'port'):
  653.             fn_name = 'set_ok_' + n
  654.             fn = getattr(self, fn_name)
  655.             if not fn(cookie, request):
  656.                 return False
  657.         
  658.         return True
  659.  
  660.     
  661.     def set_ok_version(self, cookie, request):
  662.         if cookie.version is None:
  663.             _debug('   Set-Cookie2 without version attribute (%s=%s)', cookie.name, cookie.value)
  664.             return False
  665.         if cookie.version > 0 and not (self.rfc2965):
  666.             _debug('   RFC 2965 cookies are switched off')
  667.             return False
  668.         if cookie.version == 0 and not (self.netscape):
  669.             _debug('   Netscape cookies are switched off')
  670.             return False
  671.         return True
  672.  
  673.     
  674.     def set_ok_verifiability(self, cookie, request):
  675.         return True
  676.  
  677.     
  678.     def set_ok_name(self, cookie, request):
  679.         if cookie.version == 0 and self.strict_ns_set_initial_dollar and cookie.name.startswith('$'):
  680.             _debug("   illegal name (starts with '$'): '%s'", cookie.name)
  681.             return False
  682.         return True
  683.  
  684.     
  685.     def set_ok_path(self, cookie, request):
  686.         if cookie.path_specified:
  687.             req_path = request_path(request)
  688.             if (cookie.version > 0 or cookie.version == 0 or self.strict_ns_set_path) and not req_path.startswith(cookie.path):
  689.                 _debug('   path attribute %s is not a prefix of request path %s', cookie.path, req_path)
  690.                 return False
  691.         
  692.         return True
  693.  
  694.     
  695.     def set_ok_domain(self, cookie, request):
  696.         if self.is_blocked(cookie.domain):
  697.             _debug('   domain %s is in user block-list', cookie.domain)
  698.             return False
  699.         if self.is_not_allowed(cookie.domain):
  700.             _debug('   domain %s is not in user allow-list', cookie.domain)
  701.             return False
  702.         if cookie.domain_specified:
  703.             (req_host, erhn) = eff_request_host(request)
  704.             domain = cookie.domain
  705.             if domain.startswith('.'):
  706.                 undotted_domain = domain[1:]
  707.             else:
  708.                 undotted_domain = domain
  709.             embedded_dots = undotted_domain.find('.') >= 0
  710.             if not embedded_dots and domain != '.local':
  711.                 _debug('   non-local domain %s contains no embedded dot', domain)
  712.                 return False
  713.             if cookie.version > 0 or self.strict_ns_domain & self.DomainStrictNoDots:
  714.                 host_prefix = req_host[:-len(domain)]
  715.                 if host_prefix.find('.') >= 0 and not IPV4_RE.search(req_host):
  716.                     _debug('   host prefix %s for domain %s contains a dot', host_prefix, domain)
  717.                     return False
  718.             
  719.         
  720.         return True
  721.  
  722.     
  723.     def set_ok_port(self, cookie, request):
  724.         if cookie.port_specified:
  725.             req_port = request_port(request)
  726.             if req_port is None:
  727.                 req_port = '80'
  728.             else:
  729.                 req_port = str(req_port)
  730.             for p in cookie.port.split(','):
  731.                 
  732.                 try:
  733.                     int(p)
  734.                 except ValueError:
  735.                     _debug('   bad port %s (not numeric)', p)
  736.                     return False
  737.  
  738.                 if p == req_port:
  739.                     break
  740.                     continue
  741.             else:
  742.                 return False
  743.         return True
  744.  
  745.     
  746.     def return_ok(self, cookie, request):
  747.         _debug(' - checking cookie %s=%s', cookie.name, cookie.value)
  748.         for n in ('version', 'verifiability', 'secure', 'expires', 'port', 'domain'):
  749.             fn_name = 'return_ok_' + n
  750.             fn = getattr(self, fn_name)
  751.             if not fn(cookie, request):
  752.                 return False
  753.         
  754.         return True
  755.  
  756.     
  757.     def return_ok_version(self, cookie, request):
  758.         if cookie.version > 0 and not (self.rfc2965):
  759.             _debug('   RFC 2965 cookies are switched off')
  760.             return False
  761.         if cookie.version == 0 and not (self.netscape):
  762.             _debug('   Netscape cookies are switched off')
  763.             return False
  764.         return True
  765.  
  766.     
  767.     def return_ok_verifiability(self, cookie, request):
  768.         return True
  769.  
  770.     
  771.     def return_ok_secure(self, cookie, request):
  772.         if cookie.secure and request.get_type() != 'https':
  773.             _debug('   secure cookie with non-secure request')
  774.             return False
  775.         return True
  776.  
  777.     
  778.     def return_ok_expires(self, cookie, request):
  779.         if cookie.is_expired(self._now):
  780.             _debug('   cookie expired')
  781.             return False
  782.         return True
  783.  
  784.     
  785.     def return_ok_port(self, cookie, request):
  786.         if cookie.port:
  787.             req_port = request_port(request)
  788.             if req_port is None:
  789.                 req_port = '80'
  790.             
  791.             for p in cookie.port.split(','):
  792.                 if p == req_port:
  793.                     break
  794.                     continue
  795.             else:
  796.                 return False
  797.         return True
  798.  
  799.     
  800.     def return_ok_domain(self, cookie, request):
  801.         (req_host, erhn) = eff_request_host(request)
  802.         domain = cookie.domain
  803.         if cookie.version == 0 and self.strict_ns_domain & self.DomainStrictNonDomain and not (cookie.domain_specified) and domain != erhn:
  804.             _debug('   cookie with unspecified domain does not string-compare equal to request domain')
  805.             return False
  806.         if cookie.version > 0 and not domain_match(erhn, domain):
  807.             _debug('   effective request-host name %s does not domain-match RFC 2965 cookie domain %s', erhn, domain)
  808.             return False
  809.         if cookie.version == 0 and not ('.' + erhn).endswith(domain):
  810.             _debug('   request-host %s does not match Netscape cookie domain %s', req_host, domain)
  811.             return False
  812.         return True
  813.  
  814.     
  815.     def domain_return_ok(self, domain, request):
  816.         (req_host, erhn) = eff_request_host(request)
  817.         if not req_host.startswith('.'):
  818.             req_host = '.' + req_host
  819.         
  820.         if not erhn.startswith('.'):
  821.             erhn = '.' + erhn
  822.         
  823.         if not req_host.endswith(domain) or erhn.endswith(domain):
  824.             return False
  825.         if self.is_blocked(domain):
  826.             _debug('   domain %s is in user block-list', domain)
  827.             return False
  828.         if self.is_not_allowed(domain):
  829.             _debug('   domain %s is not in user allow-list', domain)
  830.             return False
  831.         return True
  832.  
  833.     
  834.     def path_return_ok(self, path, request):
  835.         _debug('- checking cookie path=%s', path)
  836.         req_path = request_path(request)
  837.         if not req_path.startswith(path):
  838.             _debug('  %s does not path-match %s', req_path, path)
  839.             return False
  840.         return True
  841.  
  842.  
  843.  
  844. def vals_sorted_by_key(adict):
  845.     keys = adict.keys()
  846.     keys.sort()
  847.     return map(adict.get, keys)
  848.  
  849.  
  850. def deepvalues(mapping):
  851.     values = vals_sorted_by_key(mapping)
  852.     for obj in values:
  853.         mapping = False
  854.         
  855.         try:
  856.             obj.items
  857.         except AttributeError:
  858.             pass
  859.  
  860.         mapping = True
  861.         for subobj in deepvalues(obj):
  862.             yield subobj
  863.         
  864.         if not mapping:
  865.             yield obj
  866.             continue
  867.     
  868.  
  869.  
  870. class Absent:
  871.     pass
  872.  
  873.  
  874. class CookieJar:
  875.     non_word_re = re.compile('\\W')
  876.     quote_re = re.compile('([\\"\\\\])')
  877.     strict_domain_re = re.compile('\\.?[^.]*')
  878.     domain_re = re.compile('[^.]*')
  879.     dots_re = re.compile('^\\.+')
  880.     magic_re = '^\\#LWP-Cookies-(\\d+\\.\\d+)'
  881.     
  882.     def __init__(self, policy = None):
  883.         if policy is None:
  884.             policy = DefaultCookiePolicy()
  885.         
  886.         self._policy = policy
  887.         self._cookies_lock = _threading.RLock()
  888.         self._cookies = { }
  889.  
  890.     
  891.     def set_policy(self, policy):
  892.         self._policy = policy
  893.  
  894.     
  895.     def _cookies_for_domain(self, domain, request):
  896.         cookies = []
  897.         if not self._policy.domain_return_ok(domain, request):
  898.             return []
  899.         _debug('Checking %s for cookies to return', domain)
  900.         cookies_by_path = self._cookies[domain]
  901.         for path in cookies_by_path.keys():
  902.             if not self._policy.path_return_ok(path, request):
  903.                 continue
  904.             
  905.             cookies_by_name = cookies_by_path[path]
  906.             for cookie in cookies_by_name.values():
  907.                 if not self._policy.return_ok(cookie, request):
  908.                     _debug('   not returning cookie')
  909.                     continue
  910.                 
  911.                 _debug("   it's a match")
  912.                 cookies.append(cookie)
  913.             
  914.         
  915.         return cookies
  916.  
  917.     
  918.     def _cookies_for_request(self, request):
  919.         cookies = []
  920.         for domain in self._cookies.keys():
  921.             cookies.extend(self._cookies_for_domain(domain, request))
  922.         
  923.         return cookies
  924.  
  925.     
  926.     def _cookie_attrs(self, cookies):
  927.         cookies.sort(key = (lambda arg: len(arg.path)), reverse = True)
  928.         version_set = False
  929.         attrs = []
  930.         for cookie in cookies:
  931.             version = cookie.version
  932.             if not version_set:
  933.                 version_set = True
  934.                 if version > 0:
  935.                     attrs.append('$Version=%s' % version)
  936.                 
  937.             
  938.             if cookie.value is not None and self.non_word_re.search(cookie.value) and version > 0:
  939.                 value = self.quote_re.sub('\\\\\\1', cookie.value)
  940.             else:
  941.                 value = cookie.value
  942.             if cookie.value is None:
  943.                 attrs.append(cookie.name)
  944.             else:
  945.                 attrs.append('%s=%s' % (cookie.name, value))
  946.             if version > 0:
  947.                 if cookie.path_specified:
  948.                     attrs.append('$Path="%s"' % cookie.path)
  949.                 
  950.                 if cookie.domain.startswith('.'):
  951.                     domain = cookie.domain
  952.                     if not (cookie.domain_initial_dot) and domain.startswith('.'):
  953.                         domain = domain[1:]
  954.                     
  955.                     attrs.append('$Domain="%s"' % domain)
  956.                 
  957.                 if cookie.port is not None:
  958.                     p = '$Port'
  959.                     if cookie.port_specified:
  960.                         p = p + '="%s"' % cookie.port
  961.                     
  962.                     attrs.append(p)
  963.                 
  964.             cookie.port is not None
  965.         
  966.         return attrs
  967.  
  968.     
  969.     def add_cookie_header(self, request):
  970.         _debug('add_cookie_header')
  971.         self._cookies_lock.acquire()
  972.         
  973.         try:
  974.             self._policy._now = self._now = int(time.time())
  975.             cookies = self._cookies_for_request(request)
  976.             attrs = self._cookie_attrs(cookies)
  977.             if attrs:
  978.                 if not request.has_header('Cookie'):
  979.                     request.add_unredirected_header('Cookie', '; '.join(attrs))
  980.                 
  981.             
  982.             if self._policy.rfc2965 and not (self._policy.hide_cookie2) and not request.has_header('Cookie2'):
  983.                 for cookie in cookies:
  984.                     if cookie.version != 1:
  985.                         request.add_unredirected_header('Cookie2', '$Version="1"')
  986.                         break
  987.                         continue
  988.                 
  989.         finally:
  990.             self._cookies_lock.release()
  991.  
  992.         self.clear_expired_cookies()
  993.  
  994.     
  995.     def _normalized_cookie_tuples(self, attrs_set):
  996.         cookie_tuples = []
  997.         boolean_attrs = ('discard', 'secure')
  998.         value_attrs = ('version', 'expires', 'max-age', 'domain', 'path', 'port', 'comment', 'commenturl')
  999.         for cookie_attrs in attrs_set:
  1000.             (name, value) = cookie_attrs[0]
  1001.             max_age_set = False
  1002.             bad_cookie = False
  1003.             standard = { }
  1004.             rest = { }
  1005.             for k, v in cookie_attrs[1:]:
  1006.                 lc = k.lower()
  1007.                 if lc in value_attrs or lc in boolean_attrs:
  1008.                     k = lc
  1009.                 
  1010.                 if k in boolean_attrs and v is None:
  1011.                     v = True
  1012.                 
  1013.                 if k in standard:
  1014.                     continue
  1015.                 
  1016.                 if k == 'domain':
  1017.                     if v is None:
  1018.                         _debug('   missing value for domain attribute')
  1019.                         bad_cookie = True
  1020.                         break
  1021.                     
  1022.                     v = v.lower()
  1023.                 
  1024.                 if k == 'expires':
  1025.                     if max_age_set:
  1026.                         continue
  1027.                     
  1028.                     if v is None:
  1029.                         _debug('   missing or invalid value for expires attribute: treating as session cookie')
  1030.                         continue
  1031.                     
  1032.                 
  1033.                 if k == 'max-age':
  1034.                     max_age_set = True
  1035.                     
  1036.                     try:
  1037.                         v = int(v)
  1038.                     except ValueError:
  1039.                         _debug('   missing or invalid (non-numeric) value for max-age attribute')
  1040.                         bad_cookie = True
  1041.                         break
  1042.  
  1043.                     k = 'expires'
  1044.                     v = self._now + v
  1045.                 
  1046.                 if k in value_attrs or k in boolean_attrs:
  1047.                     if v is None and k not in ('port', 'comment', 'commenturl'):
  1048.                         _debug('   missing value for %s attribute' % k)
  1049.                         bad_cookie = True
  1050.                         break
  1051.                     
  1052.                     standard[k] = v
  1053.                     continue
  1054.                 rest[k] = v
  1055.             
  1056.             if bad_cookie:
  1057.                 continue
  1058.             
  1059.             cookie_tuples.append((name, value, standard, rest))
  1060.         
  1061.         return cookie_tuples
  1062.  
  1063.     
  1064.     def _cookie_from_cookie_tuple(self, tup, request):
  1065.         (name, value, standard, rest) = tup
  1066.         domain = standard.get('domain', Absent)
  1067.         path = standard.get('path', Absent)
  1068.         port = standard.get('port', Absent)
  1069.         expires = standard.get('expires', Absent)
  1070.         version = standard.get('version', None)
  1071.         if version is not None:
  1072.             version = int(version)
  1073.         
  1074.         secure = standard.get('secure', False)
  1075.         discard = standard.get('discard', False)
  1076.         comment = standard.get('comment', None)
  1077.         comment_url = standard.get('commenturl', None)
  1078.         if path is not Absent and path != '':
  1079.             path_specified = True
  1080.             path = escape_path(path)
  1081.         else:
  1082.             path_specified = False
  1083.             path = request_path(request)
  1084.             i = path.rfind('/')
  1085.             if i != -1:
  1086.                 if version == 0:
  1087.                     path = path[:i]
  1088.                 else:
  1089.                     path = path[:i + 1]
  1090.             
  1091.             if len(path) == 0:
  1092.                 path = '/'
  1093.             
  1094.         domain_specified = domain is not Absent
  1095.         domain_initial_dot = False
  1096.         if domain_specified:
  1097.             domain_initial_dot = bool(domain.startswith('.'))
  1098.         
  1099.         if domain is Absent:
  1100.             (req_host, erhn) = eff_request_host(request)
  1101.             domain = erhn
  1102.         elif not domain.startswith('.'):
  1103.             domain = '.' + domain
  1104.         
  1105.         port_specified = False
  1106.         if port is not Absent:
  1107.             if port is None:
  1108.                 port = request_port(request)
  1109.             else:
  1110.                 port_specified = True
  1111.                 port = re.sub('\\s+', '', port)
  1112.         else:
  1113.             port = None
  1114.         if expires is Absent:
  1115.             expires = None
  1116.             discard = True
  1117.         elif expires <= self._now:
  1118.             
  1119.             try:
  1120.                 self.clear(domain, path, name)
  1121.             except KeyError:
  1122.                 pass
  1123.  
  1124.             _debug("Expiring cookie, domain='%s', path='%s', name='%s'", domain, path, name)
  1125.             return None
  1126.         return Cookie(version, name, value, port, port_specified, domain, domain_specified, domain_initial_dot, path, path_specified, secure, expires, discard, comment, comment_url, rest)
  1127.  
  1128.     
  1129.     def _cookies_from_attrs_set(self, attrs_set, request):
  1130.         cookie_tuples = self._normalized_cookie_tuples(attrs_set)
  1131.         cookies = []
  1132.         for tup in cookie_tuples:
  1133.             cookie = self._cookie_from_cookie_tuple(tup, request)
  1134.             if cookie:
  1135.                 cookies.append(cookie)
  1136.                 continue
  1137.         
  1138.         return cookies
  1139.  
  1140.     
  1141.     def _process_rfc2109_cookies(self, cookies):
  1142.         rfc2109_as_ns = getattr(self._policy, 'rfc2109_as_netscape', None)
  1143.         if rfc2109_as_ns is None:
  1144.             rfc2109_as_ns = not (self._policy.rfc2965)
  1145.         
  1146.         for cookie in cookies:
  1147.             if cookie.version == 1:
  1148.                 cookie.rfc2109 = True
  1149.                 if rfc2109_as_ns:
  1150.                     cookie.version = 0
  1151.                 
  1152.             rfc2109_as_ns
  1153.         
  1154.  
  1155.     
  1156.     def make_cookies(self, response, request):
  1157.         headers = response.info()
  1158.         rfc2965_hdrs = headers.getheaders('Set-Cookie2')
  1159.         ns_hdrs = headers.getheaders('Set-Cookie')
  1160.         rfc2965 = self._policy.rfc2965
  1161.         netscape = self._policy.netscape
  1162.         if not not rfc2965_hdrs or not ns_hdrs:
  1163.             if not not ns_hdrs or not rfc2965:
  1164.                 if (not rfc2965_hdrs or not netscape or not netscape) and not rfc2965:
  1165.                     return []
  1166.                 
  1167.                 try:
  1168.                     cookies = self._cookies_from_attrs_set(split_header_words(rfc2965_hdrs), request)
  1169.                 except Exception:
  1170.                     not rfc2965
  1171.                     not rfc2965
  1172.                     _warn_unhandled_exception()
  1173.                     cookies = []
  1174.                 except:
  1175.                     not rfc2965
  1176.  
  1177.                 if ns_hdrs and netscape:
  1178.                     
  1179.                     try:
  1180.                         ns_cookies = self._cookies_from_attrs_set(parse_ns_headers(ns_hdrs), request)
  1181.                     except Exception:
  1182.                         not rfc2965
  1183.                         not rfc2965
  1184.                         _warn_unhandled_exception()
  1185.                         ns_cookies = []
  1186.                     except:
  1187.                         not rfc2965
  1188.  
  1189.                     self._process_rfc2109_cookies(ns_cookies)
  1190.                     if rfc2965:
  1191.                         lookup = { }
  1192.                         for cookie in cookies:
  1193.                             lookup[(cookie.domain, cookie.path, cookie.name)] = None
  1194.                         
  1195.                         
  1196.                         def no_matching_rfc2965(ns_cookie, lookup = lookup):
  1197.                             key = (ns_cookie.domain, ns_cookie.path, ns_cookie.name)
  1198.                             return key not in lookup
  1199.  
  1200.                         ns_cookies = filter(no_matching_rfc2965, ns_cookies)
  1201.                     
  1202.                     if ns_cookies:
  1203.                         cookies.extend(ns_cookies)
  1204.                     
  1205.                 
  1206.         return cookies
  1207.  
  1208.     
  1209.     def set_cookie_if_ok(self, cookie, request):
  1210.         self._cookies_lock.acquire()
  1211.         
  1212.         try:
  1213.             self._policy._now = self._now = int(time.time())
  1214.             if self._policy.set_ok(cookie, request):
  1215.                 self.set_cookie(cookie)
  1216.         finally:
  1217.             self._cookies_lock.release()
  1218.  
  1219.  
  1220.     
  1221.     def set_cookie(self, cookie):
  1222.         c = self._cookies
  1223.         self._cookies_lock.acquire()
  1224.         
  1225.         try:
  1226.             if cookie.domain not in c:
  1227.                 c[cookie.domain] = { }
  1228.             
  1229.             c2 = c[cookie.domain]
  1230.             if cookie.path not in c2:
  1231.                 c2[cookie.path] = { }
  1232.             
  1233.             c3 = c2[cookie.path]
  1234.             c3[cookie.name] = cookie
  1235.         finally:
  1236.             self._cookies_lock.release()
  1237.  
  1238.  
  1239.     
  1240.     def extract_cookies(self, response, request):
  1241.         _debug('extract_cookies: %s', response.info())
  1242.         self._cookies_lock.acquire()
  1243.         
  1244.         try:
  1245.             self._policy._now = self._now = int(time.time())
  1246.             for cookie in self.make_cookies(response, request):
  1247.                 if self._policy.set_ok(cookie, request):
  1248.                     _debug(' setting cookie: %s', cookie)
  1249.                     self.set_cookie(cookie)
  1250.                     continue
  1251.         finally:
  1252.             self._cookies_lock.release()
  1253.  
  1254.  
  1255.     
  1256.     def clear(self, domain = None, path = None, name = None):
  1257.         if name is not None:
  1258.             if domain is None or path is None:
  1259.                 raise ValueError('domain and path must be given to remove a cookie by name')
  1260.             path is None
  1261.             del self._cookies[domain][path][name]
  1262.         elif path is not None:
  1263.             if domain is None:
  1264.                 raise ValueError('domain must be given to remove cookies by path')
  1265.             domain is None
  1266.             del self._cookies[domain][path]
  1267.         elif domain is not None:
  1268.             del self._cookies[domain]
  1269.         else:
  1270.             self._cookies = { }
  1271.  
  1272.     
  1273.     def clear_session_cookies(self):
  1274.         self._cookies_lock.acquire()
  1275.         
  1276.         try:
  1277.             for cookie in self:
  1278.                 if cookie.discard:
  1279.                     self.clear(cookie.domain, cookie.path, cookie.name)
  1280.                     continue
  1281.         finally:
  1282.             self._cookies_lock.release()
  1283.  
  1284.  
  1285.     
  1286.     def clear_expired_cookies(self):
  1287.         self._cookies_lock.acquire()
  1288.         
  1289.         try:
  1290.             now = time.time()
  1291.             for cookie in self:
  1292.                 if cookie.is_expired(now):
  1293.                     self.clear(cookie.domain, cookie.path, cookie.name)
  1294.                     continue
  1295.         finally:
  1296.             self._cookies_lock.release()
  1297.  
  1298.  
  1299.     
  1300.     def __iter__(self):
  1301.         return deepvalues(self._cookies)
  1302.  
  1303.     
  1304.     def __len__(self):
  1305.         i = 0
  1306.         for cookie in self:
  1307.             i = i + 1
  1308.         
  1309.         return i
  1310.  
  1311.     
  1312.     def __repr__(self):
  1313.         r = []
  1314.         for cookie in self:
  1315.             r.append(repr(cookie))
  1316.         
  1317.         return '<%s[%s]>' % (self.__class__, ', '.join(r))
  1318.  
  1319.     
  1320.     def __str__(self):
  1321.         r = []
  1322.         for cookie in self:
  1323.             r.append(str(cookie))
  1324.         
  1325.         return '<%s[%s]>' % (self.__class__, ', '.join(r))
  1326.  
  1327.  
  1328.  
  1329. class LoadError(IOError):
  1330.     pass
  1331.  
  1332.  
  1333. class FileCookieJar(CookieJar):
  1334.     
  1335.     def __init__(self, filename = None, delayload = False, policy = None):
  1336.         CookieJar.__init__(self, policy)
  1337.         if filename is not None:
  1338.             
  1339.             try:
  1340.                 filename + ''
  1341.             raise ValueError('filename must be string-like')
  1342.  
  1343.         
  1344.         self.filename = filename
  1345.         self.delayload = bool(delayload)
  1346.  
  1347.     
  1348.     def save(self, filename = None, ignore_discard = False, ignore_expires = False):
  1349.         raise NotImplementedError()
  1350.  
  1351.     
  1352.     def load(self, filename = None, ignore_discard = False, ignore_expires = False):
  1353.         if filename is None:
  1354.             if self.filename is not None:
  1355.                 filename = self.filename
  1356.             else:
  1357.                 raise ValueError(MISSING_FILENAME_TEXT)
  1358.         self.filename is not None
  1359.         f = open(filename)
  1360.         
  1361.         try:
  1362.             self._really_load(f, filename, ignore_discard, ignore_expires)
  1363.         finally:
  1364.             f.close()
  1365.  
  1366.  
  1367.     
  1368.     def revert(self, filename = None, ignore_discard = False, ignore_expires = False):
  1369.         if filename is None:
  1370.             if self.filename is not None:
  1371.                 filename = self.filename
  1372.             else:
  1373.                 raise ValueError(MISSING_FILENAME_TEXT)
  1374.         self.filename is not None
  1375.         self._cookies_lock.acquire()
  1376.         
  1377.         try:
  1378.             old_state = copy.deepcopy(self._cookies)
  1379.             self._cookies = { }
  1380.             
  1381.             try:
  1382.                 self.load(filename, ignore_discard, ignore_expires)
  1383.             except (LoadError, IOError):
  1384.                 self._cookies = old_state
  1385.                 raise 
  1386.  
  1387.         finally:
  1388.             self._cookies_lock.release()
  1389.  
  1390.  
  1391.  
  1392. from _LWPCookieJar import LWPCookieJar, lwp_cookie_str
  1393. from _MozillaCookieJar import MozillaCookieJar
  1394.