This commit is contained in:
Makis Maropoulos 2016-07-01 01:38:29 +03:00
parent 82d37c5c35
commit af67a97518
5 changed files with 25 additions and 9 deletions

View File

@ -63,6 +63,9 @@ type (
Provider string Provider string
// Cookie string, the session's client cookie name, for example: "irissessionid" // Cookie string, the session's client cookie name, for example: "irissessionid"
Cookie string Cookie string
// DecodeCookie set it to true to decode the cookie key with base64 URLEncoding
// Defaults to false
DecodeCookie bool
//Expires the date which the cookie must expires. Default infinitive/unlimited life //Expires the date which the cookie must expires. Default infinitive/unlimited life
Expires time.Time Expires time.Time
// GcDuration every how much duration(GcDuration) the memory should be clear for unused cookies (GcDuration) // GcDuration every how much duration(GcDuration) the memory should be clear for unused cookies (GcDuration)
@ -83,6 +86,7 @@ func DefaultSessions() Sessions {
return Sessions{ return Sessions{
Provider: "memory", // the default provider is "memory", if you set it to "" means that sessions are disabled. Provider: "memory", // the default provider is "memory", if you set it to "" means that sessions are disabled.
Cookie: DefaultCookieName, Cookie: DefaultCookieName,
DecodeCookie: false,
Expires: CookieExpireNever, Expires: CookieExpireNever,
GcDuration: DefaultSessionGcDuration, GcDuration: DefaultSessionGcDuration,
DisableSubdomainPersistence: false, DisableSubdomainPersistence: false,

View File

@ -42,11 +42,15 @@ func newManager(c config.Sessions) (*Manager, error) {
if !found { if !found {
return nil, ErrProviderNotFound.Format(c.Provider) return nil, ErrProviderNotFound.Format(c.Provider)
} }
if c.DecodeCookie {
c.Cookie = base64.URLEncoding.EncodeToString([]byte(c.Cookie)) // change the cookie's name/key to a more safe(?)
// get the real value for your tests by:
//sessIdKey := url.QueryEscape(base64.URLEncoding.EncodeToString([]byte(iris.Config.Sessions.Cookie)))
}
manager := &Manager{} manager := &Manager{}
manager.config = &c manager.config = &c
manager.provider = provider manager.provider = provider
manager.config.Cookie = base64.URLEncoding.EncodeToString([]byte(c.Cookie)) // change the cookie's name/key to a more safe
return manager, nil return manager, nil
} }
@ -90,7 +94,7 @@ func (m *Manager) Start(ctx context.IContext) store.IStore {
cookie := fasthttp.AcquireCookie() cookie := fasthttp.AcquireCookie()
// The RFC makes no mention of encoding url value, so here I think to encode both sessionid key and the value using the safe(to put and to use as cookie) url-encoding // The RFC makes no mention of encoding url value, so here I think to encode both sessionid key and the value using the safe(to put and to use as cookie) url-encoding
cookie.SetKey(m.config.Cookie) cookie.SetKey(m.config.Cookie)
cookie.SetValue(base64.URLEncoding.EncodeToString([]byte(sid))) cookie.SetValue(sid)
cookie.SetPath("/") cookie.SetPath("/")
if !m.config.DisableSubdomainPersistence { if !m.config.DisableSubdomainPersistence {
requestDomain := ctx.HostString() requestDomain := ctx.HostString()
@ -132,8 +136,7 @@ func (m *Manager) Start(ctx context.IContext) store.IStore {
requestCtx.Response.Header.SetCookie(cookie) requestCtx.Response.Header.SetCookie(cookie)
fasthttp.ReleaseCookie(cookie) fasthttp.ReleaseCookie(cookie)
} else { } else {
sid, _ := base64.URLEncoding.DecodeString(cookieValue) store, _ = m.provider.Read(cookieValue)
store, _ = m.provider.Read(string(sid))
} }
m.mu.Unlock() m.mu.Unlock()
@ -149,9 +152,7 @@ func (m *Manager) Destroy(ctx context.IContext) {
m.mu.Lock() m.mu.Lock()
m.provider.Destroy(cookieValue) m.provider.Destroy(cookieValue)
ctx.RemoveCookie(m.config.Cookie) ctx.RemoveCookie(m.config.Cookie)
m.mu.Unlock() m.mu.Unlock()
} }

View File

@ -55,9 +55,12 @@ func (p *Provider) Init(sid string) (store.IStore, error) {
// Read returns the store which sid parameter is belongs // Read returns the store which sid parameter is belongs
func (p *Provider) Read(sid string) (store.IStore, error) { func (p *Provider) Read(sid string) (store.IStore, error) {
p.mu.Lock()
if elem, found := p.sessions[sid]; found { if elem, found := p.sessions[sid]; found {
p.mu.Unlock() // yes defer is slow
return elem.Value.(store.IStore), nil return elem.Value.(store.IStore), nil
} }
p.mu.Unlock()
// if not found // if not found
sessionStore, err := p.Init(sid) sessionStore, err := p.Init(sid)
return sessionStore, err return sessionStore, err
@ -66,12 +69,13 @@ func (p *Provider) Read(sid string) (store.IStore, error) {
// Destroy always returns a nil error, for now. // Destroy always returns a nil error, for now.
func (p *Provider) Destroy(sid string) error { func (p *Provider) Destroy(sid string) error {
p.mu.Lock()
if elem, found := p.sessions[sid]; found { if elem, found := p.sessions[sid]; found {
elem.Value.(store.IStore).Destroy() elem.Value.(store.IStore).Destroy()
delete(p.sessions, sid) delete(p.sessions, sid)
p.list.Remove(elem) p.list.Remove(elem)
} }
p.mu.Unlock()
return nil return nil
} }

View File

@ -102,7 +102,10 @@ func (s *Store) SetLastAccessedTime(lastacc time.Time) {
s.lastAccessedTime = lastacc s.lastAccessedTime = lastacc
} }
// Destroy does nothing here, to destroy the session use the manager's .Destroy func // Destroy
func (s *Store) Destroy() { func (s *Store) Destroy() {
// nothing // clears without provider's update.
for key := range s.values {
delete(s.values, key)
}
} }

View File

@ -173,4 +173,8 @@ func (s *Store) SetLastAccessedTime(lastacc time.Time) {
func (s *Store) Destroy() { func (s *Store) Destroy() {
// remove the whole value which is the s.values from real redis // remove the whole value which is the s.values from real redis
redis.Delete(s.sid) redis.Delete(s.sid)
for key := range s.values {
delete(s.values, key)
}
} }