From 67899843326615eb013a1549755bb5b12bef2e70 Mon Sep 17 00:00:00 2001 From: Wenhui Shen Date: Fri, 21 Apr 2017 23:53:14 +0800 Subject: [PATCH] update --- .vscode/temp.sql | 0 lex.go | 102 +++++++++++++++++++++++++++++++++++++++++++++++ sessions.go | 8 +++- store.go | 18 +++++++++ 4 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 .vscode/temp.sql create mode 100644 lex.go diff --git a/.vscode/temp.sql b/.vscode/temp.sql new file mode 100644 index 0000000..e69de29 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.