-
Notifications
You must be signed in to change notification settings - Fork 6
/
session.lisp
48 lines (39 loc) · 1.48 KB
/
session.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
(in-package #:house)
(defparameter *sessions* (make-hash-table :test 'equal))
(defparameter *new-session-hook* nil)
(defmethod new-session-hook! ((callback function))
(push callback *new-session-hook*))
(defun clear-session-hooks! ()
(setf *new-session-hook* nil))
(let ((gen nil))
(defun new-session-token! ()
(unless gen
(setf gen (session-token:make-generator
:token-length 64
:initial-seed #-windows (session-token:init-kernel-seed) #+windows (session-token:init-common-lisp-random-seed))))
#+windows (warn "Running on Windows; using insecure session tokens")
(funcall gen)))
(let ((session-count 0))
(defun new-session! ()
(when (>= (incf session-count) +clean-sessions-every+)
(setf session-count 0)
(clean-sessions!))
(let ((session (make-instance 'session :token (new-session-token!))))
(setf (gethash (token session) *sessions*) session)
(loop for hook in *new-session-hook*
do (funcall hook session))
session)))
(defun get-session! (token)
(awhen (gethash token *sessions*)
(if (idling? it)
(progn (remhash token *sessions*) nil)
(poke! it))))
(defun clean-sessions! ()
(loop for k being the hash-keys of *sessions*
for v being the hash-values of *sessions*
when (idling? v) do (remhash k *sessions*)))
(defmethod idling? ((sess session))
(> (- (get-universal-time) (last-poked sess)) +max-session-idle+))
(defmethod poke! ((sess session))
(setf (last-poked sess) (get-universal-time))
sess)