From 6fb90cfdb4bcc6da6219cedb3041d37d1e00c987 Mon Sep 17 00:00:00 2001 From: kataras Date: Wed, 2 Aug 2017 20:53:17 +0300 Subject: [PATCH] Implement a file-storage session database for https://github.com/kataras/iris/issues/702 (UNTESTED) Former-commit-id: 7ca4183ee0602936d8270d6e7dac6bec3d3fa2b5 --- sessions/sessiondb/file/database.go | 85 ++++++++++++++++++++++++++++ sessions/sessiondb/redis/database.go | 4 +- 2 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 sessions/sessiondb/file/database.go diff --git a/sessions/sessiondb/file/database.go b/sessions/sessiondb/file/database.go new file mode 100644 index 00000000..0b83b35f --- /dev/null +++ b/sessions/sessiondb/file/database.go @@ -0,0 +1,85 @@ +package file + +import ( + "bytes" + "encoding/gob" + "io/ioutil" + "os" + "path/filepath" + + "github.com/kataras/golog" +) + +// Database is the basic file-storage session database. +type Database struct { + path string +} + +// New returns a new file-storage database instance based on the "path". +func New(path string) *Database { + lindex := path[len(path)-1] + if lindex != os.PathSeparator && lindex != '/' { + path += string(os.PathSeparator) + } + + return &Database{path: path} +} + +func (d *Database) sessPath(sid string) string { + return filepath.Join(d.path, sid) +} + +// Load loads the values to the underline +func (d *Database) Load(sid string) map[string]interface{} { + values := make(map[string]interface{}) + + val, err := ioutil.ReadFile(d.sessPath(sid)) + + if err == nil { + err = DeserializeBytes(val, &values) + } + + if err != nil { + golog.Errorf("load error: %v", err) + } + + return values +} + +// serialize the values to be stored as strings inside the session file-storage. +func serialize(values map[string]interface{}) []byte { + val, err := SerializeBytes(values) + if err != nil { + golog.Errorf("serialize error: %v", err) + } + + return val +} + +// Update updates the session file-storage. +func (d *Database) Update(sid string, newValues map[string]interface{}) { + sessPath := d.sessPath(sid) + if len(newValues) == 0 { + go os.Remove(sessPath) + return + } + + ioutil.WriteFile(sessPath, serialize(newValues), 0666) +} + +// SerializeBytes serializes the "m" into bytes using gob encoder and and returns the result. +func SerializeBytes(m interface{}) ([]byte, error) { + buf := new(bytes.Buffer) + enc := gob.NewEncoder(buf) + err := enc.Encode(m) + if err == nil { + return buf.Bytes(), nil + } + return nil, err +} + +// DeserializeBytes converts the bytes to a go value and puts that to "m" using the gob decoder. +func DeserializeBytes(b []byte, m interface{}) error { + dec := gob.NewDecoder(bytes.NewBuffer(b)) + return dec.Decode(m) //no reference here otherwise doesn't work because of go remote object +} diff --git a/sessions/sessiondb/redis/database.go b/sessions/sessiondb/redis/database.go index 62dfc4af..00b95c6a 100644 --- a/sessions/sessiondb/redis/database.go +++ b/sessions/sessiondb/redis/database.go @@ -88,7 +88,7 @@ func (d *Database) Update(sid string, newValues map[string]interface{}, expireDa } -// SerializeBytes serializa bytes using gob encoder and returns them +// SerializeBytes serialize the "m" into bytes using the gob encoder and returns the result. func SerializeBytes(m interface{}) ([]byte, error) { buf := new(bytes.Buffer) enc := gob.NewEncoder(buf) @@ -99,7 +99,7 @@ func SerializeBytes(m interface{}) ([]byte, error) { return nil, err } -// DeserializeBytes converts the bytes to an object using gob decoder +// DeserializeBytes converts the bytes to a go value and puts that to "m" using the gob decoder. func DeserializeBytes(b []byte, m interface{}) error { dec := gob.NewDecoder(bytes.NewBuffer(b)) return dec.Decode(m) //no reference here otherwise doesn't work because of go remote object