Prevent panics due to EOF in gob.Decode #5

Merged
6543 merged 3 commits from zeripath/session:no-more-EOF-panic into master 2022-12-20 00:55:50 +00:00
10 changed files with 74 additions and 30 deletions
Showing only changes of commit 15afcca0bc - Show all commits

View File

@ -1,6 +1,6 @@
# Session
Middleware session provides session management which copied from [Macaron Session](https://gitea.com/go-chi/session) for [go-chi](https://github.com/go-chi/chi). It can use many session providers, including memory, file, Redis, Memcache, PostgreSQL, MySQL, Couchbase, Ledis and Nodb.
Middleware session provides session management which based on a [fork](https://gitea.com/macaron/session) of [Macaron Session](https://github.com/go-macaron/session) for [go-chi](https://github.com/go-chi/chi). It can use many session providers, including memory, file, Redis, Memcache, PostgreSQL, MySQL, Couchbase, Ledis and Nodb.
## Installation
@ -10,8 +10,8 @@ go get gitea.com/go-chi/session
## Credits
This package is a modified version of [go-macaron/session](github.com/go-macaron/session).
This package is a modified version of [go-macaron/session](https://github.com/go-macaron/session).
## License
This project is under the Apache License, Version 2.0. See the [LICENSE](LICENSE) file for the full license text.
This project is under the Apache License, Version 2.0. See the [LICENSE](LICENSE) file for the full license text.

2
go.mod
View File

@ -9,7 +9,7 @@ require (
github.com/couchbase/goutils v0.0.0-20201030094643-5e82bb967e67 // indirect
github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76 // indirect
github.com/edsrzf/mmap-go v1.0.0 // indirect
github.com/go-chi/chi v1.5.1
github.com/go-chi/chi/v5 v5.0.4
github.com/go-redis/redis/v8 v8.4.0
github.com/go-sql-driver/mysql v1.4.1
github.com/lib/pq v1.2.0

12
go.sum
View File

@ -10,7 +10,6 @@ github.com/couchbase/goutils v0.0.0-20201030094643-5e82bb967e67 h1:NCqJ6fwen6YP0
github.com/couchbase/goutils v0.0.0-20201030094643-5e82bb967e67/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs=
github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76 h1:Lgdd/Qp96Qj8jqLpq2cI1I1X7BJnu06efS+XkhRoLUQ=
github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -18,18 +17,16 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/r
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw=
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/go-chi/chi v1.5.1 h1:kfTK3Cxd/dkMu/rKs5ZceWYp+t5CtiE7vmaTv3LjC6w=
github.com/go-chi/chi v1.5.1/go.mod h1:REp24E+25iKvxgeTfHmdUoL5x15kBiDBlnIl5bCwe2k=
github.com/go-chi/chi/v5 v5.0.4 h1:5e494iHzsYBiyXQAHHuI4tyJS9M3V84OuX3ufIIGHFo=
github.com/go-chi/chi/v5 v5.0.4/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-redis/redis/v8 v8.4.0 h1:J5NCReIgh3QgUJu398hUncxDExN4gMOHI11NVbVicGQ=
github.com/go-redis/redis/v8 v8.4.0/go.mod h1:A1tbYoHSa1fXwN+//ljcCYYJeLmVrwL9hbQN45Jdy0M=
github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
@ -48,7 +45,6 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg=
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
@ -58,12 +54,10 @@ github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.14.2 h1:8mVmC9kjFFmA8H4pKMUhcblgifdkOIXPvbhN1T36q1M=
github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
@ -118,7 +112,6 @@ golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
@ -137,7 +130,6 @@ google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyz
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=

View File

@ -20,7 +20,7 @@ import (
"testing"
"gitea.com/go-chi/session"
"github.com/go-chi/chi"
chi "github.com/go-chi/chi/v5"
. "github.com/smartystreets/goconvey/convey"
)

View File

@ -20,7 +20,7 @@ import (
"testing"
"gitea.com/go-chi/session"
"github.com/go-chi/chi"
chi "github.com/go-chi/chi/v5"
. "github.com/smartystreets/goconvey/convey"
)

View File

@ -21,7 +21,7 @@ import (
"time"
"gitea.com/go-chi/session"
"github.com/go-chi/chi"
chi "github.com/go-chi/chi/v5"
. "github.com/smartystreets/goconvey/convey"
)

View File

@ -21,7 +21,7 @@ import (
"time"
"gitea.com/go-chi/session"
"github.com/go-chi/chi"
chi "github.com/go-chi/chi/v5"
. "github.com/smartystreets/goconvey/convey"
)

View File

@ -20,7 +20,7 @@ import (
"testing"
"gitea.com/go-chi/session"
"github.com/go-chi/chi"
chi "github.com/go-chi/chi/v5"
. "github.com/smartystreets/goconvey/convey"
)

View File

@ -23,6 +23,7 @@ import (
"fmt"
"net/http"
"net/url"
"reflect"
"time"
)
@ -259,7 +260,7 @@ func Sessioner(options ...Options) func(next http.Handler) http.Handler {
return
}
if err = sess.Release(); err != nil {
if err = s.RawStore.Release(); err != nil {
panic("session(release): " + err.Error())
}
})
@ -273,6 +274,26 @@ func GetSession(req *http.Request) Store {
return sess
}
// RegenerateSession
func RegenerateSession(resp http.ResponseWriter, req *http.Request) (Store, error) {
sess, ok := GetSession(req).(*store)
if !ok {
return nil, fmt.Errorf("no session in request context")
}
oldRawStore := sess.RawStore
if err := oldRawStore.Release(); err != nil {
return nil, err
}
store, err := sess.RegenerateID(resp, req)
if err != nil {
return nil, err
}
sess.RawStore = store
return sess, nil
}
// Provider is the interface that provides session manipulations.
type Provider interface {
// Init initializes session provider.
@ -291,17 +312,34 @@ type Provider interface {
GC()
}
var providers = make(map[string]Provider)
var providers = make(map[string]func() Provider)
// Register registers a provider.
func Register(name string, provider Provider) {
if provider == nil {
if reflect.TypeOf(provider).Kind() == reflect.Ptr {
// Pointer:
RegisterFn(name, func() Provider {
return reflect.New(reflect.ValueOf(provider).Elem().Type()).Interface().(Provider)
})
return
}
// Not a Pointer
RegisterFn(name, func() Provider {
return reflect.New(reflect.TypeOf(provider)).Elem().Interface().(Provider)
})
}
// RegisterFn registers a provider function.
func RegisterFn(name string, providerfn func() Provider) {
if providerfn == nil {
panic("session: cannot register provider with nil value")
}
if _, dup := providers[name]; dup {
panic(fmt.Errorf("session: cannot register provider '%s' twice", name))
}
providers[name] = provider
providers[name] = providerfn
}
// _____
@ -318,12 +356,15 @@ type Manager struct {
}
// NewManager creates and returns a new session manager by given provider name and configuration.
// It panics when given provider isn't registered.
// It returns an error when requested provider name isn't registered.
func NewManager(name string, opt Options) (*Manager, error) {
p, ok := providers[name]
fn, ok := providers[name]
if !ok {
return nil, fmt.Errorf("session: unknown provider '%s'(forgotten import?)", name)
}
p := fn()
return &Manager{p, opt}, p.Init(opt.Maxlifetime, opt.ProviderConfig)
}

View File

@ -21,7 +21,7 @@ import (
"testing"
"time"
"github.com/go-chi/chi"
chi "github.com/go-chi/chi/v5"
. "github.com/smartystreets/goconvey/convey"
)
@ -71,20 +71,31 @@ func testProvider(opt Options) {
Convey("Basic operation", func() {
c := chi.NewRouter()
c.Use(Sessioner(opt))
var initialSid string
c.Get("/", func(resp http.ResponseWriter, req *http.Request) {
sess := GetSession(req)
sess.Set("uname", "unknwon")
initialSid = sess.ID()
})
c.Get("/reg", func(resp http.ResponseWriter, req *http.Request) {
sess := GetSession(req)
raw, err := sess.RegenerateID(resp, req)
So(initialSid, ShouldEqual, sess.ID())
raw, err := RegenerateSession(resp, req)
So(err, ShouldBeNil)
So(raw, ShouldNotBeNil)
So(sess, ShouldNotBeNil)
So(sess, ShouldEqual, raw)
uname := raw.Get("uname")
So(initialSid, ShouldNotEqual, sess.ID())
uname := sess.Get("uname")
So(uname, ShouldNotBeNil)
So(uname, ShouldEqual, "unknwon")
sess.Set("uname", "lunny")
uname = sess.Get("uname")
So(uname, ShouldNotBeNil)
So(uname, ShouldEqual, "lunny")
})
c.Get("/get", func(resp http.ResponseWriter, req *http.Request) {
sess := GetSession(req)
@ -97,7 +108,7 @@ func testProvider(opt Options) {
uname := sess.Get("uname")
So(uname, ShouldNotBeNil)
So(uname, ShouldEqual, "unknwon")
So(uname, ShouldEqual, "lunny")
So(sess.Delete("uname"), ShouldBeNil)
So(sess.Get("uname"), ShouldBeNil)