diff --git a/session.go b/session.go index 7025ddc..2e851e8 100644 --- a/session.go +++ b/session.go @@ -94,13 +94,15 @@ type SessOpts struct { } // NewManager create new *Manager using SesOpts and aditional any other opts for using in provider -func NewManager(providerName string, sopts *SessOpts, adopts any) (*Manager, error) { +func NewManager(providerName string, sopts *SessOpts, adopts any) (manager *Manager, err error) { var prv Provider var ok bool if prv, ok = provides[providerName]; !ok { return nil, fmt.Errorf("session: Provider: %q not found (forgotten import?)", providerName) } - prv.SetParams(adopts) + if err = prv.SetParams(adopts); err != nil { + return nil, fmt.Errorf("session params: %v not valid: %v", adopts, err) + } m := &Manager{ provider: prv, sessOpts: sopts, diff --git a/storage/files/files.go b/storage/files/files.go index 4e62c2a..0d68940 100644 --- a/storage/files/files.go +++ b/storage/files/files.go @@ -10,6 +10,7 @@ import ( "sync" "time" + //"git.mtux.eu/darkgopher/session" "github.com/djherbis/atime" ) @@ -18,8 +19,15 @@ const ( sessExt string = "gsd" ) -func init() { +var pder *ProviderFiles +func init() { + pder = &ProviderFiles{} + //session.Register("files", pder) +} + +func ckdirpath(sid string) string { + return fmt.Sprintf("%s/%s/%s.%s", pder.sessPath, sessDir, sid, sessExt) } // ProviderFiles implement filesystem session provider @@ -29,17 +37,13 @@ type ProviderFiles struct { sessPath string } -func (pder *ProviderFiles) ckdirpath(sid string) string { - return fmt.Sprintf("%s/%s/%s.%s", pder.sessPath, sessDir, sid, sessExt) -} - func (pder *ProviderFiles) updateAtime(sid string) (err error) { - pth := pder.ckdirpath(sid) + pth := ckdirpath(sid) return os.Chtimes(pth, time.Now(), time.Time{}) } func (pder *ProviderFiles) getAtime(sid string) (atm time.Time, err error) { - pth := pder.ckdirpath(sid) + pth := ckdirpath(sid) return atime.Stat(pth) } @@ -52,7 +56,7 @@ func (pder *ProviderFiles) SetParams(p any) (err error) { } return fmt.Errorf("parameter for files session provider is not string") } - return fmt.Errorf("parameter for files session provider must not be nil") + return fmt.Errorf("parameter for files session provider must be provided, not nil") } // Init create empty session file if not exists and retturn *Session @@ -60,7 +64,7 @@ func (pder *ProviderFiles) Init(sid string) (err error) { pder.lock.Lock() defer pder.lock.Unlock() var fd *os.File - ckf := pder.ckdirpath(sid) + ckf := ckdirpath(sid) if fd, err = os.Create(ckf); err != nil { return fmt.Errorf("create session file: %s failed with err: %w", ckf, err) } @@ -68,24 +72,32 @@ func (pder *ProviderFiles) Init(sid string) (err error) { return fd.Close() } +// Read return existing session by sid or new session if not exists +func (pder *ProviderFiles) Read(sid string) (sess *SessionFile, err error) { + pder.lock.Lock() + defer pder.lock.Unlock() + return +} + // SessionFile save session data into files using gob encode/dacode type SessionFile struct { - sfpth string + sid 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) + sfp := ckdirpath(sf.sid) + if sb, err = os.ReadFile(sfp); err != nil { + return nil, fmt.Errorf("Session file: %s read error: %v", sf.sid, 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) + return nil, fmt.Errorf("Load session file: %s into buffer err: %v", sf.sid, 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 nil, fmt.Errorf("Decode gob data from file: %s error: %v", sf.sid, err) } return } @@ -95,16 +107,18 @@ 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) + return fmt.Errorf("Gob encode file: %s error: %v", sf.sid, 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) + sfp := ckdirpath(sf.sid) + if err = os.WriteFile(sfp, gobdata.Bytes(), 0o600); err != nil { + return fmt.Errorf("Write gob data into file: %s error: %v", sf.sid, err) } return nil } // Get value from session key k func (sf *SessionFile) Get(k any) (v any, err error) { + defer pder.updateAtime(sf.sid) var data map[any]any if data, err = sf.load(); err != nil { return nil, err @@ -114,6 +128,27 @@ func (sf *SessionFile) Get(k any) (v any, err error) { // Set value of key k to v func (sf *SessionFile) Set(k, v any) (err error) { - //var data map[any]any - return + defer pder.updateAtime(sf.sid) + var data map[any]any + if data, err = sf.load(); err != nil { + return err + } + data[k] = v + return sf.save(data) +} + +// Delete remove value of key k from session +func (sf *SessionFile) Delete(k any) (err error) { + defer pder.updateAtime(sf.sid) + var data map[any]any + if data, err = sf.load(); err != nil { + return err + } + delete(data, k) + return sf.save(data) +} + +// SessionID return sid +func (sf *SessionFile) SessionID() (sid string) { + return sf.sid } diff --git a/storage/memory/memory.go b/storage/memory/memory.go index b835f8d..1b8ea26 100644 --- a/storage/memory/memory.go +++ b/storage/memory/memory.go @@ -3,7 +3,6 @@ package memory import ( "container/list" - "fmt" "sync" "time" @@ -36,7 +35,7 @@ func (pder *ProviderMemory) updateAtime(sid string) { // SetParams for memory provider not possible func (pder *ProviderMemory) SetParams(pr any) error { - return fmt.Errorf("Not possible set parameters for memory session provider") + return nil } // Init create new session store for sid