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
10 ;;;; $Id: sessions.lisp,v 1.4 2003/08/08 23:40:13 kevin Exp $
12 ;;;; This file and Wol are Copyright (c) 2003 by Kevin M. Rosenberg
13 ;;;; *************************************************************************
19 (awhen (and session-id (find-websession session-id ent))
20 (setf (websession-from-req req) it)
21 (setf (websession-method it) :url))
24 (defun find-websession (key ent)
25 (let ((sessions (sessions (session-master (entity-project ent)))))
29 (when (equal key (websession-key v))
30 (setf (websession-lastref v) (get-universal-time))
31 (return-from find-websession v)))
35 (defun is-session-enabled (ent)
36 (not (null (sessions (session-master (entity-project ent))))))
39 (defun make-websession (req ent)
40 (let* ((key (random-string :length +length-session-id+
41 :set :lower-alphanumeric))
42 (sess (make-instance 'websession
44 :lastref (get-universal-time)
45 :lifetime (lifetime (session-master (entity-project ent)))
47 (hash (sessions (session-master (entity-project ent)))))
49 (setf (gethash key hash) sess)
50 (setf (websession-from-req req) sess)
54 (defun compute-session (req ent)
55 (when (is-session-enabled ent)
56 (let ((key (cookie-session-key ent (request-cookies req)))
60 (setq has-cookie-key t)
61 (when (setq key (url-session-key (request-raw-uri req)))
62 (setq has-url-key t)))
63 (let* ((found-session (when key (find-websession key ent)))
64 (session (aif found-session it (make-websession req ent))))
65 (setf (websession-from-req req) session)
68 (setf (websession-method session) :cookies)
70 (setf (websession-method session) :url))))
74 ;;; Reap expired sessions
77 (defun start-reaper ()
78 (process-run-function "wol-reaper"
79 (lambda () (reap-sessions) (kmrcl::process-sleep *reap-interval*))))
81 (defun reap-sessions ()
82 (cmsg-c :debug "Reaping")
83 (dolist (expired (find-expired-sessions))
84 (flush-expired expired)))
86 (defun find-expired-sessions ()
87 (loop for s in (all-sessions)
88 when (is-session-expired (car s))
91 (defun all-sessions (&aux s)
94 (declare (ignore name))
95 (let* ((sm (session-master proj))
96 (sessions (when sm (sessions sm))))
101 (push (cons v proj) s))
106 (defmethod flush-expired (s)
107 (let ((sessions (sessions (session-master (cdr s)))))
108 (remhash (car s) sessions)
109 (add-log-entry (cdr s) "flush expired session: key=~A"
110 (websession-key (car s)))))
112 (defun is-session-expired (ws)
113 (> (get-universal-time) (+ (websession-lastref ws)
114 (websession-lifetime ws))))
116 (defun is-raw-session-id (str)
119 (char= #\~ (schar str 0) (schar str (1- (length str))))))
121 (defun raw-session-id->session-id (str)
122 (subseq str 1 (1- (length str))))