bugfix: protect field access with lock to avoid possible data race (#5211)
This commit is contained in:
@@ -20,15 +20,16 @@
|
||||
//
|
||||
// Usage:
|
||||
// import(
|
||||
// _ "github.com/beego/beego/v2/server/web/session/couchbase"
|
||||
// "github.com/beego/beego/v2/server/web/session"
|
||||
//
|
||||
// _ "github.com/beego/beego/v2/server/web/session/couchbase"
|
||||
// "github.com/beego/beego/v2/server/web/session"
|
||||
//
|
||||
// )
|
||||
//
|
||||
// func init() {
|
||||
// globalSessions, _ = session.NewManager("couchbase", ``{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"http://host:port/, Pool, Bucket"}``)
|
||||
// go globalSessions.GC()
|
||||
// }
|
||||
//
|
||||
package couchbase
|
||||
|
||||
import (
|
||||
@@ -105,8 +106,10 @@ func (cs *SessionStore) SessionID(context.Context) string {
|
||||
// SessionRelease Write couchbase session with Gob string
|
||||
func (cs *SessionStore) SessionRelease(ctx context.Context, w http.ResponseWriter) {
|
||||
defer cs.b.Close()
|
||||
|
||||
bo, err := session.EncodeGob(cs.values)
|
||||
cs.lock.RLock()
|
||||
values := cs.values
|
||||
cs.lock.RUnlock()
|
||||
bo, err := session.EncodeGob(values)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -69,7 +69,10 @@ func (ls *SessionStore) SessionID(context.Context) string {
|
||||
|
||||
// SessionRelease save session values to ledis
|
||||
func (ls *SessionStore) SessionRelease(ctx context.Context, w http.ResponseWriter) {
|
||||
b, err := session.EncodeGob(ls.values)
|
||||
ls.lock.RLock()
|
||||
values := ls.values
|
||||
ls.lock.RUnlock()
|
||||
b, err := session.EncodeGob(values)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -20,15 +20,16 @@
|
||||
//
|
||||
// Usage:
|
||||
// import(
|
||||
// _ "github.com/beego/beego/v2/server/web/session/memcache"
|
||||
// "github.com/beego/beego/v2/server/web/session"
|
||||
//
|
||||
// _ "github.com/beego/beego/v2/server/web/session/memcache"
|
||||
// "github.com/beego/beego/v2/server/web/session"
|
||||
//
|
||||
// )
|
||||
//
|
||||
// func init() {
|
||||
// globalSessions, _ = session.NewManager("memcache", ``{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"127.0.0.1:11211"}``)
|
||||
// go globalSessions.GC()
|
||||
// }
|
||||
//
|
||||
package memcache
|
||||
|
||||
import (
|
||||
@@ -96,7 +97,10 @@ func (rs *SessionStore) SessionID(context.Context) string {
|
||||
|
||||
// SessionRelease save session values to memcache
|
||||
func (rs *SessionStore) SessionRelease(ctx context.Context, w http.ResponseWriter) {
|
||||
b, err := session.EncodeGob(rs.values)
|
||||
rs.lock.RLock()
|
||||
values := rs.values
|
||||
rs.lock.RUnlock()
|
||||
b, err := session.EncodeGob(values)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -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,15 +29,16 @@
|
||||
//
|
||||
// Usage:
|
||||
// import(
|
||||
// _ "github.com/beego/beego/v2/server/web/session/mysql"
|
||||
// "github.com/beego/beego/v2/server/web/session"
|
||||
//
|
||||
// _ "github.com/beego/beego/v2/server/web/session/mysql"
|
||||
// "github.com/beego/beego/v2/server/web/session"
|
||||
//
|
||||
// )
|
||||
//
|
||||
// func init() {
|
||||
// globalSessions, _ = session.NewManager("mysql", ``{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"[username[:password]@][protocol[(address)]]/dbname[?param1=value1&...¶mN=valueN]"}``)
|
||||
// go globalSessions.GC()
|
||||
// }
|
||||
//
|
||||
package mysql
|
||||
|
||||
import (
|
||||
@@ -109,7 +111,10 @@ func (st *SessionStore) SessionID(context.Context) string {
|
||||
// must call this method to save values to database.
|
||||
func (st *SessionStore) SessionRelease(ctx context.Context, w 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
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
//
|
||||
// go install github.com/lib/pq
|
||||
//
|
||||
//
|
||||
// needs this table in your database:
|
||||
//
|
||||
// CREATE TABLE session (
|
||||
@@ -35,18 +34,18 @@
|
||||
// SessionSavePath = "user=a password=b dbname=c sslmode=disable"
|
||||
// SessionName = session
|
||||
//
|
||||
//
|
||||
// Usage:
|
||||
// import(
|
||||
// _ "github.com/beego/beego/v2/server/web/session/postgresql"
|
||||
// "github.com/beego/beego/v2/server/web/session"
|
||||
//
|
||||
// _ "github.com/beego/beego/v2/server/web/session/postgresql"
|
||||
// "github.com/beego/beego/v2/server/web/session"
|
||||
//
|
||||
// )
|
||||
//
|
||||
// func init() {
|
||||
// globalSessions, _ = session.NewManager("postgresql", ``{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"user=pqgotest dbname=pqgotest sslmode=verify-full"}``)
|
||||
// go globalSessions.GC()
|
||||
// }
|
||||
//
|
||||
package postgres
|
||||
|
||||
import (
|
||||
@@ -115,7 +114,10 @@ func (st *SessionStore) SessionID(context.Context) string {
|
||||
// must call this method to save values to database.
|
||||
func (st *SessionStore) SessionRelease(ctx context.Context, w 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
|
||||
}
|
||||
|
||||
@@ -20,15 +20,16 @@
|
||||
//
|
||||
// Usage:
|
||||
// import(
|
||||
// _ "github.com/beego/beego/v2/server/web/session/redis"
|
||||
// "github.com/beego/beego/v2/server/web/session"
|
||||
//
|
||||
// _ "github.com/beego/beego/v2/server/web/session/redis"
|
||||
// "github.com/beego/beego/v2/server/web/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()
|
||||
// }
|
||||
package redis
|
||||
|
||||
import (
|
||||
@@ -100,7 +101,10 @@ func (rs *SessionStore) SessionID(context.Context) string {
|
||||
|
||||
// SessionRelease save session values to redis
|
||||
func (rs *SessionStore) SessionRelease(ctx context.Context, w http.ResponseWriter) {
|
||||
b, err := session.EncodeGob(rs.values)
|
||||
rs.lock.RLock()
|
||||
values := rs.values
|
||||
rs.lock.RUnlock()
|
||||
b, err := session.EncodeGob(values)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -20,15 +20,16 @@
|
||||
//
|
||||
// Usage:
|
||||
// import(
|
||||
// _ "github.com/beego/beego/v2/server/web/session/redis_cluster"
|
||||
// "github.com/beego/beego/v2/server/web/session"
|
||||
//
|
||||
// _ "github.com/beego/beego/v2/server/web/session/redis_cluster"
|
||||
// "github.com/beego/beego/v2/server/web/session"
|
||||
//
|
||||
// )
|
||||
//
|
||||
// func init() {
|
||||
// globalSessions, _ = session.NewManager("redis_cluster", ``{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"127.0.0.1:7070;127.0.0.1:7071"}``)
|
||||
// go globalSessions.GC()
|
||||
// }
|
||||
//
|
||||
package redis_cluster
|
||||
|
||||
import (
|
||||
@@ -100,7 +101,10 @@ func (rs *SessionStore) SessionID(context.Context) string {
|
||||
|
||||
// SessionRelease save session values to redis_cluster
|
||||
func (rs *SessionStore) SessionRelease(ctx context.Context, w http.ResponseWriter) {
|
||||
b, err := session.EncodeGob(rs.values)
|
||||
rs.lock.RLock()
|
||||
values := rs.values
|
||||
rs.lock.RUnlock()
|
||||
b, err := session.EncodeGob(values)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -20,8 +20,10 @@
|
||||
//
|
||||
// Usage:
|
||||
// import(
|
||||
// _ "github.com/beego/beego/v2/server/web/session/redis_sentinel"
|
||||
// "github.com/beego/beego/v2/server/web/session"
|
||||
//
|
||||
// _ "github.com/beego/beego/v2/server/web/session/redis_sentinel"
|
||||
// "github.com/beego/beego/v2/server/web/session"
|
||||
//
|
||||
// )
|
||||
//
|
||||
// func init() {
|
||||
@@ -101,7 +103,10 @@ func (rs *SessionStore) SessionID(context.Context) string {
|
||||
|
||||
// SessionRelease save session values to redis_sentinel
|
||||
func (rs *SessionStore) SessionRelease(ctx context.Context, w http.ResponseWriter) {
|
||||
b, err := session.EncodeGob(rs.values)
|
||||
rs.lock.RLock()
|
||||
values := rs.values
|
||||
rs.lock.RUnlock()
|
||||
b, err := session.EncodeGob(values)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -75,9 +75,11 @@ func (st *CookieSessionStore) SessionID(context.Context) string {
|
||||
|
||||
// SessionRelease Write cookie session to http response cookie
|
||||
func (st *CookieSessionStore) SessionRelease(ctx context.Context, w http.ResponseWriter) {
|
||||
st.lock.Lock()
|
||||
encodedCookie, err := encodeCookie(cookiepder.block, cookiepder.config.SecurityKey, cookiepder.config.SecurityName, st.values)
|
||||
st.lock.Unlock()
|
||||
st.lock.RLock()
|
||||
values := st.values
|
||||
st.lock.RUnlock()
|
||||
encodedCookie, err := encodeCookie(
|
||||
cookiepder.block, cookiepder.config.SecurityKey, cookiepder.config.SecurityName, values)
|
||||
if err == nil {
|
||||
cookie := &http.Cookie{
|
||||
Name: cookiepder.config.CookieName,
|
||||
@@ -110,11 +112,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(ctx context.Context, maxlifetime int64, config string) error {
|
||||
pder.config = &cookieConfig{}
|
||||
err := json.Unmarshal([]byte(config), pder.config)
|
||||
|
||||
@@ -205,7 +205,10 @@ func (s *SessionStore) SessionID(context.Context) string {
|
||||
|
||||
// SessionRelease Store the keyvalues into ssdb
|
||||
func (s *SessionStore) SessionRelease(ctx context.Context, w http.ResponseWriter) {
|
||||
b, err := session.EncodeGob(s.values)
|
||||
s.lock.RLock()
|
||||
values := s.values
|
||||
s.lock.RUnlock()
|
||||
b, err := session.EncodeGob(values)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user