main
// main project main.go package main import ( "fmt" "html/template" "log" "net/http" "strings" "session" _"memory" "time" ) func sayHelloName(w http.ResponseWriter,r *http.Request) { r.ParseForm() fmt.Println(r.Form) fmt.Println(r.URL.Path) fmt.Println(r.URL.Scheme) fmt.Println(r.Form["url_long"]) for k,v := range r.Form { fmt.Println("key: ",k) fmt.Println("value:",strings.Join(v,"")) } fmt.Fprintln(w,"hello nihao") } func login(w http.ResponseWriter,r *http.Request) { r.ParseForm() fmt.Println("method: ",r.Method) if r.Method == "GET" { t,err := template.ParseFiles("src/html/login.gtpl") if err != nil { fmt.Println(err) return } t.Execute(w,nil) } else { fmt.Println("username: ",r.Form["username"]) fmt.Println("password: ",r.Form["password"]) } } func login2(w http.ResponseWriter,r *http.Request) { sess := globalSessions.SessionStart(w,r) r.ParseForm() if r.Method == "GET" { t,_ := template.ParseFiles("src/html/login.gtpl") //w.Header().Set("Content-Type","text/html") t.Execute(w,sess.Get("username")) } else { sess.Set("username",r.Form["username"]) http.Redirect(w,r,"/",302) } } func count(w http.ResponseWriter,r) createtime := sess.Get("createtime") if createtime == nil { sess.Set("createtime",time.Now().Unix()) } else if (createtime.(int64) + 360) < (time.Now().Unix()) { globalSessions.SessionDestroy(w,r) sess = globalSessions.SessionStart(w,r) } ct := sess.Get("countnum") if ct == nil { sess.Set("countnum",1) } else { sess.Set("countnum",(ct.(int) + 1)) } t,_ := template.ParseFiles("count.gtpl") w.Header().Set("Content-Type","text/html") t.Execute(w,sess.Get("countnum")) } func main() { //http.HandleFunc("/",sayHelloName); http.HandleFunc("/login",login) http.HandleFunc("/login2",login2) err := http.ListenAndServe(":9090",nil) if err != nil { log.Fatalf("Listen and server",err) } } var globalSessions *session.Manager func init() { globalSessions,_ = session.NewSessionManager("memory","goSessionid",3600) go globalSessions.GC() fmt.Println("fd") }
session
package session import ( "crypto/rand" "encoding/base64" "fmt" "io" "net/http" "net/url" "sync" "time" ) type Manager struct { cookieName string lock sync.Mutex provider Provider maxLifeTime int64 } type Provider interface { SessionInit(sid string) (Session,error) SessionRead(sid string) (Session,error) SessionDestroy(sid string) error SessionGC(maxLifeTime int64) } type Session interface { Set(key,value interface{}) error Get(key interface{}) interface{} Delete(ket interface{}) error SessionID() string } func NewSessionManager(provideName,cookieName string,maxLifeTime int64) (*Manager,error) { provide,ok := provides[provideName] if !ok { return nil,fmt.Errorf("session: unknown provide %q (forgotten import?",provideName) } return &Manager{cookieName: cookieName,provider: provide,maxLifeTime: maxLifeTime},nil } func Register(name string,provide Provider) { if provide == nil { panic("session: Register provide is nil") } if _,dup := provides[name]; dup { panic("session: Register called twice for provide " + name) } provides[name] = provide } var provides = make(map[string]Provider) func (manager *Manager) sessionId() string { b := make([]byte,32) if _,err := io.ReadFull(rand.Reader,b); err != nil { return "" } return base64.URLEncoding.EncodeToString(b) } func (manager *Manager) SessionStart(w http.ResponseWriter,r *http.Request) (session Session) { manager.lock.Lock() defer manager.lock.Unlock() cookie,err := r.Cookie(manager.cookieName) if err != nil || cookie.Value == "" { sid := manager.sessionId() session,_ = manager.provider.SessionInit(sid) cookie := http.Cookie{Name: manager.cookieName,Value: url.QueryEscape(sid),Path: "/",HttpOnly: true,MaxAge: int(manager.maxLifeTime)} http.SetCookie(w,&cookie) } else { sid,_ := url.QueryUnescape(cookie.Value) session,_ = manager.provider.SessionRead(sid) } return session } func (manager *Manager) SessionDestroy(w http.ResponseWriter,r *http.Request){ cookie,err := r.Cookie(manager.cookieName) if err != nil || cookie.Value == "" { return } else { manager.lock.Lock() defer manager.lock.Unlock() manager.provider.SessionDestroy(cookie.Value) expiration := time.Now() cookie := http.Cookie{Name: manager.cookieName,Expires: expiration,MaxAge: -1} http.SetCookie(w,&cookie) } } func (manager *Manager) GC() { manager.lock.Lock() defer manager.lock.Unlock() manager.provider.SessionGC(manager.maxLifeTime) time.AfterFunc(time.Duration(manager.maxLifeTime),func(){ manager.GC() }) }
memory
package memory import ( "container/list" "time" "sync" "fmt" "session" ) type SessionStore struct { sid string //session id 唯一标示 timeAccessed time.Time //最后访问时间 value map[interface{}]interface{} //session 里面存储的值 } func (st *SessionStore) Set(key,value interface{}) error { st.value[key] = value pder.SessionUpdate(st.sid) return nil } func (st *SessionStore) Get(key interface{}) interface{} { pder.SessionUpdate(st.sid) if v,ok := st.value[key]; ok { return v } else { return nil } return nil } func (st *SessionStore) Delete(key interface{}) error { delete(st.value,key) pder.SessionUpdate(st.sid) return nil } func (st *SessionStore) SessionID() string { return st.sid } type Provider struct { lock sync.Mutex //用来锁 sessions map[string]*list.Element //用来存储在内存 list *list.List //用来做 gc } func (provider *Provider) SessionInit(sid string) (session.Session,error) { provider.lock.Lock() defer provider.lock.Unlock() v := make(map[interface{}]interface{},0) newsess := &SessionStore{sid: sid,timeAccessed: time.Now(),value: v} element := provider.list.PushBack(newsess) provider.sessions[sid] = element return newsess,nil } func (provider *Provider) SessionRead(sid string) (session.Session,error) { if element,ok := provider.sessions[sid]; ok { return element.Value.(*SessionStore),nil } else { sess,err := provider.SessionInit(sid) return sess,err } return nil,nil } func (provider *Provider) SessionDestroy(sid string) error { if element,ok := provider.sessions[sid]; ok { delete(provider.sessions,sid) provider.list.Remove(element) return nil } return nil } func (provider *Provider) SessionGC(maxLifeTime int64) { provider.lock.Lock() defer provider.lock.Unlock() for { element := provider.list.Back() if element == nil { break } if (element.Value.(*SessionStore).timeAccessed.Unix() + maxLifeTime) < time.Now().Unix() { provider.list.Remove(element) delete(provider.sessions,element.Value.(*SessionStore).sid) } else { break } } } func (provider *Provider) SessionUpdate(sid string) error { provider.lock.Lock() defer provider.lock.Unlock() if element,ok := provider.sessions[sid]; ok { element.Value.(*SessionStore).timeAccessed = time.Now() provider.list.MoveToFront(element) return nil } return nil } var pder = &Provider{list: list.New()} func init() { pder.sessions = make(map[string]*list.Element,0) session.Register("memory",pder) fmt.Println("wzz") }原文链接:https://www.f2er.com/go/189442.html