|
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()
>
>
>
>
>
|