package httpsession import ( "log" "net/http" "sync" "time" ) const ( DefaultMaxAge = 30 * time.Minute ) var Domain string = "" type Manager struct { store Store maxAge time.Duration Path string generator IdGenerator transfer Transfer beforeReleaseListeners map[BeforeReleaseListener]bool afterCreatedListeners map[AfterCreatedListener]bool lock sync.Mutex } func Default() *Manager { log.Println("IsRedisSessionStore", IsRedisSessionStore) if IsRedisSessionStore { store := NewRedisStore(DefaultMaxAge) key := string(GenRandKey(16)) return NewManager(store, NewSha1Generator(key), NewCookieTransfer("SESSIONID", DefaultMaxAge, false, "/", Domain)) } else { store := NewMemoryStore(DefaultMaxAge) key := string(GenRandKey(16)) return NewManager(store, NewSha1Generator(key), NewCookieTransfer("SESSIONID", DefaultMaxAge, false, "/", Domain)) } } func NewManager(store Store, gen IdGenerator, transfer Transfer) *Manager { return &Manager{ store: store, generator: gen, transfer: transfer, } } func (manager *Manager) SetMaxAge(maxAge time.Duration) { manager.maxAge = maxAge manager.transfer.SetMaxAge(maxAge) manager.store.SetMaxAge(maxAge) } func (manager *Manager) Session(req *http.Request, rw http.ResponseWriter) *Session { manager.lock.Lock() defer manager.lock.Unlock() id, err := manager.transfer.Get(req) if err != nil { // TODO: println("error:", err.Error()) return nil } if !manager.generator.IsValid(id) { id = manager.generator.Gen(req) manager.transfer.Set(req, rw, id) manager.store.Add(id) session := NewSession(id, manager.maxAge, manager) session.Set("Lock", &sync.Mutex{}) // is exist? manager.afterCreated(session) return session } else { cookie, _ := req.Cookie(manager.transfer.(*CookieTransfer).Name) cookie.Path = "/" cookie.Secure = false cookie.Domain = manager.transfer.(*CookieTransfer).Domain cookie.MaxAge = int(manager.transfer.(*CookieTransfer).MaxAge / time.Second) http.SetCookie(rw, cookie) } session := NewSession(id, manager.maxAge, manager) // if session.Get("Lock") == nil { // session.Set("Lock", &sync.Mutex{}) // } return session } func (manager *Manager) Invalidate(rw http.ResponseWriter, session *Session) { manager.beforeReleased(session) manager.store.Clear(session.id) manager.transfer.Clear(rw) } //add 2017-7-30 func (manager *Manager) IsValidSession(id string) bool { return manager.store.Exist(Id(id)) } func (manager *Manager) afterCreated(session *Session) { for listener, _ := range manager.afterCreatedListeners { listener.OnAfterCreated(session) } } func (manager *Manager) beforeReleased(session *Session) { for listener, _ := range manager.beforeReleaseListeners { listener.OnBeforeRelease(session) } } func (manager *Manager) Run() error { return manager.store.Run() }