Jim Gallacher
jpg at jgassociates.ca
Fri Aug 11 12:29:59 EDT 2006
It mostly looks ok, but I really don't have a lot of spare time to audit a new session handling implementation. That's one of the disadvantages of writing things from scratch I guess. Jim Norman Tindall wrote: > Hello Jim, > So far by now i already wrote raw working code, > I know that it can invalidate a valid session, i have read this > about 2 thread A and B.. for now i can stand with this.. > Will make something like transactions in future.. > > The question is: Is Session based on this class realy locked? > > ############################################## > class MySQLSession(object): > > def __init__(self, req, sid=0, secret=None, timeout=0, create_new = 0 ): > self._lock = 1 > self._locked = 0 > self.cursors = req.cursors > self._req, self._sid = req, sid > if self._sid: > self._create_new = 1 > else: > self._create_new = create_new > self._new = 0 > self._created = 0 > self._accessed = 0 > self._timeout = 1000000 > self._invalid = 0 > > self.data = {} > > if secret: self._secret = secret > else: self._secret = "secret007" > self.session_cookie_name = "OxSess" > > > if not self._sid: > cookies = Cookie.get_cookies(req, Class=Cookie.SignedCookie, secret=self._secret) > if cookies.has_key(self.session_cookie_name): > self._sid = cookies[ self.session_cookie_name ].value > > if self._sid: > if not _check_sid(self._sid): > self._req.log_error("mod_python.Session warning: The session id contains invalid characters", > apache.APLOG_WARNING) > raise apache.SERVER_RETURN, apache.HTTP_INTERNAL_SERVER_ERROR > > ############ CLEANUP ############## > if random.randint(1, CLEANUP_CHANCE) == 1: > self.cleanup() > ################################### > > if self._create_new: > if self._sid: > self.delete() # del old one > self.unlock() # unlock old one > self.create_new_sess() > else: > self.create_new_sess() > > else: > if self._sid: > # attempt to load ourselves > self.lock() > if self.load(): > self._new = 0 > else: > # no sid no session > return None > > > > def create_new_sess(self): > self._sid = _new_sid(self._req) > self.lock() # lock new sid > Cookie.add_cookie(self._req, self.make_cookie()) > self._created = time.time() > self._accessed = self._created > self._new = 1 > > # LOCK > > def lock(self): > if self._lock: > _apache._global_lock(self._req.server, self._sid) > self._locked = 1 > self._req.register_cleanup(unlock_session_cleanup, self) > > # UNLOCK > > def unlock(self): > if self._lock and self._locked: > _apache._global_unlock(self._req.server, self._sid) > self._locked = 0 > > > def load(self): > # selecting only alive sessions > self.cursors['c'].execute( > """select UNIX_TIMESTAMP() as ACCESS_TIME,TIMEOUT,CREATE_DATE,DATA from sessions where SESS_MD = %s and > DATE_ADD(ACCESS_TIME, INTERVAL TIMEOUT SECOND) > CURRENT_TIMESTAMP()""", (self._sid,) ) > row = self.cursors['c'].fetchone() > > if row is not None: > # assigning attributes > self._accessed = row[0] > self._timeout = row[1] > self._created = row[2] > self.data = cPickle.loads(row[3]) > return 1 > else: > return 0 > > def save(self): > if not self._invalid: > > self.cursors['c'].execute("""replace into sessions > (SESS_MD,ACCESS_TIME,TIMEOUT,CREATE_DATE,DATA) values (%s,NULL,%s,FROM_UNIXTIME(%s),%s)""", > (self._sid,self._timeout,self._created, cPickle.dumps(self.data) )) > > > def invalidate(self): > c = self.make_cookie() > c.expires = 0 > Cookie.add_cookie(self._req, c) > self.delete() > self._invalid = 1 > > def make_cookie(self): > c = Cookie.SignedCookie(self.session_cookie_name, self._sid, secret=self._secret) > c.path = '/' > return c > > def cleanup(self): > self.cursors['c'].execute("delete from sessions where DATE_ADD(ACCESS_TIME, INTERVAL TIMEOUT SECOND) < CURRENT_TIMESTAMP()") > > def delete(self): > self.cursors['c'].execute("delete from sessions where SESS_MD=%s", (self._sid,)) > # erasing attributes ! > > ####### > def is_new(self): > return not not self._new > > def id(self): > return self._sid > > def created(self): > return self._created > > def last_accessed(self): > return self._accessed > > def timeout(self): > return self._timeout > > def set_timeout(self, secs): > self._timeout = secs > > def __del__(self): > self.unlock() > > > def unlock_session_cleanup(sess): > sess.unlock() > > > > >
|