feat(session): support v1
support v1
This commit is contained in:
parent
3c6986a5c4
commit
17e916f4a0
@ -20,8 +20,10 @@
|
||||
//
|
||||
// Usage:
|
||||
// import(
|
||||
// _ "github.com/beego/beego/session/couchbase"
|
||||
// "github.com/beego/beego/session"
|
||||
//
|
||||
// _ "github.com/beego/beego/session/couchbase"
|
||||
// "github.com/beego/beego/session"
|
||||
//
|
||||
// )
|
||||
//
|
||||
// func init() {
|
||||
@ -113,6 +115,12 @@ func (cs *SessionStore) SessionRelease(w http.ResponseWriter) {
|
||||
cs.b.Set(cs.sid, int(cs.maxlifetime), bo)
|
||||
}
|
||||
|
||||
// SessionReleaseIfPresent is not supported now.
|
||||
// If we want to use couchbase, we may refactor the code to use couchbase collection.
|
||||
func (cs *SessionStore) SessionReleaseIfPresent(w http.ResponseWriter) {
|
||||
cs.SessionRelease(w)
|
||||
}
|
||||
|
||||
func (cp *Provider) getBucket() *couchbase.Bucket {
|
||||
c, err := couchbase.Connect(cp.savePath)
|
||||
if err != nil {
|
||||
|
||||
@ -75,6 +75,13 @@ func (ls *SessionStore) SessionRelease(w http.ResponseWriter) {
|
||||
c.Expire([]byte(ls.sid), ls.maxlifetime)
|
||||
}
|
||||
|
||||
// SessionReleaseIfPresent is not supported now, because ledis has no this feature like SETXX or atomic operation.
|
||||
// https://github.com/ledisdb/ledisdb/issues/251
|
||||
// https://github.com/ledisdb/ledisdb/issues/351
|
||||
func (ls *SessionStore) SessionReleaseIfPresent(w http.ResponseWriter) {
|
||||
ls.SessionRelease(w)
|
||||
}
|
||||
|
||||
// Provider ledis session provider
|
||||
type Provider struct {
|
||||
maxlifetime int64
|
||||
@ -141,8 +148,8 @@ func (lp *Provider) SessionExist(sid string) bool {
|
||||
func (lp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error) {
|
||||
count, _ := c.Exists([]byte(sid))
|
||||
if count == 0 {
|
||||
// oldsid doesn't exists, set the new sid directly
|
||||
// ignore error here, since if it return error
|
||||
// oldsid doesn't exist, set the new sid directly
|
||||
// ignore error here, since if it returns error
|
||||
// the existed value will be 0
|
||||
c.Set([]byte(sid), []byte(""))
|
||||
c.Expire([]byte(sid), lp.maxlifetime)
|
||||
@ -160,7 +167,7 @@ func (lp *Provider) SessionDestroy(sid string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SessionGC Impelment method, no used.
|
||||
// SessionGC Implement method, no used.
|
||||
func (lp *Provider) SessionGC() {
|
||||
}
|
||||
|
||||
|
||||
@ -20,8 +20,10 @@
|
||||
//
|
||||
// Usage:
|
||||
// import(
|
||||
// _ "github.com/beego/beego/session/memcache"
|
||||
// "github.com/beego/beego/session"
|
||||
//
|
||||
// _ "github.com/beego/beego/session/memcache"
|
||||
// "github.com/beego/beego/session"
|
||||
//
|
||||
// )
|
||||
//
|
||||
// func init() {
|
||||
@ -94,12 +96,28 @@ func (rs *SessionStore) SessionID() string {
|
||||
|
||||
// SessionRelease save session values to memcache
|
||||
func (rs *SessionStore) SessionRelease(w http.ResponseWriter) {
|
||||
b, err := session.EncodeGob(rs.values)
|
||||
rs.releaseSession(w, false)
|
||||
}
|
||||
|
||||
// SessionReleaseIfPresent save session values to memcache when key is present
|
||||
func (rs *SessionStore) SessionReleaseIfPresent(w http.ResponseWriter) {
|
||||
rs.releaseSession(w, true)
|
||||
}
|
||||
|
||||
func (rs *SessionStore) releaseSession(_ http.ResponseWriter, requirePresent bool) {
|
||||
rs.lock.RLock()
|
||||
values := rs.values
|
||||
rs.lock.RUnlock()
|
||||
b, err := session.EncodeGob(values)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
item := memcache.Item{Key: rs.sid, Value: b, Expiration: int32(rs.maxlifetime)}
|
||||
client.Set(&item)
|
||||
if requirePresent {
|
||||
client.Replace(&item)
|
||||
} else {
|
||||
client.Set(&item)
|
||||
}
|
||||
}
|
||||
|
||||
// MemProvider memcache session provider
|
||||
@ -170,8 +188,8 @@ func (rp *MemProvider) SessionRegenerate(oldsid, sid string) (session.Store, err
|
||||
}
|
||||
var contain []byte
|
||||
if item, err := client.Get(sid); err != nil || len(item.Value) == 0 {
|
||||
// oldsid doesn't exists, set the new sid directly
|
||||
// ignore error here, since if it return error
|
||||
// oldsid doesn't exist, set the new sid directly
|
||||
// ignore error here, since if it returns error
|
||||
// the existed value will be 0
|
||||
item.Key = sid
|
||||
item.Value = []byte("")
|
||||
|
||||
@ -19,6 +19,7 @@
|
||||
// go install github.com/go-sql-driver/mysql
|
||||
//
|
||||
// mysql session support need create table as sql:
|
||||
//
|
||||
// CREATE TABLE `session` (
|
||||
// `session_key` char(64) NOT NULL,
|
||||
// `session_data` blob,
|
||||
@ -28,8 +29,10 @@
|
||||
//
|
||||
// Usage:
|
||||
// import(
|
||||
// _ "github.com/beego/beego/session/mysql"
|
||||
// "github.com/beego/beego/session"
|
||||
//
|
||||
// _ "github.com/beego/beego/session/mysql"
|
||||
// "github.com/beego/beego/session"
|
||||
//
|
||||
// )
|
||||
//
|
||||
// func init() {
|
||||
@ -117,6 +120,11 @@ func (st *SessionStore) SessionRelease(w http.ResponseWriter) {
|
||||
b, time.Now().Unix(), st.sid)
|
||||
}
|
||||
|
||||
// SessionReleaseIfPresent save mysql session values to database.
|
||||
func (st *SessionStore) SessionReleaseIfPresent(w http.ResponseWriter) {
|
||||
st.SessionRelease(w)
|
||||
}
|
||||
|
||||
// Provider mysql session provider
|
||||
type Provider struct {
|
||||
maxlifetime int64
|
||||
|
||||
@ -18,7 +18,6 @@
|
||||
//
|
||||
// go install github.com/lib/pq
|
||||
//
|
||||
//
|
||||
// needs this table in your database:
|
||||
//
|
||||
// CREATE TABLE session (
|
||||
@ -35,11 +34,12 @@
|
||||
// SessionSavePath = "user=a password=b dbname=c sslmode=disable"
|
||||
// SessionName = session
|
||||
//
|
||||
//
|
||||
// Usage:
|
||||
// import(
|
||||
// _ "github.com/beego/beego/session/postgresql"
|
||||
// "github.com/beego/beego/session"
|
||||
//
|
||||
// _ "github.com/beego/beego/session/postgresql"
|
||||
// "github.com/beego/beego/session"
|
||||
//
|
||||
// )
|
||||
//
|
||||
// func init() {
|
||||
@ -113,15 +113,22 @@ func (st *SessionStore) SessionID() string {
|
||||
|
||||
// SessionRelease save postgresql session values to database.
|
||||
// must call this method to save values to database.
|
||||
func (st *SessionStore) SessionRelease(w http.ResponseWriter) {
|
||||
func (st *SessionStore) SessionRelease(_ http.ResponseWriter) {
|
||||
defer st.c.Close()
|
||||
b, err := session.EncodeGob(st.values)
|
||||
st.lock.RLock()
|
||||
values := st.values
|
||||
st.lock.RUnlock()
|
||||
b, err := session.EncodeGob(values)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
st.c.Exec("UPDATE session set session_data=$1, session_expiry=$2 where session_key=$3",
|
||||
b, time.Now().Format(time.RFC3339), st.sid)
|
||||
}
|
||||
|
||||
// SessionReleaseIfPresent save postgresql session values to database when key is present
|
||||
func (st *SessionStore) SessionReleaseIfPresent(w http.ResponseWriter) {
|
||||
st.SessionRelease(w)
|
||||
}
|
||||
|
||||
// Provider postgresql session provider
|
||||
|
||||
@ -20,14 +20,16 @@
|
||||
//
|
||||
// Usage:
|
||||
// import(
|
||||
// _ "github.com/beego/beego/session/redis"
|
||||
// "github.com/beego/beego/session"
|
||||
//
|
||||
// _ "github.com/beego/beego/session/redis"
|
||||
// "github.com/beego/beego/session"
|
||||
//
|
||||
// )
|
||||
//
|
||||
// func init() {
|
||||
// globalSessions, _ = session.NewManager("redis", ``{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"127.0.0.1:7070"}``)
|
||||
// go globalSessions.GC()
|
||||
// }
|
||||
// func init() {
|
||||
// globalSessions, _ = session.NewManager("redis", ``{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"127.0.0.1:7070"}``)
|
||||
// go globalSessions.GC()
|
||||
// }
|
||||
//
|
||||
// more docs: http://beego.me/docs/module/session.md
|
||||
package redis
|
||||
@ -99,13 +101,28 @@ func (rs *SessionStore) SessionID() string {
|
||||
|
||||
// SessionRelease save session values to redis
|
||||
func (rs *SessionStore) SessionRelease(w http.ResponseWriter) {
|
||||
b, err := session.EncodeGob(rs.values)
|
||||
rs.releaseSession(w, false)
|
||||
}
|
||||
|
||||
// SessionReleaseIfPresent save session values to redis when key is present
|
||||
func (rs *SessionStore) SessionReleaseIfPresent(w http.ResponseWriter) {
|
||||
rs.releaseSession(w, true)
|
||||
}
|
||||
|
||||
func (rs *SessionStore) releaseSession(_ http.ResponseWriter, requirePresent bool) {
|
||||
rs.lock.RLock()
|
||||
values := rs.values
|
||||
rs.lock.RUnlock()
|
||||
b, err := session.EncodeGob(values)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
c := rs.p.Get()
|
||||
defer c.Close()
|
||||
c.Do("SETEX", rs.sid, rs.maxlifetime, string(b))
|
||||
if requirePresent {
|
||||
c.Do("SETXX", rs.sid, string(b), time.Duration(rs.maxlifetime)*time.Second, "XX")
|
||||
} else {
|
||||
c.Do("SETEX", rs.sid, string(b), time.Duration(rs.maxlifetime)*time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
// Provider redis session provider
|
||||
@ -227,8 +244,8 @@ func (rp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error)
|
||||
defer c.Close()
|
||||
|
||||
if existed, _ := redis.Int(c.Do("EXISTS", oldsid)); existed == 0 {
|
||||
// oldsid doesn't exists, set the new sid directly
|
||||
// ignore error here, since if it return error
|
||||
// oldsid doesn't exist, set the new sid directly
|
||||
// ignore error here, since if it returns error
|
||||
// the existed value will be 0
|
||||
c.Do("SET", sid, "", "EX", rp.maxlifetime)
|
||||
} else {
|
||||
|
||||
148
session/redis/session_redis_test.go
Normal file
148
session/redis/session_redis_test.go
Normal file
@ -0,0 +1,148 @@
|
||||
package redis
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/beego/beego/session"
|
||||
)
|
||||
|
||||
func TestRedis(t *testing.T) {
|
||||
globalSession, err := setupSessionManager(t)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
go globalSession.GC()
|
||||
|
||||
r, _ := http.NewRequest("GET", "/", nil)
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
sess, err := globalSession.SessionStart(w, r)
|
||||
if err != nil {
|
||||
t.Fatal("session start failed:", err)
|
||||
}
|
||||
defer sess.SessionRelease(w)
|
||||
|
||||
// SET AND GET
|
||||
err = sess.Set("username", "astaxie")
|
||||
if err != nil {
|
||||
t.Fatal("set username failed:", err)
|
||||
}
|
||||
username := sess.Get("username")
|
||||
if username != "astaxie" {
|
||||
t.Fatal("get username failed")
|
||||
}
|
||||
|
||||
// DELETE
|
||||
err = sess.Delete("username")
|
||||
if err != nil {
|
||||
t.Fatal("delete username failed:", err)
|
||||
}
|
||||
username = sess.Get("username")
|
||||
if username != nil {
|
||||
t.Fatal("delete username failed")
|
||||
}
|
||||
|
||||
// FLUSH
|
||||
err = sess.Set("username", "astaxie")
|
||||
if err != nil {
|
||||
t.Fatal("set failed:", err)
|
||||
}
|
||||
err = sess.Set("password", "1qaz2wsx")
|
||||
if err != nil {
|
||||
t.Fatal("set failed:", err)
|
||||
}
|
||||
username = sess.Get("username")
|
||||
if username != "astaxie" {
|
||||
t.Fatal("get username failed")
|
||||
}
|
||||
password := sess.Get("password")
|
||||
if password != "1qaz2wsx" {
|
||||
t.Fatal("get password failed")
|
||||
}
|
||||
err = sess.Flush()
|
||||
if err != nil {
|
||||
t.Fatal("flush failed:", err)
|
||||
}
|
||||
username = sess.Get("username")
|
||||
if username != nil {
|
||||
t.Fatal("flush failed")
|
||||
}
|
||||
password = sess.Get("password")
|
||||
if password != nil {
|
||||
t.Fatal("flush failed")
|
||||
}
|
||||
|
||||
sess.SessionRelease(w)
|
||||
}
|
||||
|
||||
func TestProvider_SessionInit(t *testing.T) {
|
||||
savePath := `
|
||||
{ "save_path": "my save path", "idle_timeout": "3s"}
|
||||
`
|
||||
cp := &Provider{}
|
||||
cp.SessionInit(12, savePath)
|
||||
assert.Equal(t, int64(12), cp.maxlifetime)
|
||||
}
|
||||
|
||||
func TestStoreSessionReleaseIfPresentAndSessionDestroy(t *testing.T) {
|
||||
globalSessions, err := setupSessionManager(t)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// todo test if e==nil
|
||||
go globalSessions.GC()
|
||||
|
||||
r, _ := http.NewRequest("GET", "/", nil)
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
sess, err := globalSessions.SessionStart(w, r)
|
||||
if err != nil {
|
||||
t.Fatal("session start failed:", err)
|
||||
}
|
||||
|
||||
if err := globalSessions.GetProvider().SessionDestroy(sess.SessionID()); err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
sess.SessionReleaseIfPresent(httptest.NewRecorder())
|
||||
}()
|
||||
wg.Wait()
|
||||
|
||||
if globalSessions.GetProvider().SessionExist(sess.SessionID()) {
|
||||
t.Fatalf("session %s should exist", sess.SessionID())
|
||||
}
|
||||
}
|
||||
|
||||
func setupSessionManager(t *testing.T) (*session.Manager, error) {
|
||||
redisAddr := os.Getenv("REDIS_ADDR")
|
||||
if redisAddr == "" {
|
||||
redisAddr = "127.0.0.1:6379"
|
||||
}
|
||||
redisConfig := fmt.Sprintf("%s,100,,0,30", redisAddr)
|
||||
sessionConfig := &session.ManagerConfig{}
|
||||
sessionConfig.CookieName = "gosessionid"
|
||||
sessionConfig.EnableSetCookie = true
|
||||
sessionConfig.Gclifetime = 3600
|
||||
sessionConfig.Maxlifetime = 3600
|
||||
sessionConfig.Secure = false
|
||||
sessionConfig.CookieLifeTime = 3600
|
||||
sessionConfig.ProviderConfig = redisConfig
|
||||
globalSessions, err := session.NewManager("redis", sessionConfig)
|
||||
if err != nil {
|
||||
t.Log("could not create manager: ", err)
|
||||
return nil, err
|
||||
}
|
||||
return globalSessions, nil
|
||||
}
|
||||
@ -20,8 +20,10 @@
|
||||
//
|
||||
// Usage:
|
||||
// import(
|
||||
// _ "github.com/beego/beego/session/redis_cluster"
|
||||
// "github.com/beego/beego/session"
|
||||
//
|
||||
// _ "github.com/beego/beego/session/redis_cluster"
|
||||
// "github.com/beego/beego/session"
|
||||
//
|
||||
// )
|
||||
//
|
||||
// func init() {
|
||||
@ -39,8 +41,9 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/beego/beego/session"
|
||||
rediss "github.com/go-redis/redis"
|
||||
|
||||
"github.com/beego/beego/session"
|
||||
)
|
||||
|
||||
var redispder = &Provider{}
|
||||
@ -98,12 +101,28 @@ func (rs *SessionStore) SessionID() string {
|
||||
|
||||
// SessionRelease save session values to redis_cluster
|
||||
func (rs *SessionStore) SessionRelease(w http.ResponseWriter) {
|
||||
b, err := session.EncodeGob(rs.values)
|
||||
rs.releaseSession(w, false)
|
||||
}
|
||||
|
||||
// SessionReleaseIfPresent save session values to redis_cluster when key is present
|
||||
func (rs *SessionStore) SessionReleaseIfPresent(w http.ResponseWriter) {
|
||||
rs.releaseSession(w, true)
|
||||
}
|
||||
|
||||
func (rs *SessionStore) releaseSession(_ http.ResponseWriter, requirePresent bool) {
|
||||
rs.lock.RLock()
|
||||
values := rs.values
|
||||
rs.lock.RUnlock()
|
||||
b, err := session.EncodeGob(values)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
c := rs.p
|
||||
c.Set(rs.sid, string(b), time.Duration(rs.maxlifetime)*time.Second)
|
||||
if requirePresent {
|
||||
c.SetXX(rs.sid, string(b), time.Duration(rs.maxlifetime)*time.Second)
|
||||
} else {
|
||||
c.Set(rs.sid, string(b), time.Duration(rs.maxlifetime)*time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
// Provider redis_cluster session provider
|
||||
@ -190,8 +209,8 @@ func (rp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error)
|
||||
c := rp.poollist
|
||||
|
||||
if existed, err := c.Exists(oldsid).Result(); err != nil || existed == 0 {
|
||||
// oldsid doesn't exists, set the new sid directly
|
||||
// ignore error here, since if it return error
|
||||
// oldsid doesn't exist, set the new sid directly
|
||||
// ignore error here, since if it returns error
|
||||
// the existed value will be 0
|
||||
c.Set(sid, "", time.Duration(rp.maxlifetime)*time.Second)
|
||||
} else {
|
||||
|
||||
@ -20,8 +20,10 @@
|
||||
//
|
||||
// Usage:
|
||||
// import(
|
||||
// _ "github.com/beego/beego/session/redis_sentinel"
|
||||
// "github.com/beego/beego/session"
|
||||
//
|
||||
// _ "github.com/beego/beego/session/redis_sentinel"
|
||||
// "github.com/beego/beego/session"
|
||||
//
|
||||
// )
|
||||
//
|
||||
// func init() {
|
||||
@ -39,8 +41,9 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/beego/beego/session"
|
||||
"github.com/go-redis/redis"
|
||||
|
||||
"github.com/beego/beego/session"
|
||||
)
|
||||
|
||||
var redispder = &Provider{}
|
||||
@ -98,12 +101,28 @@ func (rs *SessionStore) SessionID() string {
|
||||
|
||||
// SessionRelease save session values to redis_sentinel
|
||||
func (rs *SessionStore) SessionRelease(w http.ResponseWriter) {
|
||||
b, err := session.EncodeGob(rs.values)
|
||||
rs.releaseSession(w, false)
|
||||
}
|
||||
|
||||
// SessionReleaseIfPresent save session values to redis_sentinel when key is present
|
||||
func (rs *SessionStore) SessionReleaseIfPresent(w http.ResponseWriter) {
|
||||
rs.releaseSession(w, true)
|
||||
}
|
||||
|
||||
func (rs *SessionStore) releaseSession(_ http.ResponseWriter, requirePresent bool) {
|
||||
rs.lock.RLock()
|
||||
values := rs.values
|
||||
rs.lock.RUnlock()
|
||||
b, err := session.EncodeGob(values)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
c := rs.p
|
||||
c.Set(rs.sid, string(b), time.Duration(rs.maxlifetime)*time.Second)
|
||||
if requirePresent {
|
||||
c.SetXX(rs.sid, string(b), time.Duration(rs.maxlifetime)*time.Second)
|
||||
} else {
|
||||
c.Set(rs.sid, string(b), time.Duration(rs.maxlifetime)*time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
// Provider redis_sentinel session provider
|
||||
@ -203,8 +222,8 @@ func (rp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error)
|
||||
c := rp.poollist
|
||||
|
||||
if existed, err := c.Exists(oldsid).Result(); err != nil || existed == 0 {
|
||||
// oldsid doesn't exists, set the new sid directly
|
||||
// ignore error here, since if it return error
|
||||
// oldsid doesn't exist, set the new sid directly
|
||||
// ignore error here, since if it returns error
|
||||
// the existed value will be 0
|
||||
c.Set(sid, "", time.Duration(rp.maxlifetime)*time.Second)
|
||||
} else {
|
||||
|
||||
@ -88,6 +88,12 @@ func (st *CookieSessionStore) SessionRelease(w http.ResponseWriter) {
|
||||
}
|
||||
}
|
||||
|
||||
// SessionReleaseIfPresent Write cookie session to http response cookie when it is present
|
||||
// This is a no-op for cookie sessions, because they are always present.
|
||||
func (st *CookieSessionStore) SessionReleaseIfPresent(w http.ResponseWriter) {
|
||||
st.SessionRelease(w)
|
||||
}
|
||||
|
||||
type cookieConfig struct {
|
||||
SecurityKey string `json:"securityKey"`
|
||||
BlockKey string `json:"blockKey"`
|
||||
@ -107,11 +113,12 @@ type CookieProvider struct {
|
||||
// SessionInit Init cookie session provider with max lifetime and config json.
|
||||
// maxlifetime is ignored.
|
||||
// json config:
|
||||
// securityKey - hash string
|
||||
// blockKey - gob encode hash string. it's saved as aes crypto.
|
||||
// securityName - recognized name in encoded cookie string
|
||||
// cookieName - cookie name
|
||||
// maxage - cookie max life time.
|
||||
//
|
||||
// securityKey - hash string
|
||||
// blockKey - gob encode hash string. it's saved as aes crypto.
|
||||
// securityName - recognized name in encoded cookie string
|
||||
// cookieName - cookie name
|
||||
// maxage - cookie max life time.
|
||||
func (pder *CookieProvider) SessionInit(maxlifetime int64, config string) error {
|
||||
pder.config = &cookieConfig{}
|
||||
err := json.Unmarshal([]byte(config), pder.config)
|
||||
|
||||
@ -80,6 +80,15 @@ func (fs *FileSessionStore) SessionID() string {
|
||||
|
||||
// SessionRelease Write file session to local file with Gob string
|
||||
func (fs *FileSessionStore) SessionRelease(w http.ResponseWriter) {
|
||||
fs.releaseSession(w, true)
|
||||
}
|
||||
|
||||
// SessionReleaseIfPresent Write file session to local file with Gob string when session exists
|
||||
func (fs *FileSessionStore) SessionReleaseIfPresent(w http.ResponseWriter) {
|
||||
fs.releaseSession(w, false)
|
||||
}
|
||||
|
||||
func (fs *FileSessionStore) releaseSession(_ http.ResponseWriter, createIfNotExist bool) {
|
||||
filepder.lock.Lock()
|
||||
defer filepder.lock.Unlock()
|
||||
b, err := EncodeGob(fs.values)
|
||||
@ -87,16 +96,16 @@ func (fs *FileSessionStore) SessionRelease(w http.ResponseWriter) {
|
||||
SLogger.Println(err)
|
||||
return
|
||||
}
|
||||
_, err = os.Stat(path.Join(filepder.savePath, string(fs.sid[0]), string(fs.sid[1]), fs.sid))
|
||||
_, err = os.Stat(filepath.Join(filepder.savePath, string(fs.sid[0]), string(fs.sid[1]), fs.sid))
|
||||
var f *os.File
|
||||
if err == nil {
|
||||
f, err = os.OpenFile(path.Join(filepder.savePath, string(fs.sid[0]), string(fs.sid[1]), fs.sid), os.O_RDWR, 0777)
|
||||
f, err = os.OpenFile(filepath.Join(filepder.savePath, string(fs.sid[0]), string(fs.sid[1]), fs.sid), os.O_RDWR, 0o777)
|
||||
if err != nil {
|
||||
SLogger.Println(err)
|
||||
return
|
||||
}
|
||||
} else if os.IsNotExist(err) {
|
||||
f, err = os.Create(path.Join(filepder.savePath, string(fs.sid[0]), string(fs.sid[1]), fs.sid))
|
||||
} else if os.IsNotExist(err) && createIfNotExist {
|
||||
f, err = os.Create(filepath.Join(filepder.savePath, string(fs.sid[0]), string(fs.sid[1]), fs.sid))
|
||||
if err != nil {
|
||||
SLogger.Println(err)
|
||||
return
|
||||
@ -221,7 +230,7 @@ func (fp *FileProvider) SessionAll() int {
|
||||
}
|
||||
|
||||
// SessionRegenerate Generate new sid for file session.
|
||||
// it delete old file and create new file named from new sid.
|
||||
// it deletes old file and create new file named from new sid.
|
||||
func (fp *FileProvider) SessionRegenerate(oldsid, sid string) (Store, error) {
|
||||
filepder.lock.Lock()
|
||||
defer filepder.lock.Unlock()
|
||||
|
||||
@ -75,6 +75,10 @@ func (st *MemSessionStore) SessionID() string {
|
||||
func (st *MemSessionStore) SessionRelease(w http.ResponseWriter) {
|
||||
}
|
||||
|
||||
// SessionReleaseIfPresent Implement method, no used.
|
||||
func (*MemSessionStore) SessionReleaseIfPresent(_ http.ResponseWriter) {
|
||||
}
|
||||
|
||||
// MemProvider Implement the provider interface
|
||||
type MemProvider struct {
|
||||
lock sync.RWMutex // locker
|
||||
|
||||
@ -16,13 +16,15 @@
|
||||
//
|
||||
// Usage:
|
||||
// import(
|
||||
// "github.com/beego/beego/session"
|
||||
//
|
||||
// "github.com/beego/beego/session"
|
||||
//
|
||||
// )
|
||||
//
|
||||
// func init() {
|
||||
// globalSessions, _ = session.NewManager("memory", `{"cookieName":"gosessionid", "enableSetCookie,omitempty": true, "gclifetime":3600, "maxLifetime": 3600, "secure": false, "cookieLifeTime": 3600, "providerConfig": ""}`)
|
||||
// go globalSessions.GC()
|
||||
// }
|
||||
// func init() {
|
||||
// globalSessions, _ = session.NewManager("memory", `{"cookieName":"gosessionid", "enableSetCookie,omitempty": true, "gclifetime":3600, "maxLifetime": 3600, "secure": false, "cookieLifeTime": 3600, "providerConfig": ""}`)
|
||||
// go globalSessions.GC()
|
||||
// }
|
||||
//
|
||||
// more docs: http://beego.me/docs/module/session.md
|
||||
package session
|
||||
@ -43,12 +45,13 @@ import (
|
||||
|
||||
// Store contains all data for one session process with specific id.
|
||||
type Store interface {
|
||||
Set(key, value interface{}) error //set session value
|
||||
Get(key interface{}) interface{} //get session value
|
||||
Delete(key interface{}) error //delete session value
|
||||
SessionID() string //back current sessionID
|
||||
SessionRelease(w http.ResponseWriter) // release the resource & save data to provider & return the data
|
||||
Flush() error //delete all data
|
||||
Set(key, value interface{}) error // Set set session value
|
||||
Get(key interface{}) interface{} // Get get session value
|
||||
Delete(key interface{}) error // Delete delete session value
|
||||
SessionID() string // SessionID return current sessionID
|
||||
SessionReleaseIfPresent(w http.ResponseWriter) // SessionReleaseIfPresent release the resource & save data to provider & return the data when the session is present, not all implementation support this feature, you need to check if the specific implementation if support this feature.
|
||||
SessionRelease(w http.ResponseWriter) // SessionRelease release the resource & save data to provider & return the data
|
||||
Flush() error // Flush delete all data
|
||||
}
|
||||
|
||||
// Provider contains global session methods and saved SessionStores.
|
||||
@ -81,7 +84,7 @@ func Register(name string, provide Provider) {
|
||||
provides[name] = provide
|
||||
}
|
||||
|
||||
//GetProvider
|
||||
// GetProvider
|
||||
func GetProvider(name string) (Provider, error) {
|
||||
provider, ok := provides[name]
|
||||
if !ok {
|
||||
|
||||
@ -7,8 +7,9 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/beego/beego/session"
|
||||
"github.com/ssdb/gossdb/ssdb"
|
||||
|
||||
"github.com/beego/beego/session"
|
||||
)
|
||||
|
||||
var ssdbProvider = &Provider{}
|
||||
@ -67,7 +68,7 @@ func (p *Provider) SessionRead(sid string) (session.Store, error) {
|
||||
return rs, nil
|
||||
}
|
||||
|
||||
// SessionExist judged whether sid is exist in session
|
||||
// SessionExist judged whether sid is existed in session
|
||||
func (p *Provider) SessionExist(sid string) bool {
|
||||
if p.client == nil {
|
||||
if err := p.connectInit(); err != nil {
|
||||
@ -194,6 +195,12 @@ func (s *SessionStore) SessionRelease(w http.ResponseWriter) {
|
||||
s.client.Do("setx", s.sid, string(b), s.maxLifetime)
|
||||
}
|
||||
|
||||
// SessionReleaseIfPresent is not supported now
|
||||
// Because ssdb does not support lua script or SETXX command
|
||||
func (s *SessionStore) SessionReleaseIfPresent(w http.ResponseWriter) {
|
||||
s.SessionRelease(w)
|
||||
}
|
||||
|
||||
func init() {
|
||||
session.Register("ssdb", ssdbProvider)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user