0e287232 by 傅小黑

add comments for session packages, part 1

1 parent ab8f8d53
...@@ -11,12 +11,15 @@ import ( ...@@ -11,12 +11,15 @@ import (
11 11
12 var cookiepder = &CookieProvider{} 12 var cookiepder = &CookieProvider{}
13 13
14 // Cookie SessionStore
14 type CookieSessionStore struct { 15 type CookieSessionStore struct {
15 sid string 16 sid string
16 values map[interface{}]interface{} //session data 17 values map[interface{}]interface{} // session data
17 lock sync.RWMutex 18 lock sync.RWMutex
18 } 19 }
19 20
21 // Set value to cookie session.
22 // the value are encoded as gob with hash block string.
20 func (st *CookieSessionStore) Set(key, value interface{}) error { 23 func (st *CookieSessionStore) Set(key, value interface{}) error {
21 st.lock.Lock() 24 st.lock.Lock()
22 defer st.lock.Unlock() 25 defer st.lock.Unlock()
...@@ -24,6 +27,7 @@ func (st *CookieSessionStore) Set(key, value interface{}) error { ...@@ -24,6 +27,7 @@ func (st *CookieSessionStore) Set(key, value interface{}) error {
24 return nil 27 return nil
25 } 28 }
26 29
30 // Get value from cookie session
27 func (st *CookieSessionStore) Get(key interface{}) interface{} { 31 func (st *CookieSessionStore) Get(key interface{}) interface{} {
28 st.lock.RLock() 32 st.lock.RLock()
29 defer st.lock.RUnlock() 33 defer st.lock.RUnlock()
...@@ -35,6 +39,7 @@ func (st *CookieSessionStore) Get(key interface{}) interface{} { ...@@ -35,6 +39,7 @@ func (st *CookieSessionStore) Get(key interface{}) interface{} {
35 return nil 39 return nil
36 } 40 }
37 41
42 // Delete value in cookie session
38 func (st *CookieSessionStore) Delete(key interface{}) error { 43 func (st *CookieSessionStore) Delete(key interface{}) error {
39 st.lock.Lock() 44 st.lock.Lock()
40 defer st.lock.Unlock() 45 defer st.lock.Unlock()
...@@ -42,6 +47,7 @@ func (st *CookieSessionStore) Delete(key interface{}) error { ...@@ -42,6 +47,7 @@ func (st *CookieSessionStore) Delete(key interface{}) error {
42 return nil 47 return nil
43 } 48 }
44 49
50 // Clean all values in cookie session
45 func (st *CookieSessionStore) Flush() error { 51 func (st *CookieSessionStore) Flush() error {
46 st.lock.Lock() 52 st.lock.Lock()
47 defer st.lock.Unlock() 53 defer st.lock.Unlock()
...@@ -49,10 +55,12 @@ func (st *CookieSessionStore) Flush() error { ...@@ -49,10 +55,12 @@ func (st *CookieSessionStore) Flush() error {
49 return nil 55 return nil
50 } 56 }
51 57
58 // Return id of this cookie session
52 func (st *CookieSessionStore) SessionID() string { 59 func (st *CookieSessionStore) SessionID() string {
53 return st.sid 60 return st.sid
54 } 61 }
55 62
63 // Write cookie session to http response cookie
56 func (st *CookieSessionStore) SessionRelease(w http.ResponseWriter) { 64 func (st *CookieSessionStore) SessionRelease(w http.ResponseWriter) {
57 str, err := encodeCookie(cookiepder.block, 65 str, err := encodeCookie(cookiepder.block,
58 cookiepder.config.SecurityKey, 66 cookiepder.config.SecurityKey,
...@@ -79,12 +87,21 @@ type cookieConfig struct { ...@@ -79,12 +87,21 @@ type cookieConfig struct {
79 Maxage int `json:"maxage"` 87 Maxage int `json:"maxage"`
80 } 88 }
81 89
90 // Cookie session provider
82 type CookieProvider struct { 91 type CookieProvider struct {
83 maxlifetime int64 92 maxlifetime int64
84 config *cookieConfig 93 config *cookieConfig
85 block cipher.Block 94 block cipher.Block
86 } 95 }
87 96
97 // Init cookie session provider with max lifetime and config json.
98 // maxlifetime is ignored.
99 // json config:
100 // securityKey - hash string
101 // blockKey - gob encode hash string. it's saved as aes crypto.
102 // securityName - recognized name in encoded cookie string
103 // cookieName - cookie name
104 // maxage - cookie max life time.
88 func (pder *CookieProvider) SessionInit(maxlifetime int64, config string) error { 105 func (pder *CookieProvider) SessionInit(maxlifetime int64, config string) error {
89 pder.config = &cookieConfig{} 106 pder.config = &cookieConfig{}
90 err := json.Unmarshal([]byte(config), pder.config) 107 err := json.Unmarshal([]byte(config), pder.config)
...@@ -104,6 +121,8 @@ func (pder *CookieProvider) SessionInit(maxlifetime int64, config string) error ...@@ -104,6 +121,8 @@ func (pder *CookieProvider) SessionInit(maxlifetime int64, config string) error
104 return nil 121 return nil
105 } 122 }
106 123
124 // Get SessionStore in cooke.
125 // decode cooke string to map and put into SessionStore with sid.
107 func (pder *CookieProvider) SessionRead(sid string) (SessionStore, error) { 126 func (pder *CookieProvider) SessionRead(sid string) (SessionStore, error) {
108 maps, _ := decodeCookie(pder.block, 127 maps, _ := decodeCookie(pder.block,
109 pder.config.SecurityKey, 128 pder.config.SecurityKey,
...@@ -116,26 +135,32 @@ func (pder *CookieProvider) SessionRead(sid string) (SessionStore, error) { ...@@ -116,26 +135,32 @@ func (pder *CookieProvider) SessionRead(sid string) (SessionStore, error) {
116 return rs, nil 135 return rs, nil
117 } 136 }
118 137
138 // Cookie session is always existed
119 func (pder *CookieProvider) SessionExist(sid string) bool { 139 func (pder *CookieProvider) SessionExist(sid string) bool {
120 return true 140 return true
121 } 141 }
122 142
143 // Implement method, no used.
123 func (pder *CookieProvider) SessionRegenerate(oldsid, sid string) (SessionStore, error) { 144 func (pder *CookieProvider) SessionRegenerate(oldsid, sid string) (SessionStore, error) {
124 return nil, nil 145 return nil, nil
125 } 146 }
126 147
148 // Implement method, no used.
127 func (pder *CookieProvider) SessionDestroy(sid string) error { 149 func (pder *CookieProvider) SessionDestroy(sid string) error {
128 return nil 150 return nil
129 } 151 }
130 152
153 // Implement method, no used.
131 func (pder *CookieProvider) SessionGC() { 154 func (pder *CookieProvider) SessionGC() {
132 return 155 return
133 } 156 }
134 157
158 // Implement method, return 0.
135 func (pder *CookieProvider) SessionAll() int { 159 func (pder *CookieProvider) SessionAll() int {
136 return 0 160 return 0
137 } 161 }
138 162
163 // Implement method, no used.
139 func (pder *CookieProvider) SessionUpdate(sid string) error { 164 func (pder *CookieProvider) SessionUpdate(sid string) error {
140 return nil 165 return nil
141 } 166 }
......
...@@ -18,6 +18,7 @@ var ( ...@@ -18,6 +18,7 @@ var (
18 gcmaxlifetime int64 18 gcmaxlifetime int64
19 ) 19 )
20 20
21 // File session store
21 type FileSessionStore struct { 22 type FileSessionStore struct {
22 f *os.File 23 f *os.File
23 sid string 24 sid string
...@@ -25,6 +26,7 @@ type FileSessionStore struct { ...@@ -25,6 +26,7 @@ type FileSessionStore struct {
25 values map[interface{}]interface{} 26 values map[interface{}]interface{}
26 } 27 }
27 28
29 // Set value to file session
28 func (fs *FileSessionStore) Set(key, value interface{}) error { 30 func (fs *FileSessionStore) Set(key, value interface{}) error {
29 fs.lock.Lock() 31 fs.lock.Lock()
30 defer fs.lock.Unlock() 32 defer fs.lock.Unlock()
...@@ -32,6 +34,7 @@ func (fs *FileSessionStore) Set(key, value interface{}) error { ...@@ -32,6 +34,7 @@ func (fs *FileSessionStore) Set(key, value interface{}) error {
32 return nil 34 return nil
33 } 35 }
34 36
37 // Get value from file session
35 func (fs *FileSessionStore) Get(key interface{}) interface{} { 38 func (fs *FileSessionStore) Get(key interface{}) interface{} {
36 fs.lock.RLock() 39 fs.lock.RLock()
37 defer fs.lock.RUnlock() 40 defer fs.lock.RUnlock()
...@@ -43,6 +46,7 @@ func (fs *FileSessionStore) Get(key interface{}) interface{} { ...@@ -43,6 +46,7 @@ func (fs *FileSessionStore) Get(key interface{}) interface{} {
43 return nil 46 return nil
44 } 47 }
45 48
49 // Delete value in file session by given key
46 func (fs *FileSessionStore) Delete(key interface{}) error { 50 func (fs *FileSessionStore) Delete(key interface{}) error {
47 fs.lock.Lock() 51 fs.lock.Lock()
48 defer fs.lock.Unlock() 52 defer fs.lock.Unlock()
...@@ -50,6 +54,7 @@ func (fs *FileSessionStore) Delete(key interface{}) error { ...@@ -50,6 +54,7 @@ func (fs *FileSessionStore) Delete(key interface{}) error {
50 return nil 54 return nil
51 } 55 }
52 56
57 // Clean all values in file session
53 func (fs *FileSessionStore) Flush() error { 58 func (fs *FileSessionStore) Flush() error {
54 fs.lock.Lock() 59 fs.lock.Lock()
55 defer fs.lock.Unlock() 60 defer fs.lock.Unlock()
...@@ -57,10 +62,12 @@ func (fs *FileSessionStore) Flush() error { ...@@ -57,10 +62,12 @@ func (fs *FileSessionStore) Flush() error {
57 return nil 62 return nil
58 } 63 }
59 64
65 // Get file session store id
60 func (fs *FileSessionStore) SessionID() string { 66 func (fs *FileSessionStore) SessionID() string {
61 return fs.sid 67 return fs.sid
62 } 68 }
63 69
70 // Write file session to local file with Gob string
64 func (fs *FileSessionStore) SessionRelease(w http.ResponseWriter) { 71 func (fs *FileSessionStore) SessionRelease(w http.ResponseWriter) {
65 defer fs.f.Close() 72 defer fs.f.Close()
66 b, err := encodeGob(fs.values) 73 b, err := encodeGob(fs.values)
...@@ -72,17 +79,23 @@ func (fs *FileSessionStore) SessionRelease(w http.ResponseWriter) { ...@@ -72,17 +79,23 @@ func (fs *FileSessionStore) SessionRelease(w http.ResponseWriter) {
72 fs.f.Write(b) 79 fs.f.Write(b)
73 } 80 }
74 81
82 // File session provider
75 type FileProvider struct { 83 type FileProvider struct {
76 maxlifetime int64 84 maxlifetime int64
77 savePath string 85 savePath string
78 } 86 }
79 87
88 // Init file session provider.
89 // savePath sets the session files path.
80 func (fp *FileProvider) SessionInit(maxlifetime int64, savePath string) error { 90 func (fp *FileProvider) SessionInit(maxlifetime int64, savePath string) error {
81 fp.maxlifetime = maxlifetime 91 fp.maxlifetime = maxlifetime
82 fp.savePath = savePath 92 fp.savePath = savePath
83 return nil 93 return nil
84 } 94 }
85 95
96 // Read file session by sid.
97 // if file is not exist, create it.
98 // the file path is generated from sid string.
86 func (fp *FileProvider) SessionRead(sid string) (SessionStore, error) { 99 func (fp *FileProvider) SessionRead(sid string) (SessionStore, error) {
87 err := os.MkdirAll(path.Join(fp.savePath, string(sid[0]), string(sid[1])), 0777) 100 err := os.MkdirAll(path.Join(fp.savePath, string(sid[0]), string(sid[1])), 0777)
88 if err != nil { 101 if err != nil {
...@@ -117,6 +130,8 @@ func (fp *FileProvider) SessionRead(sid string) (SessionStore, error) { ...@@ -117,6 +130,8 @@ func (fp *FileProvider) SessionRead(sid string) (SessionStore, error) {
117 return ss, nil 130 return ss, nil
118 } 131 }
119 132
133 // Check file session exist.
134 // it checkes the file named from sid exist or not.
120 func (fp *FileProvider) SessionExist(sid string) bool { 135 func (fp *FileProvider) SessionExist(sid string) bool {
121 _, err := os.Stat(path.Join(fp.savePath, string(sid[0]), string(sid[1]), sid)) 136 _, err := os.Stat(path.Join(fp.savePath, string(sid[0]), string(sid[1]), sid))
122 if err == nil { 137 if err == nil {
...@@ -126,16 +141,20 @@ func (fp *FileProvider) SessionExist(sid string) bool { ...@@ -126,16 +141,20 @@ func (fp *FileProvider) SessionExist(sid string) bool {
126 } 141 }
127 } 142 }
128 143
144 // Remove all files in this save path
129 func (fp *FileProvider) SessionDestroy(sid string) error { 145 func (fp *FileProvider) SessionDestroy(sid string) error {
130 os.Remove(path.Join(fp.savePath)) 146 os.Remove(path.Join(fp.savePath))
131 return nil 147 return nil
132 } 148 }
133 149
150 // Recycle files in save path
134 func (fp *FileProvider) SessionGC() { 151 func (fp *FileProvider) SessionGC() {
135 gcmaxlifetime = fp.maxlifetime 152 gcmaxlifetime = fp.maxlifetime
136 filepath.Walk(fp.savePath, gcpath) 153 filepath.Walk(fp.savePath, gcpath)
137 } 154 }
138 155
156 // Get active file session number.
157 // it walks save path to count files.
139 func (fp *FileProvider) SessionAll() int { 158 func (fp *FileProvider) SessionAll() int {
140 a := &activeSession{} 159 a := &activeSession{}
141 err := filepath.Walk(fp.savePath, func(path string, f os.FileInfo, err error) error { 160 err := filepath.Walk(fp.savePath, func(path string, f os.FileInfo, err error) error {
...@@ -148,6 +167,8 @@ func (fp *FileProvider) SessionAll() int { ...@@ -148,6 +167,8 @@ func (fp *FileProvider) SessionAll() int {
148 return a.total 167 return a.total
149 } 168 }
150 169
170 // Generate new sid for file session.
171 // it delete old file and create new file named from new sid.
151 func (fp *FileProvider) SessionRegenerate(oldsid, sid string) (SessionStore, error) { 172 func (fp *FileProvider) SessionRegenerate(oldsid, sid string) (SessionStore, error) {
152 err := os.MkdirAll(path.Join(fp.savePath, string(oldsid[0]), string(oldsid[1])), 0777) 173 err := os.MkdirAll(path.Join(fp.savePath, string(oldsid[0]), string(oldsid[1])), 0777)
153 if err != nil { 174 if err != nil {
...@@ -197,6 +218,7 @@ func (fp *FileProvider) SessionRegenerate(oldsid, sid string) (SessionStore, err ...@@ -197,6 +218,7 @@ func (fp *FileProvider) SessionRegenerate(oldsid, sid string) (SessionStore, err
197 return ss, nil 218 return ss, nil
198 } 219 }
199 220
221 // remove file in save path if expired
200 func gcpath(path string, info os.FileInfo, err error) error { 222 func gcpath(path string, info os.FileInfo, err error) error {
201 if err != nil { 223 if err != nil {
202 return err 224 return err
......
...@@ -14,6 +14,7 @@ import ( ...@@ -14,6 +14,7 @@ import (
14 "time" 14 "time"
15 ) 15 )
16 16
17 // SessionStore contains all data for one session process with specific id.
17 type SessionStore interface { 18 type SessionStore interface {
18 Set(key, value interface{}) error //set session value 19 Set(key, value interface{}) error //set session value
19 Get(key interface{}) interface{} //get session value 20 Get(key interface{}) interface{} //get session value
...@@ -23,6 +24,8 @@ type SessionStore interface { ...@@ -23,6 +24,8 @@ type SessionStore interface {
23 Flush() error //delete all data 24 Flush() error //delete all data
24 } 25 }
25 26
27 // Provider contains global session methods and saved SessionStores.
28 // it can operate a SessionStore by its id.
26 type Provider interface { 29 type Provider interface {
27 SessionInit(gclifetime int64, config string) error 30 SessionInit(gclifetime int64, config string) error
28 SessionRead(sid string) (SessionStore, error) 31 SessionRead(sid string) (SessionStore, error)
...@@ -61,16 +64,24 @@ type managerConfig struct { ...@@ -61,16 +64,24 @@ type managerConfig struct {
61 ProviderConfig string `json:"providerConfig"` 64 ProviderConfig string `json:"providerConfig"`
62 } 65 }
63 66
67 // Manager contains Provider and its configuration.
64 type Manager struct { 68 type Manager struct {
65 provider Provider 69 provider Provider
66 config *managerConfig 70 config *managerConfig
67 } 71 }
68 72
69 //options 73 // Create new Manager with provider name and json config string.
70 //1. is https default false 74 // provider name:
71 //2. hashfunc default sha1 75 // 1. cookie
72 //3. hashkey default beegosessionkey 76 // 2. file
73 //4. maxage default is none 77 // 3. memory
78 // 4. redis
79 // 5. mysql
80 // json config:
81 // 1. is https default false
82 // 2. hashfunc default sha1
83 // 3. hashkey default beegosessionkey
84 // 4. maxage default is none
74 func NewManager(provideName, config string) (*Manager, error) { 85 func NewManager(provideName, config string) (*Manager, error) {
75 provider, ok := provides[provideName] 86 provider, ok := provides[provideName]
76 if !ok { 87 if !ok {
...@@ -102,7 +113,8 @@ func NewManager(provideName, config string) (*Manager, error) { ...@@ -102,7 +113,8 @@ func NewManager(provideName, config string) (*Manager, error) {
102 }, nil 113 }, nil
103 } 114 }
104 115
105 //get Session 116 // Start session. generate or read the session id from http request.
117 // if session id exists, return SessionStore with this id.
106 func (manager *Manager) SessionStart(w http.ResponseWriter, r *http.Request) (session SessionStore) { 118 func (manager *Manager) SessionStart(w http.ResponseWriter, r *http.Request) (session SessionStore) {
107 cookie, err := r.Cookie(manager.config.CookieName) 119 cookie, err := r.Cookie(manager.config.CookieName)
108 if err != nil || cookie.Value == "" { 120 if err != nil || cookie.Value == "" {
...@@ -144,7 +156,7 @@ func (manager *Manager) SessionStart(w http.ResponseWriter, r *http.Request) (se ...@@ -144,7 +156,7 @@ func (manager *Manager) SessionStart(w http.ResponseWriter, r *http.Request) (se
144 return 156 return
145 } 157 }
146 158
147 //Destroy sessionid 159 // Destroy session by its id in http request cookie.
148 func (manager *Manager) SessionDestroy(w http.ResponseWriter, r *http.Request) { 160 func (manager *Manager) SessionDestroy(w http.ResponseWriter, r *http.Request) {
149 cookie, err := r.Cookie(manager.config.CookieName) 161 cookie, err := r.Cookie(manager.config.CookieName)
150 if err != nil || cookie.Value == "" { 162 if err != nil || cookie.Value == "" {
...@@ -161,16 +173,20 @@ func (manager *Manager) SessionDestroy(w http.ResponseWriter, r *http.Request) { ...@@ -161,16 +173,20 @@ func (manager *Manager) SessionDestroy(w http.ResponseWriter, r *http.Request) {
161 } 173 }
162 } 174 }
163 175
176 // Get SessionStore by its id.
164 func (manager *Manager) GetProvider(sid string) (sessions SessionStore, err error) { 177 func (manager *Manager) GetProvider(sid string) (sessions SessionStore, err error) {
165 sessions, err = manager.provider.SessionRead(sid) 178 sessions, err = manager.provider.SessionRead(sid)
166 return 179 return
167 } 180 }
168 181
182 // Start session gc process.
183 // it can do gc in times after gc lifetime.
169 func (manager *Manager) GC() { 184 func (manager *Manager) GC() {
170 manager.provider.SessionGC() 185 manager.provider.SessionGC()
171 time.AfterFunc(time.Duration(manager.config.Gclifetime)*time.Second, func() { manager.GC() }) 186 time.AfterFunc(time.Duration(manager.config.Gclifetime)*time.Second, func() { manager.GC() })
172 } 187 }
173 188
189 // Regenerate a session id for this SessionStore who's id is saving in http request.
174 func (manager *Manager) SessionRegenerateId(w http.ResponseWriter, r *http.Request) (session SessionStore) { 190 func (manager *Manager) SessionRegenerateId(w http.ResponseWriter, r *http.Request) (session SessionStore) {
175 sid := manager.sessionId(r) 191 sid := manager.sessionId(r)
176 cookie, err := r.Cookie(manager.config.CookieName) 192 cookie, err := r.Cookie(manager.config.CookieName)
...@@ -198,20 +214,23 @@ func (manager *Manager) SessionRegenerateId(w http.ResponseWriter, r *http.Reque ...@@ -198,20 +214,23 @@ func (manager *Manager) SessionRegenerateId(w http.ResponseWriter, r *http.Reque
198 return 214 return
199 } 215 }
200 216
217 // Get all active sessions count number.
201 func (manager *Manager) GetActiveSession() int { 218 func (manager *Manager) GetActiveSession() int {
202 return manager.provider.SessionAll() 219 return manager.provider.SessionAll()
203 } 220 }
204 221
222 // Set hash function for generating session id.
205 func (manager *Manager) SetHashFunc(hasfunc, hashkey string) { 223 func (manager *Manager) SetHashFunc(hasfunc, hashkey string) {
206 manager.config.SessionIDHashFunc = hasfunc 224 manager.config.SessionIDHashFunc = hasfunc
207 manager.config.SessionIDHashKey = hashkey 225 manager.config.SessionIDHashKey = hashkey
208 } 226 }
209 227
228 // Set cookie with https.
210 func (manager *Manager) SetSecure(secure bool) { 229 func (manager *Manager) SetSecure(secure bool) {
211 manager.config.Secure = secure 230 manager.config.Secure = secure
212 } 231 }
213 232
214 //remote_addr cruunixnano randdata 233 // generate session id with rand string, unix nano time, remote addr by hash function.
215 func (manager *Manager) sessionId(r *http.Request) (sid string) { 234 func (manager *Manager) sessionId(r *http.Request) (sid string) {
216 bs := make([]byte, 24) 235 bs := make([]byte, 24)
217 if _, err := io.ReadFull(rand.Reader, bs); err != nil { 236 if _, err := io.ReadFull(rand.Reader, bs); err != nil {
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!