1 ;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; Base: 10; Package: wol -*-
2 ;;;; *************************************************************************
3 ;;;; FILE IDENTIFICATION
5 ;;;; Name: sessions.lisp
6 ;;;; Purpose: Session handler
7 ;;;; Programmer: Kevin M. Rosenberg
8 ;;;; Date Started: July 2003
12 ;;;; This file and Wol are Copyright (c) 2003 by Kevin M. Rosenberg
13 ;;;; *************************************************************************
18 (defun find-websession (key ent)
19 (let ((sessions (sessions (session-master (entity-project ent)))))
23 (when (equal key (websession-key v))
24 (setf (websession-lastref v) (get-universal-time))
25 (return-from find-websession v)))
29 (defun is-session-enabled (ent)
30 (not (null (sessions (session-master (entity-project ent))))))
33 (defun make-websession (req ent)
34 (let* ((key (random-string :length +length-session-id+
35 :set :lower-alphanumeric))
36 (sess (make-instance 'websession
38 :lastref (get-universal-time)
39 :lifetime (lifetime (session-master (entity-project ent)))
41 (hash (sessions (session-master (entity-project ent)))))
43 (setf (gethash key hash) sess)
44 (setf (websession-from-req req) sess)
48 (defun compute-session (req ent url-session-id)
49 (when (is-session-enabled ent)
50 (let* ((cookie-session-id (cookie-session-key ent (request-cookies req)))
51 (session-id (or url-session-id cookie-session-id))
52 (found-session (when session-id
53 (find-websession session-id ent)))
54 (session (aif found-session
56 (make-websession req ent))))
59 (setf (websession-method session) :cookies))
61 (setf (websession-method session) :url)))
62 (setf (websession-from-req req) session))))
65 ;;; Reap expired sessions
68 (defun start-reaper ()
69 (process-run-function "wol-reaper"
70 (lambda () (reap-sessions) (kmrcl::process-sleep *reap-interval*))))
72 (defun reap-sessions ()
73 (cmsg-c :debug "Reaping")
74 (dolist (expired (find-expired-sessions))
75 (flush-expired expired)))
77 (defun find-expired-sessions ()
78 (loop for s in (all-sessions)
79 when (is-session-expired (car s))
82 (defun all-sessions (&aux s)
85 (declare (ignore name))
86 (let* ((sm (session-master proj))
87 (sessions (when sm (sessions sm))))
92 (push (cons v proj) s))
97 (defmethod flush-expired (s)
98 (let ((sessions (sessions (session-master (cdr s)))))
99 (remhash (car s) sessions)
100 (add-log-entry (cdr s) "flush expired session: key=~A"
101 (websession-key (car s)))))
103 (defun is-session-expired (ws)
104 (> (get-universal-time) (+ (websession-lastref ws)
105 (websession-lifetime ws))))
107 (defun is-raw-session-id (str)
110 (char= #\~ (schar str 0) (schar str (1- (length str))))))
112 (defun raw-session-id->session-id (str)
113 (subseq str 1 (1- (length str))))