PageRenderTime 27ms CodeModel.GetById 15ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

/session.go

http://github.com/TheOnly92/bloody.go
Go | 134 lines | 119 code | 14 blank | 1 comment | 21 complexity | d1ed48cbd03800f477dcec1cb5756922 MD5 | raw file
  1package session
  2
  3import (
  4	"crypto/sha1"
  5	"http"
  6	"time"
  7	"hash"
  8	"web"
  9	"launchpad.net/mgo"
 10	"launchpad.net/gobson/bson"
 11	"encoding/hex"
 12	"json"
 13	"strconv"
 14)
 15
 16type Session struct {
 17	id		string
 18	old_id	string
 19	Data	map[string]interface{}
 20	handler	*MHandler
 21}
 22
 23func Start(ctx *web.Context, handler *MHandler) *Session {
 24	session := new(Session)
 25	session.handler = handler
 26	session.handler.Clean()
 27	old := false
 28	if ctx.Cookies != nil {
 29		if id, exists := ctx.Cookies["bloody_sess"]; exists {
 30			session.id = id
 31			old = true
 32		}
 33	}
 34	if !old {
 35		// Starts new session
 36		session.generateId()
 37		session.handler.Store(session.GetID(), nil)
 38	}
 39	rt := session.handler.Retrieve(session.GetID())
 40	json.Unmarshal(rt.SessionData, &session.Data)
 41	if session.Data == nil {
 42		t := make(map[string]interface{})
 43		session.Data = t
 44	}
 45	ctx.SetCookie("bloody_sess", session.GetID(), time.LocalTime().Seconds() + 3600)
 46	return session
 47}
 48
 49func (session *Session) Save() {
 50	session.handler.Store(session.id, session.Data)
 51}
 52
 53func (session *Session) generateId() string {
 54	var header = make(http.Header)
 55	remoteAddr := header.Get("REMOTE_ADDR")
 56	t := time.LocalTime()
 57	var h hash.Hash = sha1.New()
 58	h.Write([]byte(remoteAddr+strconv.Itoa64(t.Seconds())))
 59	session.id = hex.EncodeToString(h.Sum())
 60	return session.id
 61}
 62
 63func (session *Session) GetID() string {
 64	return session.id
 65}
 66
 67func (session *Session) SetID(id string) {
 68	session.id = id
 69}
 70
 71type MHandler struct {
 72	session		*mgo.Session
 73}
 74
 75type sessionRow struct {
 76	SessionID		string
 77	ExpirationTS	int64
 78	SessionData		[]byte
 79}
 80
 81func (handler *MHandler) Store(id string, data map[string]interface{}) {
 82	c := handler.session.DB("bloody").C("sessions")
 83	t := time.LocalTime()
 84	b, _ := json.Marshal(data)
 85	var sav sessionRow
 86	sav.SessionID = id
 87	sav.ExpirationTS = t.Seconds()+1440
 88	sav.SessionData = b
 89	err := c.Update(bson.M{"sessionid": id}, sav)
 90	if err != nil {
 91		if err == mgo.NotFound {
 92			err = c.Insert(&sessionRow{id, t.Seconds()+1440, b})
 93			if err != nil {
 94				panic(err)
 95			}
 96		} else {
 97			panic(err)
 98		}
 99	}
100}
101
102func (handler *MHandler) Clean() {
103	c := handler.session.DB("bloody").C("sessions")
104	t := time.LocalTime()
105	err := c.RemoveAll(bson.M{"expirationts": bson.M{"$lt":t.Seconds()}})
106	if err != nil {
107		panic(err)
108	}
109}
110
111func (handler *MHandler) Remove(id string) {
112	c := handler.session.DB("bloody").C("sessions")
113	err := c.Remove(bson.M{"sessionid": id})
114	if err != nil {
115		panic(err)
116	}
117}
118
119func (handler *MHandler) Retrieve(id string) *sessionRow {
120	var rt sessionRow
121	c := handler.session.DB("bloody").C("sessions")
122	err := c.Find(bson.M{"sessionid": id}).One(&rt)
123	if err != nil {
124		if err == mgo.NotFound {
125			return &sessionRow{id,0,nil}
126		}
127		panic(err)
128	}
129	return &rt
130}
131
132func (handler *MHandler) SetSession(mSession *mgo.Session) {
133	handler.session = mSession
134}