home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / tsw / TSW_3.4.0.exe / Apache2 / python / Session.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2004-03-11  |  14.9 KB  |  401 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.3)
  3.  
  4. import apache
  5. import Cookie
  6. import _apache
  7. import os
  8. import time
  9. import anydbm
  10. import whichdb
  11. import random
  12. import md5
  13. import cPickle
  14. import tempfile
  15. COOKIE_NAME = 'pysid'
  16. DFT_TIMEOUT = 30 * 60
  17. CLEANUP_CHANCE = 1000
  18. tempdir = tempfile.gettempdir()
  19.  
  20. def _init_rnd():
  21.     ''' initialize random number generators
  22.     this is key in multithreaded env, see
  23.     python docs for random '''
  24.     if _apache.mpm_query(apache.AP_MPMQ_IS_THREADED):
  25.         gennum = _apache.mpm_query(apache.AP_MPMQ_MAX_SPARE_THREADS)
  26.     else:
  27.         gennum = 10
  28.     g = random.Random(time.time())
  29.     result = [
  30.         g]
  31.     for i in range(gennum - 1):
  32.         laststate = g.getstate()
  33.         g = random.Random()
  34.         g.setstate(laststate)
  35.         g.jumpahead(1000000)
  36.         result.append(g)
  37.     
  38.     return result
  39.  
  40. rnd_gens = _init_rnd()
  41. rnd_iter = iter(rnd_gens)
  42.  
  43. def _get_generator():
  44.     global rnd_iter
  45.     
  46.     try:
  47.         return rnd_iter.next()
  48.     except StopIteration:
  49.         rnd_iter = iter(rnd_gens)
  50.         return rnd_iter.next()
  51.  
  52.  
  53.  
  54. def _new_sid(req):
  55.     t = long(time.time() * 10000)
  56.     pid = os.getpid()
  57.     g = _get_generator()
  58.     rnd1 = g.randint(0, 999999999)
  59.     rnd2 = g.randint(0, 999999999)
  60.     ip = req.connection.remote_ip
  61.     return md5.new('%d%d%d%d%s' % (t, pid, rnd1, rnd2, ip)).hexdigest()
  62.  
  63.  
  64. class BaseSession(dict):
  65.     
  66.     def __init__(self, req, sid = None, secret = None, lock = 1, timeout = 0):
  67.         (self._req, self._sid, self._secret) = (req, sid, secret)
  68.         self._lock = lock
  69.         self._new = 1
  70.         self._created = 0
  71.         self._accessed = 0
  72.         self._timeout = 0
  73.         self._locked = 0
  74.         self._invalid = 0
  75.         dict.__init__(self)
  76.         if not (self._sid):
  77.             if secret:
  78.                 cookies = Cookie.get_cookies(req, Class = Cookie.SignedCookie, secret = self._secret)
  79.             else:
  80.                 cookies = Cookie.get_cookies(req)
  81.             if cookies.has_key(COOKIE_NAME):
  82.                 self._sid = cookies[COOKIE_NAME].value
  83.             
  84.         
  85.         self.init_lock()
  86.         if self._sid:
  87.             self.lock()
  88.             if self.load():
  89.                 self._new = 0
  90.             
  91.         
  92.         if self._new:
  93.             if self._sid:
  94.                 self.unlock()
  95.             
  96.             self._sid = _new_sid(self._req)
  97.             self.lock()
  98.             Cookie.add_cookie(self._req, self.make_cookie())
  99.             self._created = time.time()
  100.             if timeout:
  101.                 self._timeout = timeout
  102.             else:
  103.                 self._timeout = DFT_TIMEOUT
  104.         
  105.         self._accessed = time.time()
  106.         if random.randint(1, CLEANUP_CHANCE) == 1:
  107.             self.cleanup()
  108.         
  109.  
  110.     
  111.     def make_cookie(self):
  112.         if self._secret:
  113.             c = Cookie.SignedCookie(COOKIE_NAME, self._sid, secret = self._secret)
  114.         else:
  115.             c = Cookie.Cookie(COOKIE_NAME, self._sid)
  116.         config = self._req.get_options()
  117.         if config.has_key('ApplicationPath'):
  118.             c.path = config['ApplicationPath']
  119.         else:
  120.             docroot = self._req.document_root()
  121.             dirpath = self._req.hlist.directory
  122.             c.path = dirpath[len(docroot):]
  123.             if os.name == 'nt' and c.path[-1] == '\\':
  124.                 c.path = c.path[:-1]
  125.             
  126.             if not (c.path) or not self._req.uri.startswith(c.path):
  127.                 c.path = '/'
  128.             
  129.         return c
  130.  
  131.     
  132.     def invalidate(self):
  133.         c = self.make_cookie()
  134.         c.expires = 0
  135.         Cookie.add_cookie(self._req, c)
  136.         self.delete()
  137.         self._invalid = 1
  138.  
  139.     
  140.     def load(self):
  141.         dict = self.do_load()
  142.         if dict == None:
  143.             return 0
  144.         
  145.         if time.time() - dict['_accessed'] > dict['_timeout']:
  146.             return 0
  147.         
  148.         self._created = dict['_created']
  149.         self._accessed = dict['_accessed']
  150.         self._timeout = dict['_timeout']
  151.         self.update(dict['_data'])
  152.         return 1
  153.  
  154.     
  155.     def save(self):
  156.         if not (self._invalid):
  157.             dict = {
  158.                 '_data': self.copy(),
  159.                 '_created': self._created,
  160.                 '_accessed': self._accessed,
  161.                 '_timeout': self._timeout }
  162.             self.do_save(dict)
  163.         
  164.  
  165.     
  166.     def delete(self):
  167.         self.do_delete()
  168.         self.clear()
  169.  
  170.     
  171.     def init_lock(self):
  172.         pass
  173.  
  174.     
  175.     def lock(self):
  176.         if self._lock:
  177.             _apache._global_lock(self._req.server, self._sid)
  178.             self._locked = 1
  179.             self._req.register_cleanup(unlock_session_cleanup, self)
  180.         
  181.  
  182.     
  183.     def unlock(self):
  184.         if self._lock and self._locked:
  185.             _apache._global_unlock(self._req.server, self._sid)
  186.             self._locked = 0
  187.         
  188.  
  189.     
  190.     def is_new(self):
  191.         return not (not (self._new))
  192.  
  193.     
  194.     def id(self):
  195.         return self._sid
  196.  
  197.     
  198.     def created(self):
  199.         return self._created
  200.  
  201.     
  202.     def last_accessed(self):
  203.         return self._accessed
  204.  
  205.     
  206.     def timeout(self):
  207.         return self._timeout
  208.  
  209.     
  210.     def set_timeout(self, secs):
  211.         self._timeout = secs
  212.  
  213.     
  214.     def cleanup(self):
  215.         self.do_cleanup()
  216.  
  217.     
  218.     def __del__(self):
  219.         self.unlock()
  220.  
  221.  
  222.  
  223. def unlock_session_cleanup(sess):
  224.     sess.unlock()
  225.  
  226.  
  227. def dbm_cleanup(data):
  228.     (dbm, server) = data
  229.     _apache._global_lock(server, None, 0)
  230.     db = anydbm.open(dbm, 'c')
  231.     
  232.     try:
  233.         old = []
  234.         s = db.first()
  235.         while None:
  236.             pass
  237.         if None:
  238.             (key, val) = s
  239.             dict = cPickle.loads(val)
  240.             
  241.             try:
  242.                 if time.time() - dict['_accessed'] > dict['_timeout']:
  243.                     old.append(key)
  244.             except KeyError:
  245.                 old.append(key)
  246.  
  247.             
  248.             try:
  249.                 s = db.next()
  250.             continue
  251.             except KeyError:
  252.                 break
  253.                 continue
  254.             
  255.  
  256.         None<EXCEPTION MATCH>KeyError
  257.     finally:
  258.         for key in old:
  259.             
  260.             try:
  261.                 del db[key]
  262.             continue
  263.             continue
  264.  
  265.         db.close()
  266.         _apache._global_unlock(server, None, 0)
  267.  
  268.  
  269.  
  270. class DbmSession(BaseSession):
  271.     
  272.     def __init__(self, req, dbm = None, sid = 0, secret = None, dbmtype = anydbm, timeout = 0, lock = 1):
  273.         if not dbm:
  274.             opts = req.get_options()
  275.             if opts.has_key('SessionDbm'):
  276.                 dbm = opts['SessionDbm']
  277.             else:
  278.                 dbm = os.path.join(tempdir, 'mp_sess.dbm')
  279.         
  280.         self._dbmfile = dbm
  281.         self._dbmtype = dbmtype
  282.         BaseSession.__init__(self, req, sid = sid, secret = secret, timeout = timeout, lock = lock)
  283.  
  284.     
  285.     def _set_dbm_type(self):
  286.         module = whichdb.whichdb(self._dbmfile)
  287.         if module:
  288.             self._dbmtype = __import__(module)
  289.         
  290.  
  291.     
  292.     def _get_dbm(self):
  293.         result = self._dbmtype.open(self._dbmfile, 'c')
  294.         if self._dbmtype is anydbm:
  295.             self._set_dbm_type()
  296.         
  297.         return result
  298.  
  299.     
  300.     def do_cleanup(self):
  301.         data = [
  302.             self._dbmfile,
  303.             self._req.server]
  304.         self._req.register_cleanup(dbm_cleanup, data)
  305.         self._req.log_error('DbmSession: registered database cleanup.', apache.APLOG_NOTICE)
  306.  
  307.     
  308.     def do_load(self):
  309.         _apache._global_lock(self._req.server, None, 0)
  310.         dbm = self._get_dbm()
  311.         
  312.         try:
  313.             if dbm.has_key(self._sid):
  314.                 return cPickle.loads(dbm[self._sid])
  315.             else:
  316.                 return None
  317.         finally:
  318.             dbm.close()
  319.             _apache._global_unlock(self._req.server, None, 0)
  320.  
  321.  
  322.     
  323.     def do_save(self, dict):
  324.         _apache._global_lock(self._req.server, None, 0)
  325.         dbm = self._get_dbm()
  326.         
  327.         try:
  328.             dbm[self._sid] = cPickle.dumps(dict)
  329.         finally:
  330.             dbm.close()
  331.             _apache._global_unlock(self._req.server, None, 0)
  332.  
  333.  
  334.     
  335.     def do_delete(self):
  336.         _apache._global_lock(self._req.server, None, 0)
  337.         dbm = self._get_dbm()
  338.         
  339.         try:
  340.             del dbm[self._sid]
  341.         except KeyError:
  342.             pass
  343.         finally:
  344.             dbm.close()
  345.             _apache._global_unlock(self._req.server, None, 0)
  346.  
  347.  
  348.  
  349.  
  350. def mem_cleanup(sdict):
  351.     for sid in sdict:
  352.         dict = sdict[sid]
  353.         if time.time() - dict['_accessed'] > dict['_timeout']:
  354.             del sdict[sid]
  355.             continue
  356.     
  357.  
  358.  
  359. class MemorySession(BaseSession):
  360.     sdict = { }
  361.     
  362.     def __init__(self, req, sid = 0, secret = None, timeout = 0, lock = 1):
  363.         BaseSession.__init__(self, req, sid = sid, secret = secret, timeout = timeout, lock = lock)
  364.  
  365.     
  366.     def do_cleanup(self):
  367.         self._req.register_cleanup(mem_cleanup, MemorySession.sdict)
  368.         self._req.log_error('MemorySession: registered session cleanup.', apache.APLOG_NOTICE)
  369.  
  370.     
  371.     def do_load(self):
  372.         if MemorySession.sdict.has_key(self._sid):
  373.             return MemorySession.sdict[self._sid]
  374.         
  375.         return None
  376.  
  377.     
  378.     def do_save(self, dict):
  379.         MemorySession.sdict[self._sid] = dict
  380.  
  381.     
  382.     def do_delete(self):
  383.         
  384.         try:
  385.             del MemorySession.sdict[self._sid]
  386.         except KeyError:
  387.             pass
  388.  
  389.  
  390.  
  391.  
  392. def Session(req, sid = 0, secret = None, timeout = 0, lock = 1):
  393.     threaded = _apache.mpm_query(apache.AP_MPMQ_IS_THREADED)
  394.     forked = _apache.mpm_query(apache.AP_MPMQ_IS_FORKED)
  395.     daemons = _apache.mpm_query(apache.AP_MPMQ_MAX_DAEMONS)
  396.     if threaded and not forked or daemons == 1:
  397.         return MemorySession(req, sid = sid, secret = secret, timeout = timeout, lock = lock)
  398.     else:
  399.         return DbmSession(req, sid = sid, secret = secret, timeout = timeout, lock = lock)
  400.  
  401.