mirror of
https://github.com/kataras/iris.git
synced 2026-01-04 02:37:14 +00:00
Update to 8.2.0 | BoltDB session database, fix file sessiondb, faster, simpler and improvement Session Database API
Former-commit-id: 4034737a65b78a77277e4283fd9289c17f4a452e
This commit is contained in:
68
core/memstore/gob.go
Normal file
68
core/memstore/gob.go
Normal file
@@ -0,0 +1,68 @@
|
||||
package memstore
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/gob"
|
||||
"io"
|
||||
"time"
|
||||
)
|
||||
|
||||
// why?
|
||||
// on the future we may change how these encoders/decoders
|
||||
// and we may need different method for store and other for entry.
|
||||
|
||||
func init() {
|
||||
gob.Register(Store{})
|
||||
gob.Register(Entry{})
|
||||
gob.Register(time.Time{})
|
||||
}
|
||||
|
||||
// GobEncode accepts a store and writes
|
||||
// as series of bytes to the "w" writer.
|
||||
func GobEncode(store Store, w io.Writer) error {
|
||||
enc := gob.NewEncoder(w)
|
||||
err := enc.Encode(store)
|
||||
return err
|
||||
}
|
||||
|
||||
// GobSerialize same as GobEncode but it returns
|
||||
// the bytes using a temp buffer.
|
||||
func GobSerialize(store Store) ([]byte, error) {
|
||||
w := new(bytes.Buffer)
|
||||
err := GobEncode(store, w)
|
||||
return w.Bytes(), err
|
||||
}
|
||||
|
||||
// GobEncodeEntry accepts an entry and writes
|
||||
// as series of bytes to the "w" writer.
|
||||
func GobEncodeEntry(entry Entry, w io.Writer) error {
|
||||
enc := gob.NewEncoder(w)
|
||||
err := enc.Encode(entry)
|
||||
return err
|
||||
}
|
||||
|
||||
// GobSerializeEntry same as GobEncodeEntry but it returns
|
||||
// the bytes using a temp buffer.
|
||||
func GobSerializeEntry(entry Entry) ([]byte, error) {
|
||||
w := new(bytes.Buffer)
|
||||
err := GobEncodeEntry(entry, w)
|
||||
return w.Bytes(), err
|
||||
}
|
||||
|
||||
// GobDecode accepts a series of bytes and returns
|
||||
// the store.
|
||||
func GobDecode(b []byte) (store Store, err error) {
|
||||
dec := gob.NewDecoder(bytes.NewBuffer(b))
|
||||
// no reference because of:
|
||||
// gob: decoding into local type *memstore.Store, received remote type Entry
|
||||
err = dec.Decode(&store)
|
||||
return
|
||||
}
|
||||
|
||||
// GobDecodeEntry accepts a series of bytes and returns
|
||||
// the entry.
|
||||
func GobDecodeEntry(b []byte) (entry Entry, err error) {
|
||||
dec := gob.NewDecoder(bytes.NewBuffer(b))
|
||||
err = dec.Decode(&entry)
|
||||
return
|
||||
}
|
||||
@@ -16,7 +16,7 @@ type (
|
||||
// Entry is the entry of the context storage Store - .Values()
|
||||
Entry struct {
|
||||
Key string
|
||||
value interface{}
|
||||
ValueRaw interface{}
|
||||
immutable bool // if true then it can't change by its caller.
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ type (
|
||||
func (e Entry) Value() interface{} {
|
||||
if e.immutable {
|
||||
// take its value, no pointer even if setted with a rreference.
|
||||
vv := reflect.Indirect(reflect.ValueOf(e.value))
|
||||
vv := reflect.Indirect(reflect.ValueOf(e.ValueRaw))
|
||||
|
||||
// return copy of that slice
|
||||
if vv.Type().Kind() == reflect.Slice {
|
||||
@@ -48,18 +48,16 @@ func (e Entry) Value() interface{} {
|
||||
// if was *value it will return value{}.
|
||||
return vv.Interface()
|
||||
}
|
||||
return e.value
|
||||
return e.ValueRaw
|
||||
}
|
||||
|
||||
// the id is immutable(true or false)+key
|
||||
// so the users will be able to use the same key
|
||||
// to store two different entries (one immutable and other mutable).
|
||||
// or no? better no, that will confuse and maybe result on unexpected results.
|
||||
// I will just replace the value and the immutable bool value when Set if
|
||||
// a key is already exists.
|
||||
// func (e Entry) identifier() string {}
|
||||
|
||||
func (r *Store) save(key string, value interface{}, immutable bool) {
|
||||
// Save same as `Set`
|
||||
// However, if "immutable" is true then saves it as immutable (same as `SetImmutable`).
|
||||
//
|
||||
//
|
||||
// Returns the entry and true if it was just inserted, meaning that
|
||||
// it will return the entry and a false boolean if the entry exists and it has been updated.
|
||||
func (r *Store) Save(key string, value interface{}, immutable bool) (Entry, bool) {
|
||||
args := *r
|
||||
n := len(args)
|
||||
|
||||
@@ -71,15 +69,15 @@ func (r *Store) save(key string, value interface{}, immutable bool) {
|
||||
// if called by `SetImmutable`
|
||||
// then allow the update, maybe it's a slice that user wants to update by SetImmutable method,
|
||||
// we should allow this
|
||||
kv.value = value
|
||||
kv.ValueRaw = value
|
||||
kv.immutable = immutable
|
||||
} else if kv.immutable == false {
|
||||
// if it was not immutable then user can alt it via `Set` and `SetImmutable`
|
||||
kv.value = value
|
||||
kv.ValueRaw = value
|
||||
kv.immutable = immutable
|
||||
}
|
||||
// else it was immutable and called by `Set` then disallow the update
|
||||
return
|
||||
return *kv, false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,25 +87,29 @@ func (r *Store) save(key string, value interface{}, immutable bool) {
|
||||
args = args[:n+1]
|
||||
kv := &args[n]
|
||||
kv.Key = key
|
||||
kv.value = value
|
||||
kv.ValueRaw = value
|
||||
kv.immutable = immutable
|
||||
*r = args
|
||||
return
|
||||
return *kv, true
|
||||
}
|
||||
|
||||
// add
|
||||
kv := Entry{
|
||||
Key: key,
|
||||
value: value,
|
||||
ValueRaw: value,
|
||||
immutable: immutable,
|
||||
}
|
||||
*r = append(args, kv)
|
||||
return kv, true
|
||||
}
|
||||
|
||||
// Set saves a value to the key-value storage.
|
||||
// Returns the entry and true if it was just inserted, meaning that
|
||||
// it will return the entry and a false boolean if the entry exists and it has been updated.
|
||||
//
|
||||
// See `SetImmutable` and `Get`.
|
||||
func (r *Store) Set(key string, value interface{}) {
|
||||
r.save(key, value, false)
|
||||
func (r *Store) Set(key string, value interface{}) (Entry, bool) {
|
||||
return r.Save(key, value, false)
|
||||
}
|
||||
|
||||
// SetImmutable saves a value to the key-value storage.
|
||||
@@ -116,10 +118,13 @@ func (r *Store) Set(key string, value interface{}) {
|
||||
// An Immutable entry should be only changed with a `SetImmutable`, simple `Set` will not work
|
||||
// if the entry was immutable, for your own safety.
|
||||
//
|
||||
// Returns the entry and true if it was just inserted, meaning that
|
||||
// it will return the entry and a false boolean if the entry exists and it has been updated.
|
||||
//
|
||||
// Use it consistently, it's far slower than `Set`.
|
||||
// Read more about muttable and immutable go types: https://stackoverflow.com/a/8021081
|
||||
func (r *Store) SetImmutable(key string, value interface{}) {
|
||||
r.save(key, value, true)
|
||||
func (r *Store) SetImmutable(key string, value interface{}) (Entry, bool) {
|
||||
return r.Save(key, value, true)
|
||||
}
|
||||
|
||||
// Get returns the entry's value based on its key.
|
||||
@@ -205,3 +210,9 @@ func (r *Store) Len() int {
|
||||
args := *r
|
||||
return len(args)
|
||||
}
|
||||
|
||||
// Serialize returns the byte representation of the current Store.
|
||||
func (r Store) Serialize() []byte { // note: no pointer here, ignore linters if shows up.
|
||||
b, _ := GobSerialize(r)
|
||||
return b
|
||||
}
|
||||
|
||||
@@ -487,6 +487,7 @@ func (rb *APIBuilder) StaticServe(systemPath string, requestPath ...string) *Rou
|
||||
}
|
||||
|
||||
if err := ctx.ServeFile(spath, true); err != nil {
|
||||
ctx.Application().Logger().Warnf("while trying to serve static file: '%v' on IP: '%s'", err, ctx.RemoteAddr())
|
||||
ctx.StatusCode(http.StatusInternalServerError)
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user