summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWenhui Shen <swhbox@foxmail.com>2017-04-21 18:53:14 +0300
committerWenhui Shen <swhbox@foxmail.com>2017-04-21 18:53:14 +0300
commit67899843326615eb013a1549755bb5b12bef2e70 (patch)
treef815aa261cfccf4d53bfb1247096b1ee8fc2a284
parent9a96fc7c41f2271e80c057640931757eaccc755c (diff)
update
-rw-r--r--.vscode/temp.sql0
-rw-r--r--lex.go102
-rw-r--r--sessions.go8
-rw-r--r--store.go18
4 files changed, 127 insertions, 1 deletions
diff --git a/.vscode/temp.sql b/.vscode/temp.sql
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.vscode/temp.sql
diff --git a/lex.go b/lex.go
new file mode 100644
index 0000000..4bbbe10
--- /dev/null
+++ b/lex.go
@@ -0,0 +1,102 @@
+// This file contains code adapted from the Go standard library
+// https://github.com/golang/go/blob/39ad0fd0789872f9469167be7fe9578625ff246e/src/net/http/lex.go
+
+package sessions
+
+import "strings"
+
+var isTokenTable = [127]bool{
+ '!': true,
+ '#': true,
+ '$': true,
+ '%': true,
+ '&': true,
+ '\'': true,
+ '*': true,
+ '+': true,
+ '-': true,
+ '.': true,
+ '0': true,
+ '1': true,
+ '2': true,
+ '3': true,
+ '4': true,
+ '5': true,
+ '6': true,
+ '7': true,
+ '8': true,
+ '9': true,
+ 'A': true,
+ 'B': true,
+ 'C': true,
+ 'D': true,
+ 'E': true,
+ 'F': true,
+ 'G': true,
+ 'H': true,
+ 'I': true,
+ 'J': true,
+ 'K': true,
+ 'L': true,
+ 'M': true,
+ 'N': true,
+ 'O': true,
+ 'P': true,
+ 'Q': true,
+ 'R': true,
+ 'S': true,
+ 'T': true,
+ 'U': true,
+ 'W': true,
+ 'V': true,
+ 'X': true,
+ 'Y': true,
+ 'Z': true,
+ '^': true,
+ '_': true,
+ '`': true,
+ 'a': true,
+ 'b': true,
+ 'c': true,
+ 'd': true,
+ 'e': true,
+ 'f': true,
+ 'g': true,
+ 'h': true,
+ 'i': true,
+ 'j': true,
+ 'k': true,
+ 'l': true,
+ 'm': true,
+ 'n': true,
+ 'o': true,
+ 'p': true,
+ 'q': true,
+ 'r': true,
+ 's': true,
+ 't': true,
+ 'u': true,
+ 'v': true,
+ 'w': true,
+ 'x': true,
+ 'y': true,
+ 'z': true,
+ '|': true,
+ '~': true,
+}
+
+func isToken(r rune) bool {
+ i := int(r)
+ return i < len(isTokenTable) && isTokenTable[i]
+}
+
+func isNotToken(r rune) bool {
+ return !isToken(r)
+}
+
+func isCookieNameValid(raw string) bool {
+ if raw == "" {
+ return false
+ }
+ return strings.IndexFunc(raw, isNotToken) < 0
+}
diff --git a/sessions.go b/sessions.go
index a4d019d..115f3ab 100644
--- a/sessions.go
+++ b/sessions.go
@@ -45,7 +45,10 @@ func NewSession(store Store, name string) *Session {
// Session stores the values and optional configuration for a session.
type Session struct {
- ID string
+ // The ID of the session, generated by stores. It should not be used for
+ // user data.
+ ID string
+ // Values contains the user-data for the session.
Values map[interface{}]interface{}
Options *Options
IsNew bool
@@ -139,6 +142,9 @@ type Registry struct {
//
// It returns a new session if there are no sessions registered for the name.
func (s *Registry) Get(store Store, name string) (session *Session, err error) {
+ if !isCookieNameValid(name) {
+ return nil, fmt.Errorf("sessions: invalid character in cookie name: %s", name)
+ }
if info, ok := s.sessions[name]; ok {
session, err = info.s, info.e
} else {
diff --git a/store.go b/store.go
index 74f4fe1..33b2e77 100644
--- a/store.go
+++ b/store.go
@@ -206,6 +206,14 @@ func (s *FilesystemStore) New(ctx echo.Context, name string) (*Session, error) {
// Save adds a single session to the response.
func (s *FilesystemStore) Save(ctx echo.Context,
session *Session) error {
+ // Delete if max-age is <= 0
+ if session.Options.MaxAge <= 0 {
+ if err := s.erase(session); err != nil {
+ return err
+ }
+ SetCookie(ctx, session.Name(), "", session.Options)
+ return nil
+ }
if len(session.ID) == 0 {
// Because the ID is used in the filename, encode it to
// use alphanumeric characters only.
@@ -225,6 +233,16 @@ func (s *FilesystemStore) Save(ctx echo.Context,
return nil
}
+// delete session file
+func (s *FilesystemStore) erase(session *Session) error {
+ filename := filepath.Join(s.path, "session_"+session.ID)
+ fileMutex.RLock()
+ defer fileMutex.RUnlock()
+
+ err := os.Remove(filename)
+ return err
+}
+
// MaxAge sets the maximum age for the store and the underlying cookie
// implementation. Individual sessions can be deleted by setting Options.MaxAge
// = -1 for that session.