summaryrefslogtreecommitdiff
path: root/paste/session.py
diff options
context:
space:
mode:
authorianb <devnull@localhost>2006-10-20 04:34:05 +0000
committerianb <devnull@localhost>2006-10-20 04:34:05 +0000
commit0309aed5f854a375d944191358ccfab9191c5034 (patch)
treec527da33c18068d60ce414e404247e7dd558b508 /paste/session.py
parentf418617343a21ea16097892ea338c8eab18c0c56 (diff)
downloadpaste-0309aed5f854a375d944191358ccfab9191c5034.tar.gz
Added session cleanup, from patch by Amir
Diffstat (limited to 'paste/session.py')
-rw-r--r--paste/session.py82
1 files changed, 79 insertions, 3 deletions
diff --git a/paste/session.py b/paste/session.py
index 6cddf5d..3219fab 100644
--- a/paste/session.py
+++ b/paste/session.py
@@ -28,6 +28,9 @@ import time
import random
import os
import md5
+import datetime
+import threading
+
try:
import cPickle
except ImportError:
@@ -68,10 +71,15 @@ class SessionMiddleware(object):
session_factory.close()
return wsgilib.add_start_close(app_iter, start, close)
+
class SessionFactory(object):
+
def __init__(self, environ, cookie_name='_SID_',
- session_class=None, **session_class_kw):
+ session_class=None,
+ expiration=60*12, # in minutes
+ **session_class_kw):
+
self.created = False
self.used = False
self.environ = environ
@@ -80,6 +88,9 @@ class SessionFactory(object):
self.session_class = session_class or FileSession
self.session_class_kw = session_class_kw
+ self.expiration = expiration
+ self.session_class_kw['expiration'] = self.expiration
+
def __call__(self):
self.used = True
if self.session is not None:
@@ -99,6 +110,7 @@ class SessionFactory(object):
self.sid = self.make_sid()
session = self.session_class(self.sid, create=True,
**self.session_class_kw)
+ session.clean_up()
self.session = session
return session.data()
@@ -140,6 +152,10 @@ class SessionFactory(object):
c = SimpleCookie()
c[self.cookie_name] = self.sid
c[self.cookie_name]['path'] = '/'
+
+ gmt_expiration_time = time.gmtime(time.time() + (self.expiration * 60))
+ c[self.cookie_name]['expires'] = time.strftime("%a, %d-%b-%Y %H:%M:%S GMT", gmt_expiration_time)
+
name, value = str(c).split(': ', 1)
return (name, value)
@@ -147,10 +163,17 @@ class SessionFactory(object):
if self.session is not None:
self.session.close()
+
+last_cleanup = None
+cleaning_up = False
+cleanup_cycle = datetime.timedelta(seconds=15*60) #15 min
+
class FileSession(object):
-
+
def __init__(self, sid, create=False, session_file_path='/tmp',
- chmod=None):
+ chmod=None,
+ expiration=2880, # in minutes: 48 hours
+ ):
if chmod and isinstance(chmod, basestring):
chmod = int(chmod, 8)
self.chmod = chmod
@@ -164,6 +187,9 @@ class FileSession(object):
raise KeyError
self._data = None
+ self.expiration = expiration
+
+
def filename(self):
return os.path.join(self.session_file_path, self.sid)
@@ -191,3 +217,53 @@ class FileSession(object):
f.close()
if not exists and self.chmod:
os.chmod(filename, self.chmod)
+
+ def _clean_up(self):
+ global cleaning_up
+ try:
+ exp_time = datetime.timedelta(seconds=self.expiration*60)
+ now = datetime.datetime.now()
+
+ #Open every session and check that it isn't too old
+ for root, dirs, files in os.walk(self.session_file_path):
+ for f in files:
+ self._clean_up_file(f)
+ finally:
+ cleaning_up = False
+
+ def _clean_up_file(self, f):
+ t = f.split("-")
+ if len(t) != 2:
+ return
+ t = t[0]
+ sess_time = datetime.datetime(
+ int(t[0:4]),
+ int(t[4:6]),
+ int(t[6:8]),
+ int(t[8:10]),
+ int(t[10:12]),
+ int(t[12:14]))
+
+ if sess_time + exp_time < now:
+ os.remove(os.path.join(self.session_file_path, f))
+
+ def clean_up(self):
+ global last_cleanup, cleanup_cycle, cleaning_up
+ now = datetime.datetime.now()
+
+ if cleaning_up:
+ return
+
+ if not last_cleanup or last_cleanup + cleanup_cycle < now:
+ if not cleaning_up:
+ cleaning_up = True
+ try:
+ last_cleanup = now
+ t = threading.Thread(target=self._clean_up)
+ t.start()
+ except:
+ # Normally _clean_up should set cleaning_up
+ # to false, but if something goes wrong starting
+ # it...
+ cleaning_up = False
+ raise