fix #254
Showing
4 changed files
with
77 additions
and
39 deletions
| ... | @@ -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 { | ... | ... |
-
Please register or sign in to post a comment