Browse Source

Remove expired sessions from server memory

Toni Fadjukoff 6 years ago
parent
commit
c12799395f
1 changed files with 63 additions and 6 deletions
  1. 63 6
      auth.go

+ 63 - 6
auth.go View File

@@ -1,6 +1,7 @@
1 1
 package main
2 2
 
3 3
 import (
4
+	"container/heap"
4 5
 	"crypto/rand"
5 6
 	"encoding/base64"
6 7
 	"errors"
@@ -10,13 +11,68 @@ import (
10 11
 )
11 12
 
12 13
 type SessionData struct {
14
+	sid      string
13 15
 	username string
16
+	priority time.Time
17
+	index    int
18
+}
19
+
20
+type SessionQueue []*SessionData
21
+
22
+func (pq SessionQueue) Len() int {
23
+	return len(pq)
24
+}
25
+
26
+func (pq SessionQueue) Less(i, j int) bool {
27
+	return pq[i].priority.Before(pq[j].priority)
28
+}
29
+
30
+func (pq SessionQueue) Swap(i, j int) {
31
+	pq[i], pq[j] = pq[j], pq[i]
32
+	pq[i].index = i
33
+	pq[j].index = j
34
+}
35
+
36
+func (pq *SessionQueue) Push(x interface{}) {
37
+	n := len(*pq)
38
+	item := x.(*SessionData)
39
+	item.index = n
40
+	*pq = append(*pq, item)
41
+}
42
+
43
+func (pq *SessionQueue) Pop() interface{} {
44
+	old := *pq
45
+	n := len(old)
46
+	item := old[n-1]
47
+	item.index = -1 // for safety
48
+	*pq = old[0 : n-1]
49
+	return item
14 50
 }
15 51
 
16 52
 var (
17
-	sessions = make(map[string]*SessionData)
53
+	sessions     = make(map[string]*SessionData)
54
+	sessionQueue = make(SessionQueue, 0)
18 55
 )
19 56
 
57
+func sessionExpirer() {
58
+	for {
59
+		for len(sessionQueue) > 0 && time.Now().After(sessionQueue[0].priority) {
60
+			session := heap.Pop(&sessionQueue).(*SessionData)
61
+			delete(sessions, session.sid)
62
+		}
63
+		time.Sleep(time.Second * 5)
64
+	}
65
+}
66
+
67
+func init() {
68
+	go sessionExpirer()
69
+}
70
+
71
+func addSession(data *SessionData) {
72
+	sessions[data.sid] = data
73
+	heap.Push(&sessionQueue, data)
74
+}
75
+
20 76
 func userOk(username, password string) bool {
21 77
 	return (username == "Lamperi" && password == "paskaa")
22 78
 }
@@ -32,20 +88,21 @@ func tryLogin(username, password string, longerTime bool) (http.Cookie, error) {
32 88
 		return http.Cookie{}, err
33 89
 	}
34 90
 
35
-	sessions[sid] = &SessionData{username}
36
-
37
-	hours := time.Duration(1)
91
+	duration := time.Hour * 1
38 92
 	if longerTime {
39
-		hours = time.Duration(336)
93
+		duration = time.Hour * 24 * 14
40 94
 	}
41 95
 
42 96
 	loginCookie := http.Cookie{
43 97
 		Name:     "id",
44 98
 		Value:    sid,
45
-		MaxAge:   int((time.Hour * hours).Seconds()),
99
+		MaxAge:   int(duration.Seconds()),
46 100
 		HttpOnly: true,
47 101
 	}
48 102
 
103
+	expiration := time.Now().Add(duration)
104
+	addSession(&SessionData{sid, username, expiration, 0})
105
+
49 106
 	return loginCookie, nil
50 107
 }
51 108