From 0a74eadccb944ce1a97436855563af5dfe82c5e3 Mon Sep 17 00:00:00 2001 From: DarkGopher Date: Tue, 17 Jun 2025 18:50:59 +0200 Subject: [PATCH] resolvepanic moved to util.ResolvePanic --- go.mod | 2 ++ go.sum | 2 ++ session.go | 6 ++-- storage/files/files.go | 70 +++++++++++++++++++++++++++++++++++++--- storage/memory/memory.go | 14 +++----- util/panic.go | 9 ++++++ 6 files changed, 85 insertions(+), 18 deletions(-) create mode 100644 util/panic.go diff --git a/go.mod b/go.mod index f18c390..b22661a 100644 --- a/go.mod +++ b/go.mod @@ -3,3 +3,5 @@ module git.mtux.eu/darkgopher/session go 1.23.4 require golang.org/x/net v0.40.0 + +require github.com/djherbis/atime v1.1.0 diff --git a/go.sum b/go.sum index b194d68..83e9378 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,4 @@ +github.com/djherbis/atime v1.1.0 h1:rgwVbP/5by8BvvjBNrbh64Qz33idKT3pSnMSJsxhi0g= +github.com/djherbis/atime v1.1.0/go.mod h1:28OF6Y8s3NQWwacXc5eZTsEsiMzp7LF8MbXE+XJPdBE= golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= diff --git a/session.go b/session.go index 03709db..7025ddc 100644 --- a/session.go +++ b/session.go @@ -58,11 +58,11 @@ type Provider interface { // Session interface implement storage for one session and have maxLifetime and lastAccessTime type Session interface { //set session value and update last access time - Set(key, value interface{}) error + Set(key, value any) error //get session value and update last access time - Get(key interface{}) (v any, err error) + Get(key any) (v any, err error) //delete session value - Delete(key interface{}) error + Delete(key any) error //get session id SessionID() string } diff --git a/storage/files/files.go b/storage/files/files.go index 944444b..4e62c2a 100644 --- a/storage/files/files.go +++ b/storage/files/files.go @@ -2,10 +2,15 @@ package files import ( + "bytes" + "container/list" + "encoding/gob" "fmt" "os" "sync" "time" + + "github.com/djherbis/atime" ) const ( @@ -19,8 +24,9 @@ func init() { // ProviderFiles implement filesystem session provider type ProviderFiles struct { - sessPath string lock sync.Mutex + list *list.List //or gc + sessPath string } func (pder *ProviderFiles) ckdirpath(sid string) string { @@ -28,10 +34,13 @@ func (pder *ProviderFiles) ckdirpath(sid string) string { } func (pder *ProviderFiles) updateAtime(sid string) (err error) { - return + pth := pder.ckdirpath(sid) + return os.Chtimes(pth, time.Now(), time.Time{}) } -func (pder *ProviderFiles) getAtime(sid string) (atime *time.Time, err error) { - return + +func (pder *ProviderFiles) getAtime(sid string) (atm time.Time, err error) { + pth := pder.ckdirpath(sid) + return atime.Stat(pth) } // SetParams for files session provider set base path in filesystem for save sessions @@ -46,7 +55,7 @@ func (pder *ProviderFiles) SetParams(p any) (err error) { return fmt.Errorf("parameter for files session provider must not be nil") } -// Init create session file if not exists and retturn *Session +// Init create empty session file if not exists and retturn *Session func (pder *ProviderFiles) Init(sid string) (err error) { pder.lock.Lock() defer pder.lock.Unlock() @@ -55,5 +64,56 @@ func (pder *ProviderFiles) Init(sid string) (err error) { if fd, err = os.Create(ckf); err != nil { return fmt.Errorf("create session file: %s failed with err: %w", ckf, err) } + pder.list.PushBack(sid) return fd.Close() } + +// SessionFile save session data into files using gob encode/dacode +type SessionFile struct { + sfpth string +} + +// load data from session file +func (sf *SessionFile) load() (data map[any]any, err error) { + var sb []byte + if sb, err = os.ReadFile(sf.sfpth); err != nil { + return nil, fmt.Errorf("Session file: %s read error: %v", sf.sfpth, err) + } + var gobdata bytes.Buffer + if _, err = gobdata.Write(sb); err != nil { + return nil, fmt.Errorf("Load session file: %s into buffer err: %v", sf.sfpth, err) + } + dec := gob.NewDecoder(&gobdata) + if err = dec.Decode(&data); err != nil { + return nil, fmt.Errorf("Decode gob data from file: %s error: %v", sf.sfpth, err) + } + return +} + +// save data into session file +func (sf *SessionFile) save(data map[any]any) (err error) { + var gobdata bytes.Buffer + enc := gob.NewEncoder(&gobdata) + if err = enc.Encode(data); err != nil { + return fmt.Errorf("Gob encode file: %s error: %v", sf.sfpth, err) + } + if err = os.WriteFile(sf.sfpth, gobdata.Bytes(), 0o600); err != nil { + return fmt.Errorf("Write gob data into file: %s error: %v", sf.sfpth, err) + } + return nil +} + +// Get value from session key k +func (sf *SessionFile) Get(k any) (v any, err error) { + var data map[any]any + if data, err = sf.load(); err != nil { + return nil, err + } + return data[k], nil +} + +// Set value of key k to v +func (sf *SessionFile) Set(k, v any) (err error) { + //var data map[any]any + return +} diff --git a/storage/memory/memory.go b/storage/memory/memory.go index 60357b5..b835f8d 100644 --- a/storage/memory/memory.go +++ b/storage/memory/memory.go @@ -8,6 +8,7 @@ import ( "time" "git.mtux.eu/darkgopher/session" + "git.mtux.eu/darkgopher/session/util" ) var pder = &ProviderMemory{list: list.New()} @@ -118,16 +119,10 @@ type SessionMemory struct { data map[any]any } -func (sm *SessionMemory) resolvepanic(err *error) { - if r := recover(); r != nil { - *err = r.(error) - } -} - // Set - -func (sm *SessionMemory) Set(k any, v any) (err error) { +func (sm *SessionMemory) Set(k, v any) (err error) { defer pder.updateAtime(sm.sid) - defer sm.resolvepanic(&err) + defer util.ResolvePanic(&err) sm.data[k] = v return } @@ -135,14 +130,13 @@ func (sm *SessionMemory) Set(k any, v any) (err error) { // Get - func (sm *SessionMemory) Get(k any) (v any, err error) { defer pder.updateAtime(sm.sid) - defer sm.resolvepanic(&err) + defer util.ResolvePanic(&err) return sm.data[k], err } // Delete - func (sm *SessionMemory) Delete(k any) (err error) { defer pder.updateAtime(sm.sid) - delete(sm.data, k) return } diff --git a/util/panic.go b/util/panic.go new file mode 100644 index 0000000..062db2b --- /dev/null +++ b/util/panic.go @@ -0,0 +1,9 @@ +package util + +// ResolvePanic convert panic recover to error This used +// for map[any]any value manipulations when get panic +func ResolvePanic(err *error) { + if r := recover(); r != nil { + *err = r.(error) + } +}