diff --git a/.example/net/ghttp/server/session/session.go b/.example/net/ghttp/server/session/session.go index 81abd607d..e41215bd9 100644 --- a/.example/net/ghttp/server/session/session.go +++ b/.example/net/ghttp/server/session/session.go @@ -4,11 +4,12 @@ import ( "github.com/gogf/gf/frame/g" "github.com/gogf/gf/net/ghttp" "github.com/gogf/gf/os/gtime" + "time" ) func main() { s := g.Server() - s.SetSessionMaxAge(60) + s.SetSessionMaxAge(2 * time.Second) s.BindHandler("/set", func(r *ghttp.Request) { r.Session.Set("time", gtime.Second()) r.Response.Write("ok") diff --git a/net/ghttp/ghttp_server.go b/net/ghttp/ghttp_server.go index 01ab352fd..e42a14002 100644 --- a/net/ghttp/ghttp_server.go +++ b/net/ghttp/ghttp_server.go @@ -214,7 +214,7 @@ func GetServer(name ...interface{}) *Server { } config := defaultServerConfig if config.SessionStorage == nil { - config.SessionStorage = gsession.NewStorageFile(config.SessionMaxAge) + config.SessionStorage = gsession.NewStorageFile() } s := &Server{ name: serverName, diff --git a/net/ghttp/ghttp_server_config_session.go b/net/ghttp/ghttp_server_config_session.go index a1c83c280..bf127a55b 100644 --- a/net/ghttp/ghttp_server_config_session.go +++ b/net/ghttp/ghttp_server_config_session.go @@ -21,6 +21,7 @@ func (s *Server) SetSessionMaxAge(ttl time.Duration) { return } s.config.SessionMaxAge = ttl + s.sessionManager.SetTTL(ttl) } // 设置http server参数 - SessionIdName @@ -39,6 +40,7 @@ func (s *Server) SetSessionStorage(storage gsession.Storage) { return } s.config.SessionStorage = storage + s.sessionManager.SetStorage(storage) } // 获取http server参数 - SessionMaxAge diff --git a/os/gsession/gsession_manager.go b/os/gsession/gsession_manager.go index 3674f1a2f..1be4f60ce 100644 --- a/os/gsession/gsession_manager.go +++ b/os/gsession/gsession_manager.go @@ -23,7 +23,7 @@ type Manager struct { func New(ttl time.Duration, storage ...Storage) *Manager { m := &Manager{ ttl: ttl, - storage: NewStorageFile(ttl), + storage: NewStorageFile(), sessions: gcache.New(), } if len(storage) > 0 && storage[0] != nil { @@ -53,6 +53,11 @@ func (m *Manager) SetStorage(storage Storage) { m.storage = storage } +// SetTTL the TTL for the session manager. +func (m *Manager) SetTTL(ttl time.Duration) { + m.ttl = ttl +} + // TTL returns the TTL of the session manager. func (m *Manager) TTL() time.Duration { return m.ttl diff --git a/os/gsession/gsession_session.go b/os/gsession/gsession_session.go index 1e8602a28..ac7f086cc 100644 --- a/os/gsession/gsession_session.go +++ b/os/gsession/gsession_session.go @@ -32,7 +32,7 @@ func (s *Session) init() { s.dirty = gtype.NewBool(false) } if len(s.id) > 0 && s.data == nil { - if data := s.manager.storage.GetSession(s.id); data != nil { + if data := s.manager.storage.GetSession(s.id, s.manager.ttl); data != nil { if s.data = gmap.NewStrAnyMapFrom(data, true); s.data == nil { panic("session restoring failed for id:" + s.id) } diff --git a/os/gsession/gsession_storage.go b/os/gsession/gsession_storage.go index feb963f31..141be367b 100644 --- a/os/gsession/gsession_storage.go +++ b/os/gsession/gsession_storage.go @@ -6,6 +6,8 @@ package gsession +import "time" + type Storage interface { // Get retrieves session value with given key. // It returns nil if the key does not exist in the session. @@ -26,10 +28,13 @@ type Storage interface { RemoveAll() error // GetSession returns the session data bytes for given session id. - GetSession(id string) map[string]interface{} + // The parameter specifies the TTL for this session. + // It returns nil if the TTL is exceeded. + GetSession(id string, ttl time.Duration) map[string]interface{} // SetSession updates the content for session id. // Note that the parameter is the serialized bytes for session map. SetSession(id string, data map[string]interface{}) error + // UpdateTTL updates the TTL for specified session id. UpdateTTL(id string) error } diff --git a/os/gsession/gsession_storage_file.go b/os/gsession/gsession_storage_file.go index cfcb75054..00815fd3c 100644 --- a/os/gsession/gsession_storage_file.go +++ b/os/gsession/gsession_storage_file.go @@ -28,7 +28,6 @@ import ( // StorageFile implements the Session Storage interface with file system. type StorageFile struct { - ttl time.Duration path string cryptoKey []byte cryptoEnabled bool @@ -51,7 +50,7 @@ func init() { } // NewStorageFile creates and returns a file storage object for session. -func NewStorageFile(ttl time.Duration, path ...string) *StorageFile { +func NewStorageFile(path ...string) *StorageFile { storagePath := DefaultStorageFilePath if len(path) > 0 && path[0] != "" { storagePath, _ = gfile.Search(path[0]) @@ -68,7 +67,6 @@ func NewStorageFile(ttl time.Duration, path ...string) *StorageFile { } } s := &StorageFile{ - ttl: ttl, path: storagePath, cryptoKey: DefaultStorageFileCryptoKey, cryptoEnabled: DefaultStorageFileCryptoEnabled, @@ -135,12 +133,12 @@ func (s *StorageFile) RemoveAll() error { } // GetSession return the session data for given session id. -func (s *StorageFile) GetSession(id string) map[string]interface{} { +func (s *StorageFile) GetSession(id string, ttl time.Duration) map[string]interface{} { path := s.sessionFilePath(id) data := gfile.GetBytes(path) if len(data) > 8 { timestampMilli := gbinary.DecodeToInt64(data[:8]) - if timestampMilli+s.ttl.Nanoseconds()/1e6 < gtime.Millisecond() { + if timestampMilli+ttl.Nanoseconds()/1e6 < gtime.Millisecond() { return nil } var err error diff --git a/os/gsession/gsession_unit_manager_test.go b/os/gsession/gsession_unit_manager_test.go index f08f0dd93..b1017f8fe 100644 --- a/os/gsession/gsession_unit_manager_test.go +++ b/os/gsession/gsession_unit_manager_test.go @@ -15,7 +15,7 @@ import ( func Test_Manager_Basic(t *testing.T) { ttl := time.Second - storage := NewStorageFile(ttl) + storage := NewStorageFile() manager := New(ttl, storage) sessionId := "" gtest.Case(t, func() {