Commit 0e287232 authored by 傅小黑's avatar 傅小黑

add comments for session packages, part 1

parent ab8f8d53
......@@ -11,12 +11,15 @@ import (
var cookiepder = &CookieProvider{}
// Cookie SessionStore
type CookieSessionStore struct {
sid string
values map[interface{}]interface{} //session data
values map[interface{}]interface{} // session data
lock sync.RWMutex
}
// Set value to cookie session.
// the value are encoded as gob with hash block string.
func (st *CookieSessionStore) Set(key, value interface{}) error {
st.lock.Lock()
defer st.lock.Unlock()
......@@ -24,6 +27,7 @@ func (st *CookieSessionStore) Set(key, value interface{}) error {
return nil
}
// Get value from cookie session
func (st *CookieSessionStore) Get(key interface{}) interface{} {
st.lock.RLock()
defer st.lock.RUnlock()
......@@ -35,6 +39,7 @@ func (st *CookieSessionStore) Get(key interface{}) interface{} {
return nil
}
// Delete value in cookie session
func (st *CookieSessionStore) Delete(key interface{}) error {
st.lock.Lock()
defer st.lock.Unlock()
......@@ -42,6 +47,7 @@ func (st *CookieSessionStore) Delete(key interface{}) error {
return nil
}
// Clean all values in cookie session
func (st *CookieSessionStore) Flush() error {
st.lock.Lock()
defer st.lock.Unlock()
......@@ -49,10 +55,12 @@ func (st *CookieSessionStore) Flush() error {
return nil
}
// Return id of this cookie session
func (st *CookieSessionStore) SessionID() string {
return st.sid
}
// Write cookie session to http response cookie
func (st *CookieSessionStore) SessionRelease(w http.ResponseWriter) {
str, err := encodeCookie(cookiepder.block,
cookiepder.config.SecurityKey,
......@@ -79,12 +87,21 @@ type cookieConfig struct {
Maxage int `json:"maxage"`
}
// Cookie session provider
type CookieProvider struct {
maxlifetime int64
config *cookieConfig
block cipher.Block
}
// Init cookie session provider with max lifetime and config json.
// maxlifetime is ignored.
// json config:
// securityKey - hash string
// blockKey - gob encode hash string. it's saved as aes crypto.
// securityName - recognized name in encoded cookie string
// cookieName - cookie name
// maxage - cookie max life time.
func (pder *CookieProvider) SessionInit(maxlifetime int64, config string) error {
pder.config = &cookieConfig{}
err := json.Unmarshal([]byte(config), pder.config)
......@@ -104,6 +121,8 @@ func (pder *CookieProvider) SessionInit(maxlifetime int64, config string) error
return nil
}
// Get SessionStore in cooke.
// decode cooke string to map and put into SessionStore with sid.
func (pder *CookieProvider) SessionRead(sid string) (SessionStore, error) {
maps, _ := decodeCookie(pder.block,
pder.config.SecurityKey,
......@@ -116,26 +135,32 @@ func (pder *CookieProvider) SessionRead(sid string) (SessionStore, error) {
return rs, nil
}
// Cookie session is always existed
func (pder *CookieProvider) SessionExist(sid string) bool {
return true
}
// Implement method, no used.
func (pder *CookieProvider) SessionRegenerate(oldsid, sid string) (SessionStore, error) {
return nil, nil
}
// Implement method, no used.
func (pder *CookieProvider) SessionDestroy(sid string) error {
return nil
}
// Implement method, no used.
func (pder *CookieProvider) SessionGC() {
return
}
// Implement method, return 0.
func (pder *CookieProvider) SessionAll() int {
return 0
}
// Implement method, no used.
func (pder *CookieProvider) SessionUpdate(sid string) error {
return nil
}
......
......@@ -18,6 +18,7 @@ var (
gcmaxlifetime int64
)
// File session store
type FileSessionStore struct {
f *os.File
sid string
......@@ -25,6 +26,7 @@ type FileSessionStore struct {
values map[interface{}]interface{}
}
// Set value to file session
func (fs *FileSessionStore) Set(key, value interface{}) error {
fs.lock.Lock()
defer fs.lock.Unlock()
......@@ -32,6 +34,7 @@ func (fs *FileSessionStore) Set(key, value interface{}) error {
return nil
}
// Get value from file session
func (fs *FileSessionStore) Get(key interface{}) interface{} {
fs.lock.RLock()
defer fs.lock.RUnlock()
......@@ -43,6 +46,7 @@ func (fs *FileSessionStore) Get(key interface{}) interface{} {
return nil
}
// Delete value in file session by given key
func (fs *FileSessionStore) Delete(key interface{}) error {
fs.lock.Lock()
defer fs.lock.Unlock()
......@@ -50,6 +54,7 @@ func (fs *FileSessionStore) Delete(key interface{}) error {
return nil
}
// Clean all values in file session
func (fs *FileSessionStore) Flush() error {
fs.lock.Lock()
defer fs.lock.Unlock()
......@@ -57,10 +62,12 @@ func (fs *FileSessionStore) Flush() error {
return nil
}
// Get file session store id
func (fs *FileSessionStore) SessionID() string {
return fs.sid
}
// Write file session to local file with Gob string
func (fs *FileSessionStore) SessionRelease(w http.ResponseWriter) {
defer fs.f.Close()
b, err := encodeGob(fs.values)
......@@ -72,17 +79,23 @@ func (fs *FileSessionStore) SessionRelease(w http.ResponseWriter) {
fs.f.Write(b)
}
// File session provider
type FileProvider struct {
maxlifetime int64
savePath string
}
// Init file session provider.
// savePath sets the session files path.
func (fp *FileProvider) SessionInit(maxlifetime int64, savePath string) error {
fp.maxlifetime = maxlifetime
fp.savePath = savePath
return nil
}
// Read file session by sid.
// if file is not exist, create it.
// the file path is generated from sid string.
func (fp *FileProvider) SessionRead(sid string) (SessionStore, error) {
err := os.MkdirAll(path.Join(fp.savePath, string(sid[0]), string(sid[1])), 0777)
if err != nil {
......@@ -117,6 +130,8 @@ func (fp *FileProvider) SessionRead(sid string) (SessionStore, error) {
return ss, nil
}
// Check file session exist.
// it checkes the file named from sid exist or not.
func (fp *FileProvider) SessionExist(sid string) bool {
_, err := os.Stat(path.Join(fp.savePath, string(sid[0]), string(sid[1]), sid))
if err == nil {
......@@ -126,16 +141,20 @@ func (fp *FileProvider) SessionExist(sid string) bool {
}
}
// Remove all files in this save path
func (fp *FileProvider) SessionDestroy(sid string) error {
os.Remove(path.Join(fp.savePath))
return nil
}
// Recycle files in save path
func (fp *FileProvider) SessionGC() {
gcmaxlifetime = fp.maxlifetime
filepath.Walk(fp.savePath, gcpath)
}
// Get active file session number.
// it walks save path to count files.
func (fp *FileProvider) SessionAll() int {
a := &activeSession{}
err := filepath.Walk(fp.savePath, func(path string, f os.FileInfo, err error) error {
......@@ -148,6 +167,8 @@ func (fp *FileProvider) SessionAll() int {
return a.total
}
// Generate new sid for file session.
// it delete old file and create new file named from new sid.
func (fp *FileProvider) SessionRegenerate(oldsid, sid string) (SessionStore, error) {
err := os.MkdirAll(path.Join(fp.savePath, string(oldsid[0]), string(oldsid[1])), 0777)
if err != nil {
......@@ -197,6 +218,7 @@ func (fp *FileProvider) SessionRegenerate(oldsid, sid string) (SessionStore, err
return ss, nil
}
// remove file in save path if expired
func gcpath(path string, info os.FileInfo, err error) error {
if err != nil {
return err
......
......@@ -14,6 +14,7 @@ import (
"time"
)
// SessionStore contains all data for one session process with specific id.
type SessionStore interface {
Set(key, value interface{}) error //set session value
Get(key interface{}) interface{} //get session value
......@@ -23,6 +24,8 @@ type SessionStore interface {
Flush() error //delete all data
}
// Provider contains global session methods and saved SessionStores.
// it can operate a SessionStore by its id.
type Provider interface {
SessionInit(gclifetime int64, config string) error
SessionRead(sid string) (SessionStore, error)
......@@ -61,16 +64,24 @@ type managerConfig struct {
ProviderConfig string `json:"providerConfig"`
}
// Manager contains Provider and its configuration.
type Manager struct {
provider Provider
config *managerConfig
}
//options
//1. is https default false
//2. hashfunc default sha1
//3. hashkey default beegosessionkey
//4. maxage default is none
// Create new Manager with provider name and json config string.
// provider name:
// 1. cookie
// 2. file
// 3. memory
// 4. redis
// 5. mysql
// json config:
// 1. is https default false
// 2. hashfunc default sha1
// 3. hashkey default beegosessionkey
// 4. maxage default is none
func NewManager(provideName, config string) (*Manager, error) {
provider, ok := provides[provideName]
if !ok {
......@@ -102,7 +113,8 @@ func NewManager(provideName, config string) (*Manager, error) {
}, nil
}
//get Session
// Start session. generate or read the session id from http request.
// if session id exists, return SessionStore with this id.
func (manager *Manager) SessionStart(w http.ResponseWriter, r *http.Request) (session SessionStore) {
cookie, err := r.Cookie(manager.config.CookieName)
if err != nil || cookie.Value == "" {
......@@ -144,7 +156,7 @@ func (manager *Manager) SessionStart(w http.ResponseWriter, r *http.Request) (se
return
}
//Destroy sessionid
// Destroy session by its id in http request cookie.
func (manager *Manager) SessionDestroy(w http.ResponseWriter, r *http.Request) {
cookie, err := r.Cookie(manager.config.CookieName)
if err != nil || cookie.Value == "" {
......@@ -161,16 +173,20 @@ func (manager *Manager) SessionDestroy(w http.ResponseWriter, r *http.Request) {
}
}
// Get SessionStore by its id.
func (manager *Manager) GetProvider(sid string) (sessions SessionStore, err error) {
sessions, err = manager.provider.SessionRead(sid)
return
}
// Start session gc process.
// it can do gc in times after gc lifetime.
func (manager *Manager) GC() {
manager.provider.SessionGC()
time.AfterFunc(time.Duration(manager.config.Gclifetime)*time.Second, func() { manager.GC() })
}
// Regenerate a session id for this SessionStore who's id is saving in http request.
func (manager *Manager) SessionRegenerateId(w http.ResponseWriter, r *http.Request) (session SessionStore) {
sid := manager.sessionId(r)
cookie, err := r.Cookie(manager.config.CookieName)
......@@ -198,20 +214,23 @@ func (manager *Manager) SessionRegenerateId(w http.ResponseWriter, r *http.Reque
return
}
// Get all active sessions count number.
func (manager *Manager) GetActiveSession() int {
return manager.provider.SessionAll()
}
// Set hash function for generating session id.
func (manager *Manager) SetHashFunc(hasfunc, hashkey string) {
manager.config.SessionIDHashFunc = hasfunc
manager.config.SessionIDHashKey = hashkey
}
// Set cookie with https.
func (manager *Manager) SetSecure(secure bool) {
manager.config.Secure = secure
}
//remote_addr cruunixnano randdata
// generate session id with rand string, unix nano time, remote addr by hash function.
func (manager *Manager) sessionId(r *http.Request) (sid string) {
bs := make([]byte, 24)
if _, err := io.ReadFull(rand.Reader, bs); err != nil {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment