-
Notifications
You must be signed in to change notification settings - Fork 0
/
session.go
141 lines (114 loc) · 2.71 KB
/
session.go
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package session
import (
"bytes"
"encoding/gob"
"fmt"
"regexp"
"sync"
"github.com/go-baa/baa"
)
// Session session bag
type Session struct {
provider Provider
sid string
lock sync.RWMutex
data map[interface{}]interface{}
}
// ID returns session id
func (s *Session) ID() string {
return s.sid
}
// Get get a value by the key from session
func (s *Session) Get(key interface{}) interface{} {
s.lock.RLock()
defer s.lock.RUnlock()
return s.data[key]
}
// Set set a value by the key to session
func (s *Session) Set(key interface{}, val interface{}) error {
s.lock.Lock()
defer s.lock.Unlock()
s.data[key] = val
return nil
}
// Delete delete a key from session
func (s *Session) Delete(key interface{}) error {
s.lock.Lock()
defer s.lock.Unlock()
delete(s.data, key)
return nil
}
// Destroy remove all data stored in a session
func (s *Session) Destroy() error {
s.lock.Lock()
defer s.lock.Unlock()
s.data = make(map[interface{}]interface{})
return nil
}
// Close save data in session
func (s *Session) Close() error {
s.lock.Lock()
defer s.lock.Unlock()
return s.provider.Write(s.sid, s.data)
}
// NewSession create a session
func NewSession(provider Provider, sid string, data map[interface{}]interface{}) (*Session, error) {
if provider == nil {
return nil, fmt.Errorf("session.New(): provider cannot be nil")
}
if len(sid) == 0 {
return nil, fmt.Errorf("session.New(): invalid session id")
}
if data == nil {
data = make(map[interface{}]interface{})
}
return &Session{
provider: provider,
sid: sid,
data: data,
}, nil
}
// Middleware returns a middleware for baa
func Middleware(option Options) baa.HandlerFunc {
manager, err := NewManager(option)
if err != nil {
panic(err)
}
go manager.startGC()
var reStatic = regexp.MustCompile(`\.(jpeg|jpg|png|gif|ico|js|css|txt|zip)$`)
return func(c *baa.Context) {
// skip static request
if reStatic.MatchString(c.Req.URL.Path) {
c.Next()
return
}
// Start session
session, err := manager.Start(c)
if err != nil {
panic("session.Start(): " + err.Error())
}
// allows reference session instance in context
c.Set("session", session)
c.Next()
// Close session
if err := session.Close(); err != nil {
panic("session.Close(): " + err.Error())
}
}
}
// EncodeGob encode data by gob
func EncodeGob(object map[interface{}]interface{}) ([]byte, error) {
buf := new(bytes.Buffer)
enc := gob.NewEncoder(buf)
err := enc.Encode(object)
if err == nil {
return buf.Bytes(), nil
}
return nil, err
}
// DecodeGob decode data by gob
func DecodeGob(encoded []byte) (out map[interface{}]interface{}, err error) {
buf := bytes.NewBuffer(encoded)
err = gob.NewDecoder(buf).Decode(&out)
return out, err
}