X-Git-Url: http://git.kpe.io/?p=wol.git;a=blobdiff_plain;f=sessions.lisp;h=6c63e0433bd82499164e6655b6dac95db9d4736c;hp=227483bab3dabc19313794702c6a80d9db9bb87c;hb=HEAD;hpb=de82da84115f8e2a6ad7add24cb73e7876c89a3b diff --git a/sessions.lisp b/sessions.lisp index 227483b..6c63e04 100644 --- a/sessions.lisp +++ b/sessions.lisp @@ -7,56 +7,107 @@ ;;;; Programmer: Kevin M. Rosenberg ;;;; Date Started: July 2003 ;;;; -;;;; $Id: sessions.lisp,v 1.1 2003/07/16 16:02:21 kevin Exp $ +;;;; $Id$ ;;;; ;;;; This file and Wol are Copyright (c) 2003 by Kevin M. Rosenberg ;;;; ************************************************************************* (in-package #:wol) -(defun start-reaper () - (process-run-function "wol-reaper" - (lambda () (reap-sessions) (kmrcl::process-sleep *reap-interval*)))) -(defun reap-sessions () - (cmsg-c :debug "Reaping")) +(defun find-websession (key ent) + (let ((sessions (sessions (session-master (entity-project ent))))) + (maphash + (lambda (k v) + (declare (ignore k)) + (when (equal key (websession-key v)) + (setf (websession-lastref v) (get-universal-time)) + (return-from find-websession v))) + sessions) + nil)) -(defun make-new-session-id () - (random-string :length 24 :set :lower-alphanumeric)) +(defun is-session-enabled (ent) + (not (null (sessions (session-master (entity-project ent)))))) -(defun ensure-websession (key req ent method) - "Find or make websession for key" - (let ((sessions (sessions (session-master (entity-project ent))))) - ;; if sessions doesn't exist, then project is not session enabled - (when session - (cond - ((null key) - (make-websession req ent method)) - (t - (maphash - (lambda (k v) - (declare (ignore k)) - (when (equal key (websession-key v)) - (setf (websession-lastref v) (get-universal-time)) - (return-from ensure-websession v))) - sessions) - (make-websession req ent method)))))) - - -(defun make-websession (req ent method) - (let* ((key (random-string :length 24 :set :lower-alphanumeric)) - (sess (make-instance 'websession - :key key - :lastref (get-universal-time) - :method method)) - (hash (sessions (session-master (entity-project ent))))) + +(defun make-websession (req ent) + (let* ((key (random-string :length +length-session-id+ + :set :lower-alphanumeric)) + (sess (make-instance 'websession + :key key + :lastref (get-universal-time) + :lifetime (lifetime (session-master (entity-project ent))) + :method :try-cookie)) + (hash (sessions (session-master (entity-project ent))))) (when hash (setf (gethash key hash) sess) (setf (websession-from-req req) sess) sess))) -(defun compute-session (req ent) - (awhen (and (request-plist req) - (getf (request-plist req) :session-id)) - (setf (websession-from-req req) - (ensure-websession it req ent :uri)))) + +(defun compute-session (req ent url-session-id) + (when (is-session-enabled ent) + (let* ((cookie-session-id (cookie-session-key ent (request-cookies req))) + (session-id (or url-session-id cookie-session-id)) + (found-session (when session-id + (find-websession session-id ent))) + (session (aif found-session + it + (make-websession req ent)))) + (cond + (cookie-session-id + (setf (websession-method session) :cookies)) + (url-session-id + (setf (websession-method session) :url))) + (setf (websession-from-req req) session)))) + + +;;; Reap expired sessions + + +(defun start-reaper () + (process-run-function "wol-reaper" + (lambda () (reap-sessions) (kmrcl::process-sleep *reap-interval*)))) + +(defun reap-sessions () + (cmsg-c :debug "Reaping") + (dolist (expired (find-expired-sessions)) + (flush-expired expired))) + +(defun find-expired-sessions () + (loop for s in (all-sessions) + when (is-session-expired (car s)) + collect s)) + +(defun all-sessions (&aux s) + (maphash + (lambda (name proj) + (declare (ignore name)) + (let* ((sm (session-master proj)) + (sessions (when sm (sessions sm)))) + (when sessions + (maphash + (lambda (k v) + (declare (ignore k)) + (push (cons v proj) s)) + sessions)))) + *active-projects*) + s) + +(defmethod flush-expired (s) + (let ((sessions (sessions (session-master (cdr s))))) + (remhash (car s) sessions) + (add-log-entry (cdr s) "flush expired session: key=~A" + (websession-key (car s))))) + +(defun is-session-expired (ws) + (> (get-universal-time) (+ (websession-lastref ws) + (websession-lifetime ws)))) + +(defun is-raw-session-id (str) + (and (stringp str) + (> (length str) 2) + (char= #\~ (schar str 0) (schar str (1- (length str)))))) + +(defun raw-session-id->session-id (str) + (subseq str 1 (1- (length str))))