|
Norman Tindall
NormanTindall at zdisk.net
Thu Aug 10 14:26:38 EDT 2006
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()
--
Best regards,
Norman mailto:NormanTindall at zdisk.net
|