aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlyric <tiannianshou@gmail.com>2018-05-17 05:13:22 +0300
committerlyric <tiannianshou@gmail.com>2018-05-17 05:13:22 +0300
commit7c7e18faddc54ea614f135fcef8bc05649fa9452 (patch)
treee726fde3ee6835973b4ce9224dc16abdc75bc902
parent23a9229ef11190057188f4615a519ca6c9f693c4 (diff)
add echo middleware
-rw-r--r--README.md83
-rw-r--r--session.go90
-rw-r--r--session_test.go80
3 files changed, 251 insertions, 2 deletions
diff --git a/README.md b/README.md
index 0de181e..28c2235 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,81 @@
-# echo-session
-Session middleware for Echo.
+# Session middleware for [Echo](https://github.com/labstack/echo)
+
+[![ReportCard][reportcard-image]][reportcard-url] [![GoDoc][godoc-image]][godoc-url] [![License][license-image]][license-url]
+
+## Quick Start
+
+### Download and install
+
+```bash
+$ go get -u -v github.com/go-session/echo-session
+```
+
+### Create file `server.go`
+
+```go
+package main
+
+import (
+ "fmt"
+ "net/http"
+
+ "github.com/go-session/echo-session"
+ "github.com/labstack/echo"
+ "gopkg.in/session.v2"
+)
+
+func main() {
+ e := echo.New()
+
+ e.Use(echosession.New(
+ session.SetCookieName("session_id"),
+ session.SetSign([]byte("sign")),
+ ))
+
+ e.GET("/", func(ctx echo.Context) error {
+ store := echosession.FromContext(ctx)
+ store.Set("foo", "bar")
+ err := store.Save()
+ if err != nil {
+ return err
+ }
+ return ctx.Redirect(302, "/foo")
+ })
+
+ e.GET("/foo", func(ctx echo.Context) error {
+ store := echosession.FromContext(ctx)
+ foo, ok := store.Get("foo")
+ if !ok {
+ return ctx.String(http.StatusNotFound, "not found")
+ }
+ return ctx.String(http.StatusOK, fmt.Sprintf("foo:%s", foo))
+ })
+
+ e.Logger.Fatal(e.Start(":8080"))
+}
+```
+
+### Build and run
+
+```bash
+$ go build server.go
+$ ./server
+```
+
+### Open in your web browser
+
+<http://localhost:8080>
+
+ foo:bar
+
+
+## MIT License
+
+ Copyright (c) 2018 Lyric
+
+[reportcard-url]: https://goreportcard.com/report/github.com/go-session/echo-session
+[reportcard-image]: https://goreportcard.com/badge/github.com/go-session/echo-session
+[godoc-url]: https://godoc.org/github.com/go-session/echo-session
+[godoc-image]: https://godoc.org/github.com/go-session/echo-session?status.svg
+[license-url]: http://opensource.org/licenses/MIT
+[license-image]: https://img.shields.io/npm/l/express.svg \ No newline at end of file
diff --git a/session.go b/session.go
new file mode 100644
index 0000000..ea5bbc7
--- /dev/null
+++ b/session.go
@@ -0,0 +1,90 @@
+package echosession
+
+import (
+ "context"
+ "sync"
+
+ "github.com/labstack/echo"
+ "gopkg.in/session.v2"
+)
+
+type (
+ // Skipper defines a function to skip middleware. Returning true skips processing
+ // the middleware.
+ Skipper func(c echo.Context) bool
+
+ // Config defines the config for Session middleware.
+ Config struct {
+ // Skipper defines a function to skip middleware.
+ Skipper Skipper
+ // StoreKey keys stored in the context
+ StoreKey string
+ }
+)
+
+var (
+ // DefaultConfig is the default Recover middleware config.
+ DefaultConfig = Config{
+ Skipper: func(_ echo.Context) bool { return false },
+ StoreKey: "github.com/go-session/echo-session",
+ }
+
+ once sync.Once
+ internalManager *session.Manager
+ storeKey string
+)
+
+// get a session manager
+func manager(opt ...session.Option) *session.Manager {
+ once.Do(func() {
+ internalManager = session.NewManager(opt...)
+ })
+ return internalManager
+}
+
+// New create a session middleware
+func New(opt ...session.Option) echo.MiddlewareFunc {
+ return NewWithConfig(DefaultConfig, opt...)
+}
+
+// NewWithConfig create a session middleware
+func NewWithConfig(config Config, opt ...session.Option) echo.MiddlewareFunc {
+ if config.Skipper == nil {
+ config.Skipper = DefaultConfig.Skipper
+ }
+
+ storeKey = config.StoreKey
+ if storeKey == "" {
+ storeKey = DefaultConfig.StoreKey
+ }
+
+ return func(next echo.HandlerFunc) echo.HandlerFunc {
+ return func(c echo.Context) error {
+ if config.Skipper(c) {
+ return next(c)
+ }
+
+ store, err := manager(opt...).Start(context.Background(), c.Response(), c.Request())
+ if err != nil {
+ return err
+ }
+ c.Set(storeKey, store)
+ return next(c)
+ }
+ }
+}
+
+// FromContext get session storage from context
+func FromContext(ctx echo.Context) session.Store {
+ return ctx.Get(storeKey).(session.Store)
+}
+
+// Destroy a session
+func Destroy(ctx echo.Context) error {
+ return manager().Destroy(context.Background(), ctx.Response(), ctx.Request())
+}
+
+// Refresh a session and return to session storage
+func Refresh(ctx echo.Context) (session.Store, error) {
+ return manager().Refresh(context.Background(), ctx.Response(), ctx.Request())
+}
diff --git a/session_test.go b/session_test.go
new file mode 100644
index 0000000..9aea1c6
--- /dev/null
+++ b/session_test.go
@@ -0,0 +1,80 @@
+package echosession
+
+import (
+ "fmt"
+ "io/ioutil"
+ "net/http"
+ "net/http/httptest"
+ "testing"
+
+ "github.com/labstack/echo"
+ "gopkg.in/session.v2"
+)
+
+func TestSession(t *testing.T) {
+ cookieName := "test_echo_session"
+
+ e := echo.New()
+ e.Use(New(
+ session.SetCookieName(cookieName),
+ session.SetSign([]byte("sign")),
+ ))
+
+ e.GET("/", func(ctx echo.Context) error {
+ store := FromContext(ctx)
+ if ctx.QueryParam("login") == "1" {
+ foo, ok := store.Get("foo")
+ fmt.Fprintf(ctx.Response(), "%s:%v", foo, ok)
+ return nil
+ }
+
+ store.Set("foo", "bar")
+ err := store.Save()
+ if err != nil {
+ t.Error(err)
+ return nil
+ }
+ fmt.Fprint(ctx.Response(), "ok")
+ return nil
+ })
+
+ w := httptest.NewRecorder()
+ req, err := http.NewRequest("GET", "/", nil)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+ e.ServeHTTP(w, req)
+
+ res := w.Result()
+ cookie := res.Cookies()[0]
+ if cookie.Name != cookieName {
+ t.Error("Not expected value:", cookie.Name)
+ return
+ }
+
+ buf, _ := ioutil.ReadAll(res.Body)
+ res.Body.Close()
+ if string(buf) != "ok" {
+ t.Error("Not expected value:", string(buf))
+ return
+ }
+
+ req, err = http.NewRequest("GET", "/?login=1", nil)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+ req.AddCookie(cookie)
+
+ w = httptest.NewRecorder()
+ e.ServeHTTP(w, req)
+
+ res = w.Result()
+ buf, _ = ioutil.ReadAll(res.Body)
+ res.Body.Close()
+ if string(buf) != "bar:true" {
+ t.Error("Not expected value:", string(buf))
+ return
+ }
+}