Prevent (caught) panic on login ()

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 <art27@cantab.net>

Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com>
This commit is contained in:
zeripath 2020-05-24 00:59:04 +01:00 committed by GitHub
parent ac3c467770
commit f7e3767929
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -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
}