/
store.go
113 lines (94 loc) · 2.11 KB
/
store.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
package session
import (
"encoding/gob"
"sync"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/internal/storage/memory"
"github.com/gofiber/fiber/v2/utils"
"github.com/valyala/fasthttp"
)
type Store struct {
Config
}
var mux sync.Mutex
func New(config ...Config) *Store {
// Set default config
cfg := configDefault(config...)
if cfg.Storage == nil {
cfg.Storage = memory.New()
}
return &Store{
cfg,
}
}
// RegisterType will allow you to encode/decode custom types
// into any Storage provider
func (s *Store) RegisterType(i interface{}) {
gob.Register(i)
}
// Get will get/create a session
func (s *Store) Get(c *fiber.Ctx) (*Session, error) {
var fresh bool
var loadDada = true
// Get key from cookie
id := c.Cookies(s.CookieName)
if len(id) == 0 {
fresh = true
var err error
if id, err = s.responseCookies(c); err != nil {
return nil, err
}
}
// If no key exist, create new one
if len(id) == 0 {
loadDada = false
id = s.KeyGenerator()
}
// Create session object
sess := acquireSession()
sess.ctx = c
sess.config = s
sess.id = id
sess.fresh = fresh
// Fetch existing data
if loadDada {
raw, err := s.Storage.Get(id)
// Unmashal if we found data
if raw != nil && err == nil {
mux.Lock()
defer mux.Unlock()
_, _ = sess.byteBuffer.Write(raw)
encCache := gob.NewDecoder(sess.byteBuffer)
err := encCache.Decode(&sess.data.Data)
if err != nil {
return nil, err
}
} else if err != nil {
return nil, err
} else {
sess.fresh = true
}
}
return sess, nil
}
func (s *Store) responseCookies(c *fiber.Ctx) (string, error) {
// Get key from response cookie
cookieValue := c.Response().Header.PeekCookie(s.CookieName)
if len(cookieValue) == 0 {
return "", nil
}
cookie := fasthttp.AcquireCookie()
defer fasthttp.ReleaseCookie(cookie)
err := cookie.ParseBytes(cookieValue)
if err != nil {
return "", err
}
value := make([]byte, len(cookie.Value()))
copy(value, cookie.Value())
id := utils.UnsafeString(value)
return id, nil
}
// Reset will delete all session from the storage
func (s *Store) Reset() error {
return s.Storage.Reset()
}