a443a798 by astaxie

fix #254

1 parent 23d79b8b
...@@ -28,7 +28,6 @@ func (fs *FileSessionStore) Set(key, value interface{}) error { ...@@ -28,7 +28,6 @@ func (fs *FileSessionStore) Set(key, value interface{}) error {
28 fs.lock.Lock() 28 fs.lock.Lock()
29 defer fs.lock.Unlock() 29 defer fs.lock.Unlock()
30 fs.values[key] = value 30 fs.values[key] = value
31 fs.updatecontent()
32 return nil 31 return nil
33 } 32 }
34 33
...@@ -47,7 +46,6 @@ func (fs *FileSessionStore) Delete(key interface{}) error { ...@@ -47,7 +46,6 @@ func (fs *FileSessionStore) Delete(key interface{}) error {
47 fs.lock.Lock() 46 fs.lock.Lock()
48 defer fs.lock.Unlock() 47 defer fs.lock.Unlock()
49 delete(fs.values, key) 48 delete(fs.values, key)
50 fs.updatecontent()
51 return nil 49 return nil
52 } 50 }
53 51
...@@ -55,7 +53,6 @@ func (fs *FileSessionStore) Flush() error { ...@@ -55,7 +53,6 @@ func (fs *FileSessionStore) Flush() error {
55 fs.lock.Lock() 53 fs.lock.Lock()
56 defer fs.lock.Unlock() 54 defer fs.lock.Unlock()
57 fs.values = make(map[interface{}]interface{}) 55 fs.values = make(map[interface{}]interface{})
58 fs.updatecontent()
59 return nil 56 return nil
60 } 57 }
61 58
...@@ -64,10 +61,7 @@ func (fs *FileSessionStore) SessionID() string { ...@@ -64,10 +61,7 @@ func (fs *FileSessionStore) SessionID() string {
64 } 61 }
65 62
66 func (fs *FileSessionStore) SessionRelease() { 63 func (fs *FileSessionStore) SessionRelease() {
67 fs.f.Close() 64 defer fs.f.Close()
68 }
69
70 func (fs *FileSessionStore) updatecontent() {
71 b, err := encodeGob(fs.values) 65 b, err := encodeGob(fs.values)
72 if err != nil { 66 if err != nil {
73 return 67 return
......
...@@ -27,7 +27,6 @@ func (st *MysqlSessionStore) Set(key, value interface{}) error { ...@@ -27,7 +27,6 @@ func (st *MysqlSessionStore) Set(key, value interface{}) error {
27 st.lock.Lock() 27 st.lock.Lock()
28 defer st.lock.Unlock() 28 defer st.lock.Unlock()
29 st.values[key] = value 29 st.values[key] = value
30 st.updatemysql()
31 return nil 30 return nil
32 } 31 }
33 32
...@@ -46,7 +45,6 @@ func (st *MysqlSessionStore) Delete(key interface{}) error { ...@@ -46,7 +45,6 @@ func (st *MysqlSessionStore) Delete(key interface{}) error {
46 st.lock.Lock() 45 st.lock.Lock()
47 defer st.lock.Unlock() 46 defer st.lock.Unlock()
48 delete(st.values, key) 47 delete(st.values, key)
49 st.updatemysql()
50 return nil 48 return nil
51 } 49 }
52 50
...@@ -54,7 +52,6 @@ func (st *MysqlSessionStore) Flush() error { ...@@ -54,7 +52,6 @@ func (st *MysqlSessionStore) Flush() error {
54 st.lock.Lock() 52 st.lock.Lock()
55 defer st.lock.Unlock() 53 defer st.lock.Unlock()
56 st.values = make(map[interface{}]interface{}) 54 st.values = make(map[interface{}]interface{})
57 st.updatemysql()
58 return nil 55 return nil
59 } 56 }
60 57
...@@ -62,7 +59,8 @@ func (st *MysqlSessionStore) SessionID() string { ...@@ -62,7 +59,8 @@ func (st *MysqlSessionStore) SessionID() string {
62 return st.sid 59 return st.sid
63 } 60 }
64 61
65 func (st *MysqlSessionStore) updatemysql() { 62 func (st *MysqlSessionStore) SessionRelease() {
63 defer st.c.Close()
66 if len(st.values) > 0 { 64 if len(st.values) > 0 {
67 b, err := encodeGob(st.values) 65 b, err := encodeGob(st.values)
68 if err != nil { 66 if err != nil {
...@@ -72,10 +70,6 @@ func (st *MysqlSessionStore) updatemysql() { ...@@ -72,10 +70,6 @@ func (st *MysqlSessionStore) updatemysql() {
72 } 70 }
73 } 71 }
74 72
75 func (st *MysqlSessionStore) SessionRelease() {
76 st.c.Close()
77 }
78
79 type MysqlProvider struct { 73 type MysqlProvider struct {
80 maxlifetime int64 74 maxlifetime int64
81 savePath string 75 savePath string
......
...@@ -4,6 +4,7 @@ import ( ...@@ -4,6 +4,7 @@ import (
4 "github.com/garyburd/redigo/redis" 4 "github.com/garyburd/redigo/redis"
5 "strconv" 5 "strconv"
6 "strings" 6 "strings"
7 "sync"
7 ) 8 )
8 9
9 var redispder = &RedisProvider{} 10 var redispder = &RedisProvider{}
...@@ -15,31 +16,40 @@ var redisPool chan redis.Conn ...@@ -15,31 +16,40 @@ var redisPool chan redis.Conn
15 type RedisSessionStore struct { 16 type RedisSessionStore struct {
16 c redis.Conn 17 c redis.Conn
17 sid string 18 sid string
19 lock sync.RWMutex
20 values map[interface{}]interface{}
18 } 21 }
19 22
20 func (rs *RedisSessionStore) Set(key, value interface{}) error { 23 func (rs *RedisSessionStore) Set(key, value interface{}) error {
21 //_, err := rs.c.Do("HSET", rs.sid, key, value) 24 rs.lock.Lock()
22 _, err := rs.c.Do("HSET", rs.sid, key, value) 25 defer rs.lock.Unlock()
23 return err 26 rs.values[key] = value
27 return nil
24 } 28 }
25 29
26 func (rs *RedisSessionStore) Get(key interface{}) interface{} { 30 func (rs *RedisSessionStore) Get(key interface{}) interface{} {
27 reply, err := rs.c.Do("HGET", rs.sid, key) 31 rs.lock.RLock()
28 if err != nil { 32 defer rs.lock.RUnlock()
33 if v, ok := rs.values[key]; ok {
34 return v
35 } else {
29 return nil 36 return nil
30 } 37 }
31 return reply 38 return nil
32 } 39 }
33 40
34 func (rs *RedisSessionStore) Delete(key interface{}) error { 41 func (rs *RedisSessionStore) Delete(key interface{}) error {
35 //_, err := rs.c.Do("HDEL", rs.sid, key) 42 rs.lock.Lock()
36 _, err := rs.c.Do("HDEL", rs.sid, key) 43 defer rs.lock.Unlock()
37 return err 44 delete(rs.values, key)
45 return nil
38 } 46 }
39 47
40 func (rs *RedisSessionStore) Flush() error { 48 func (rs *RedisSessionStore) Flush() error {
41 _, err := rs.c.Do("DEL", rs.sid) 49 rs.lock.Lock()
42 return err 50 defer rs.lock.Unlock()
51 rs.values = make(map[interface{}]interface{})
52 return nil
43 } 53 }
44 54
45 func (rs *RedisSessionStore) SessionID() string { 55 func (rs *RedisSessionStore) SessionID() string {
...@@ -47,7 +57,23 @@ func (rs *RedisSessionStore) SessionID() string { ...@@ -47,7 +57,23 @@ func (rs *RedisSessionStore) SessionID() string {
47 } 57 }
48 58
49 func (rs *RedisSessionStore) SessionRelease() { 59 func (rs *RedisSessionStore) SessionRelease() {
50 rs.c.Close() 60 defer rs.c.Close()
61 keys, err := redis.Values(rs.c.Do("HKEYS", rs.sid))
62 if err == nil {
63 for _, key := range keys {
64 if val, ok := rs.values[key]; ok {
65 rs.c.Do("HSET", rs.sid, key, val)
66 rs.Delete(key)
67 } else {
68 rs.c.Do("HDEL", rs.sid, key)
69 }
70 }
71 }
72 if len(rs.values) > 0 {
73 for k, v := range rs.values {
74 rs.c.Do("HSET", rs.sid, k, v)
75 }
76 }
51 } 77 }
52 78
53 type RedisProvider struct { 79 type RedisProvider struct {
...@@ -103,7 +129,19 @@ func (rp *RedisProvider) SessionRead(sid string) (SessionStore, error) { ...@@ -103,7 +129,19 @@ func (rp *RedisProvider) SessionRead(sid string) (SessionStore, error) {
103 c.Do("HSET", sid, sid, rp.maxlifetime) 129 c.Do("HSET", sid, sid, rp.maxlifetime)
104 } 130 }
105 c.Do("EXPIRE", sid, rp.maxlifetime) 131 c.Do("EXPIRE", sid, rp.maxlifetime)
106 rs := &RedisSessionStore{c: c, sid: sid} 132 kvs, err := redis.Values(c.Do("HGETALL", sid))
133 vals := make(map[interface{}]interface{})
134 var key interface{}
135 if err == nil {
136 for k, v := range kvs {
137 if k%2 == 0 {
138 key = v
139 } else {
140 vals[key] = v
141 }
142 }
143 }
144 rs := &RedisSessionStore{c: c, sid: sid, values: vals}
107 return rs, nil 145 return rs, nil
108 } 146 }
109 147
...@@ -114,7 +152,19 @@ func (rp *RedisProvider) SessionRegenerate(oldsid, sid string) (SessionStore, er ...@@ -114,7 +152,19 @@ func (rp *RedisProvider) SessionRegenerate(oldsid, sid string) (SessionStore, er
114 } 152 }
115 c.Do("RENAME", oldsid, sid) 153 c.Do("RENAME", oldsid, sid)
116 c.Do("EXPIRE", sid, rp.maxlifetime) 154 c.Do("EXPIRE", sid, rp.maxlifetime)
117 rs := &RedisSessionStore{c: c, sid: sid} 155 kvs, err := redis.Values(c.Do("HGETALL", sid))
156 vals := make(map[interface{}]interface{})
157 var key interface{}
158 if err == nil {
159 for k, v := range kvs {
160 if k%2 == 0 {
161 key = v
162 } else {
163 vals[key] = v
164 }
165 }
166 }
167 rs := &RedisSessionStore{c: c, sid: sid, values: vals}
118 return rs, nil 168 return rs, nil
119 } 169 }
120 170
......
...@@ -18,7 +18,7 @@ type SessionStore interface { ...@@ -18,7 +18,7 @@ type SessionStore interface {
18 Get(key interface{}) interface{} //get session value 18 Get(key interface{}) interface{} //get session value
19 Delete(key interface{}) error //delete session value 19 Delete(key interface{}) error //delete session value
20 SessionID() string //back current sessionID 20 SessionID() string //back current sessionID
21 SessionRelease() // release the resource 21 SessionRelease() // release the resource & save data to provider
22 Flush() error //delete all data 22 Flush() error //delete all data
23 } 23 }
24 24
...@@ -129,17 +129,9 @@ func (manager *Manager) SessionStart(w http.ResponseWriter, r *http.Request) (se ...@@ -129,17 +129,9 @@ func (manager *Manager) SessionStart(w http.ResponseWriter, r *http.Request) (se
129 if manager.maxage >= 0 { 129 if manager.maxage >= 0 {
130 cookie.MaxAge = manager.maxage 130 cookie.MaxAge = manager.maxage
131 } 131 }
132 //cookie.Expires = time.Now().Add(time.Duration(manager.maxlifetime) * time.Second)
133 http.SetCookie(w, cookie) 132 http.SetCookie(w, cookie)
134 r.AddCookie(cookie) 133 r.AddCookie(cookie)
135 } else { 134 } else {
136 //cookie.Expires = time.Now().Add(time.Duration(manager.maxlifetime) * time.Second)
137 //cookie.HttpOnly = true
138 //cookie.Path = "/"
139 //if manager.maxage >= 0 {
140 // cookie.MaxAge = manager.maxage
141 // http.SetCookie(w, cookie)
142 //}
143 sid, _ := url.QueryUnescape(cookie.Value) 135 sid, _ := url.QueryUnescape(cookie.Value)
144 session, _ = manager.provider.SessionRead(sid) 136 session, _ = manager.provider.SessionRead(sid)
145 } 137 }
...@@ -200,8 +192,16 @@ func (manager *Manager) GetActiveSession() int { ...@@ -200,8 +192,16 @@ func (manager *Manager) GetActiveSession() int {
200 return manager.provider.SessionAll() 192 return manager.provider.SessionAll()
201 } 193 }
202 194
203 //remote_addr cruunixnano randdata 195 func (manager *Manager) SetHashFunc(hasfunc, hashkey string) {
196 manager.hashfunc = hasfunc
197 manager.hashkey = hashkey
198 }
204 199
200 func (manager *Manager) SetSecure(secure bool) {
201 manager.secure = secure
202 }
203
204 //remote_addr cruunixnano randdata
205 func (manager *Manager) sessionId(r *http.Request) (sid string) { 205 func (manager *Manager) sessionId(r *http.Request) (sid string) {
206 bs := make([]byte, 24) 206 bs := make([]byte, 24)
207 if _, err := io.ReadFull(rand.Reader, bs); err != nil { 207 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!