From f7e376792944f4f5130d62d6e69297fc8790185a Mon Sep 17 00:00:00 2001 From: zeripath Date: Sun, 24 May 2020 00:59:04 +0100 Subject: [PATCH] Prevent (caught) panic on login (#11590) Unfortunately when the virtual session is released it requires that the real session does not exist. This worked fine when sessions were only saved at the end of request/response cycle however, now sessions are saved proactively this does not hold. The result is a caught panic in the logs during every log-in. This panic has no significant side-effects but should not occur. This PR marks the virtual session as released when released and updates it if the same session is released again. Signed-off-by: Andrew Thornton Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com> --- modules/session/virtual.go | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/modules/session/virtual.go b/modules/session/virtual.go index 027960a28..967192016 100644 --- a/modules/session/virtual.go +++ b/modules/session/virtual.go @@ -107,10 +107,11 @@ func init() { // VirtualStore represents a virtual session store implementation. type VirtualStore struct { - p *VirtualSessionProvider - sid string - lock sync.RWMutex - data map[interface{}]interface{} + p *VirtualSessionProvider + sid string + lock sync.RWMutex + data map[interface{}]interface{} + released bool } // NewVirtualStore creates and returns a virtual session store. @@ -164,7 +165,7 @@ func (s *VirtualStore) Release() error { // Now ensure that we don't exist! realProvider := s.p.provider - if realProvider.Exist(s.sid) { + if !s.released && realProvider.Exist(s.sid) { // This is an error! return fmt.Errorf("new sid '%s' already exists", s.sid) } @@ -172,12 +173,19 @@ func (s *VirtualStore) Release() error { if err != nil { return err } + if err := realStore.Flush(); err != nil { + return err + } for key, value := range s.data { if err := realStore.Set(key, value); err != nil { return err } } - return realStore.Release() + err = realStore.Release() + if err == nil { + s.released = true + } + return err } return nil }