⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 session.py

📁 Mod_python is an Apache module that embeds the Python interpreter within the server. With mod_python
💻 PY
📖 第 1 页 / 共 2 页
字号:
    def do_delete(self):        _apache._global_lock(self._req.server, None, 0)        dbm = self._get_dbm()        try:            try:                del dbm[self._sid]            except KeyError: pass        finally:            dbm.close()            _apache._global_unlock(self._req.server, None, 0)############################################################################# FileSessionDFT_FAST_CLEANUP = True DFT_VERIFY_CLEANUP = True DFT_GRACE_PERIOD = 240DFT_CLEANUP_TIME_LIMIT = 2# Credits : this was initially contributed by dharana <dharana@dharana.net>class FileSession(BaseSession):    def __init__(self, req, sid=0, secret=None, timeout=0, lock=1,                fast_cleanup=-1, verify_cleanup=-1):                opts = req.get_options()        if fast_cleanup == -1:            if opts.has_key('mod_python.file_session.enable_fast_cleanup'):                self._fast_cleanup = true_or_false(opts.get('mod_python.file_session.enable_fast_cleanup', DFT_FAST_CLEANUP))            else:                # For backwards compatability with versions                # of mod_python prior to 3.3.                self._fast_cleanup = true_or_false(opts.get('session_fast_cleanup', DFT_FAST_CLEANUP))        else:            self._fast_cleanup = fast_cleanup        if verify_cleanup == -1:            if opts.has_key('mod_python.file_session.verify_session_timeout'):                self._verify_cleanup = true_or_false(opts.get('mod_python.file_session.verify_session_timeout', DFT_VERIFY_CLEANUP))            else:                # For backwards compatability with versions                # of mod_python prior to 3.3.                self._verify_cleanup = true_or_false(opts.get('session_verify_cleanup', DFT_VERIFY_CLEANUP))        else:            self._verify_cleanup = verify_cleanup        if opts.has_key('mod_python.file_session.cleanup_grace_period'):            self._grace_period = int(opts.get('mod_python.file_session.cleanup_grace_period', DFT_GRACE_PERIOD))        else:            # For backwards compatability with versions            # of mod_python prior to 3.3.            self._grace_period = int(opts.get('session_grace_period', DFT_GRACE_PERIOD))        if opts.has_key('mod_python.file_session.cleanup_time_limit'):            self._cleanup_time_limit = int(opts.get('mod_python.file_session.cleanup_time_limit',DFT_CLEANUP_TIME_LIMIT))        else:            # For backwards compatability with versions            # of mod_python prior to 3.3.            self._cleanup_time_limit = int(opts.get('session_cleanup_time_limit',DFT_CLEANUP_TIME_LIMIT))        if opts.has_key('mod_python.file_session.database_directory'):            self._sessdir = os.path.join(opts.get('mod_python.file_session.database_directory', tempdir), 'mp_sess')        elif opts.has_key('mod_python.session.database_directory'):            self._sessdir = os.path.join(opts.get('mod_python.session.database_directory', tempdir), 'mp_sess')        else:            # For backwards compatability with versions            # of mod_python prior to 3.3.            self._sessdir = os.path.join(opts.get('session_directory', tempdir), 'mp_sess')        # FIXME        if timeout:            self._cleanup_timeout = timeout        else:            self._cleanup_timeout = DFT_TIMEOUT                BaseSession.__init__(self, req, sid=sid, secret=secret,            timeout=timeout, lock=lock)    def do_cleanup(self):        data = {'req':self._req,                'sessdir':self._sessdir,                'fast_cleanup':self._fast_cleanup,                 'verify_cleanup':self._verify_cleanup,                 'timeout':self._cleanup_timeout,                'grace_period':self._grace_period,                'cleanup_time_limit': self._cleanup_time_limit,               }        self._req.register_cleanup(filesession_cleanup, data)        self._req.log_error("FileSession: registered filesession cleanup.",                            apache.APLOG_NOTICE)    def do_load(self):        self.lock_file()        try:            try:                path = os.path.join(self._sessdir, self._sid[0:2])                filename = os.path.join(path, self._sid)                fp = file(filename,'rb')                try:                    data = cPickle.load(fp)                    if (time.time() - data["_accessed"]) <= data["_timeout"]:                        # Change the file access time to the current time so the                         # cleanup does not delete this file before the request                        # can save it's session data                        os.utime(filename,None)                    return data                finally:                    fp.close()            except:                s = cStringIO.StringIO()                traceback.print_exc(file=s)                s = s.getvalue()                self._req.log_error('Error while loading a session : %s'%s)                return None        finally:            self.unlock_file()    def do_save(self, dict):        self.lock_file()        try:            try:                path = os.path.join(self._sessdir, self._sid[0:2])                if not os.path.exists(path):                    make_filesession_dirs(self._sessdir)                filename = os.path.join(path, self._sid)                fp = file(filename, 'wb')                try:                    cPickle.dump(dict, fp, 2)                finally:                    fp.close()            except:                s = cStringIO.StringIO()                traceback.print_exc(file=s)                s = s.getvalue()                self._req.log_error('Error while saving a session : %s'%s)        finally:            self.unlock_file()    def do_delete(self):        self.lock_file()        try:            try:                path = os.path.join(self._sessdir, self._sid[0:2])                filename = os.path.join(path, self._sid)                os.unlink(filename)            except Exception:                pass        finally:            self.unlock_file()    def lock_file(self):        # self._lock = 1 indicates that session locking is turned on,        # so let BaseSession handle it.        # Otherwise, explicitly acquire a lock for the file manipulation.        if not self._locked:            _apache._global_lock(self._req.server, self._sid)            self._locked = 1    def unlock_file(self):        if self._locked and not self._lock:            _apache._global_unlock(self._req.server, self._sid)            self._locked = 0FS_STAT_VERSION = 'MPFS_3.2'def filesession_cleanup(data):    # There is a small chance that a the cleanup for a given session file    # may occur at the exact time that the session is being accessed by    # another request. It is possible under certain circumstances for that    # session file to be saved in another request only to immediately deleted    # by the cleanup. To avoid this race condition, a session is allowed a     # grace_period before it is considered for deletion by the cleanup.     # As long as the grace_period is longer that the time it takes to complete    # the request (which should normally be less than 1 second), the session will    # not be mistakenly deleted by the cleanup. By doing this we also avoid the    # need to lock individual sessions and bypass any potential deadlock    # situations.       req = data['req']    sessdir = data['sessdir']    fast_cleanup = data['fast_cleanup']    verify_cleanup = data['verify_cleanup']    timeout = data['timeout']    grace_period = data['grace_period']    cleanup_time_limit = data['cleanup_time_limit']    req.log_error('FileSession cleanup: (fast=%s, verify=%s) ...'                    % (fast_cleanup,verify_cleanup),                    apache.APLOG_NOTICE)    lockfile = os.path.join(sessdir,'.mp_sess.lck')    try:        lockfp = os.open(lockfile, os.O_CREAT | os.O_EXCL | os.O_WRONLY, 0660)     except:        # check if it's a stale lockfile        mtime = os.stat(lockfile).st_mtime        if mtime < (time.time() - 3600):            # lockfile is over an hour old so it's likely stale.            # Even though there may not be another cleanup process running,            # we are going to defer running the cleanup at this time.            # Short circuiting this cleanup just makes the code a little cleaner.            req.log_error('FileSession cleanup: stale lockfile found - deleting it',                        apache.APLOG_NOTICE)            # Remove the stale lockfile so the next call to filesession_cleanup            # can proceed.            os.remove(lockfile)        else:            req.log_error('FileSession cleanup: another process is already running',                        apache.APLOG_NOTICE)        return    try:        status_file = file(os.path.join(sessdir, 'fs_status.txt'), 'r')        d = status_file.readline()        status_file.close()        if not d.startswith(FS_STAT_VERSION):            raise Exception, 'wrong status file version'        parts = d.split()                stat_version = parts[0]        next_i = int(parts[1])        expired_file_count = int(parts[2])        total_file_count = int(parts[3])        total_time = float(parts[4])    except:        stat_version = FS_STAT_VERSION         next_i = 0        expired_file_count = 0         total_file_count =  0        total_time = 0.0     try:        start_time = time.time()        filelist =  os.listdir(sessdir)        dir_index = range(0,256)[next_i:]        for i in dir_index:            path = '%s/%s' % (sessdir,'%02x' % i)            if not os.path.exists(path):                continue                    filelist = os.listdir(path)            total_file_count += len(filelist)            for f in filelist:                try:                    filename = os.path.join(path,f)                    if fast_cleanup:                        accessed = os.stat(filename).st_mtime                        if time.time() - accessed < (timeout + grace_period):                            continue                    if fast_cleanup and not verify_cleanup:                                delete_session = True                    else:                        try:                            fp = file(filename)                            dict = cPickle.load(fp)                            if (time.time() - dict['_accessed']) > (dict['_timeout'] + grace_period):                                delete_session = True                            else:                                delete_session = False                        finally:                            fp.close()                    if delete_session:                        os.unlink(filename)                        expired_file_count += 1                except:                    s = cStringIO.StringIO()                    traceback.print_exc(file=s)                    s = s.getvalue()                    req.log_error('FileSession cleanup error: %s'                                    % (s),                                    apache.APLOG_NOTICE)            next_i = (i + 1) % 256            time_used = time.time() - start_time             if (cleanup_time_limit > 0) and (time_used > cleanup_time_limit):                break        total_time += time.time() - start_time        if next_i == 0:            # next_i can only be 0 when the full cleanup has run to completion            req.log_error("FileSession cleanup: deleted %d of %d in %.4f seconds"                            % (expired_file_count, total_file_count, total_time),                            apache.APLOG_NOTICE)            expired_file_count = 0            total_file_count = 0            total_time = 0.0        else:            req.log_error("FileSession cleanup incomplete: next cleanup will start at index %d (%02x)"                        % (next_i,),                        apache.APLOG_NOTICE)        status_file = file(os.path.join(sessdir, 'fs_status.txt'), 'w')        status_file.write('%s %d %d %d %f\n' % (stat_version, next_i, expired_file_count, total_file_count, total_time))        status_file.close()           try:            os.unlink(lockfile)        except:            pass    finally:        os.close(lockfp)def make_filesession_dirs(sess_dir):    """Creates the directory structure used for storing session files"""    for i in range(0,256):        path = os.path.join(sess_dir, '%02x' % i)        if not os.path.exists(path):            os.makedirs(path,  stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP)############################################################################# MemorySessiondef mem_cleanup(sdict):    for sid in sdict.keys():        try:            session = sdict[sid]            if (time.time() - session["_accessed"]) > session["_timeout"]:                del sdict[sid]        except:            passclass MemorySession(BaseSession):    sdict = {}    def __init__(self, req, sid=0, secret=None, timeout=0, lock=1):        BaseSession.__init__(self, req, sid=sid, secret=secret,                             timeout=timeout, lock=lock)    def do_cleanup(self):        self._req.register_cleanup(mem_cleanup, MemorySession.sdict)        self._req.log_error("MemorySession: registered session cleanup.",                            apache.APLOG_NOTICE)    def do_load(self):        if MemorySession.sdict.has_key(self._sid):            return MemorySession.sdict[self._sid]        return None    def do_save(self, dict):        MemorySession.sdict[self._sid] = dict    def do_delete(self):        try:            del MemorySession.sdict[self._sid]        except KeyError: pass############################################################################# Sessiondef Session(req, sid=0, secret=None, timeout=0, lock=1):    opts = req.get_options()    # Check the apache config for the type of session    if opts.has_key('mod_python.session.session_type'):        sess_type = opts['mod_python.session.session_type']    elif opts.has_key('session'):        # For backwards compatability with versions        # of mod_python prior to 3.3.        sess_type = opts['session']    else:        # no session class in config so get the default for the platform        threaded = _apache.mpm_query(apache.AP_MPMQ_IS_THREADED)        forked = _apache.mpm_query(apache.AP_MPMQ_IS_FORKED)        daemons =  _apache.mpm_query(apache.AP_MPMQ_MAX_DAEMONS)        if (threaded and ((not forked) or (daemons == 1))):            sess_type = 'MemorySession'        else:            sess_type = 'DbmSession'    if sess_type == 'FileSession':        sess =  FileSession    elif sess_type == 'DbmSession':        sess = DbmSession    elif sess_type == 'MemorySession':        sess = MemorySession    else:        # TODO Add capability to load a user defined class        # For now, just raise an exception.        raise Exception, 'Unknown session type %s' % sess_type    return sess(req, sid=sid, secret=secret,                         timeout=timeout, lock=lock)## helper functionsdef true_or_false(item):    """This function is used to assist in getting appropriate    values set with the PythonOption directive    """    try:        item = item.lower()    except:        pass    if item in ['yes','true', '1', 1, True]:        return True    elif item in ['no', 'false', '0', 0, None, False]:        return False    else:        raise Exception

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -