123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- package sessions
- import (
- "crypto/sha1"
- "encoding/json"
- "errors"
- "fmt"
- "math/rand"
- "net/http"
- "os"
- "strconv"
- "time"
- )
- type Vars struct {
- Int map[string]int
- String map[string]string
- Bool map[string]bool
- }
- type Session struct {
- W *http.ResponseWriter
- R *http.Request
- VHost string
- DirVHostHome string
- RemoteIp string
- vars *Vars
- ident string
- changed bool
- }
- func New(w *http.ResponseWriter, r *http.Request, vhost string, vhosthome string, remoteip string) *Session {
- return &Session{w, r, vhost, vhosthome, remoteip, &Vars{}, "", false}
- }
- func (this *Session) Load() {
- var session, err = this.R.Cookie("fsession")
- if err == nil && len(session.Value) == 40 {
- // Load session
- this.ident = session.Value
- StartNewSession := true
- fsessfile := this.DirVHostHome + "/tmp/" + this.ident
- file, ferr := os.Open(fsessfile)
- if ferr == nil {
- defer file.Close()
- dec := json.NewDecoder(file)
- ferr = dec.Decode(&this.vars)
- if ferr == nil {
- StartNewSession = false
- }
- }
- if StartNewSession {
- sessdata := Vars{}
- sessdata.Int = map[string]int{}
- sessdata.String = map[string]string{}
- sessdata.Bool = map[string]bool{}
- this.vars = &sessdata
- this.changed = true
- }
- } else {
- // Create new session
- // Generate unique hash
- rand.Seed(time.Now().Unix())
- rnd := rand.Intn(9999999-99) + 99
- userstr := this.VHost + this.RemoteIp + this.R.Header.Get("User-Agent") +
- strconv.FormatInt((int64(time.Now().Unix())), 10) +
- strconv.FormatInt(int64(rnd), 10)
- userhashstr := fmt.Sprintf("%x", sha1.Sum([]byte(userstr)))
- this.ident = userhashstr
- // Try to create session file
- sessdata := Vars{}
- sessdata.Int = map[string]int{}
- sessdata.String = map[string]string{}
- sessdata.Bool = map[string]bool{}
- this.vars = &sessdata
- this.changed = true
- // Set session cookie
- expiration := time.Now().Add(365 * 24 * time.Hour)
- cookie := http.Cookie{
- Name: "fsession",
- Value: userhashstr,
- Path: "/",
- Expires: expiration,
- HttpOnly: true,
- }
- http.SetCookie(*this.W, &cookie)
- }
- }
- func (this *Session) Save() bool {
- if !this.changed {
- return false
- }
- fsessfile := this.DirVHostHome + "/tmp/" + this.ident
- r, err := json.Marshal(this.vars)
- if err == nil {
- file, ferr := os.Create(fsessfile)
- if ferr == nil {
- defer file.Close()
- _, ferr = file.Write(r)
- if ferr == nil {
- this.changed = false
- return true
- }
- }
- }
- return false
- }
- func (this *Session) IsSetInt(name string) bool {
- if _, ok := this.vars.Int[name]; ok {
- return true
- } else {
- return false
- }
- }
- func (this *Session) IsSetString(name string) bool {
- if _, ok := this.vars.String[name]; ok {
- return true
- } else {
- return false
- }
- }
- func (this *Session) IsSetBool(name string) bool {
- if _, ok := this.vars.Bool[name]; ok {
- return true
- } else {
- return false
- }
- }
- func (this *Session) SetInt(name string, value int) {
- this.vars.Int[name] = value
- this.changed = true
- }
- func (this *Session) SetString(name string, value string) {
- this.vars.String[name] = value
- this.changed = true
- }
- func (this *Session) SetBool(name string, value bool) {
- this.vars.Bool[name] = value
- this.changed = true
- }
- func (this *Session) GetInt(name string) (int, error) {
- if this.IsSetInt(name) {
- return this.vars.Int[name], nil
- } else {
- return 0, errors.New("Variable is not found")
- }
- }
- func (this *Session) GetString(name string) (string, error) {
- if this.IsSetString(name) {
- return this.vars.String[name], nil
- } else {
- return "", errors.New("Variable is not found")
- }
- }
- func (this *Session) GetBool(name string) (bool, error) {
- if this.IsSetBool(name) {
- return this.vars.Bool[name], nil
- } else {
- return false, errors.New("Variable is not found")
- }
- }
- func (this *Session) GetIntDef(name string, def int) int {
- if this.IsSetInt(name) {
- return this.vars.Int[name]
- } else {
- return def
- }
- }
- func (this *Session) GetStringDef(name string, def string) string {
- if this.IsSetString(name) {
- return this.vars.String[name]
- } else {
- return def
- }
- }
- func (this *Session) GetBoolDef(name string, def bool) bool {
- if this.IsSetBool(name) {
- return this.vars.Bool[name]
- } else {
- return def
- }
- }
- func (this *Session) DelInt(name string) {
- if this.IsSetInt(name) {
- delete(this.vars.Int, name)
- this.changed = true
- }
- }
- func (this *Session) DelString(name string) {
- if this.IsSetString(name) {
- delete(this.vars.String, name)
- this.changed = true
- }
- }
- func (this *Session) DelBool(name string) {
- if this.IsSetBool(name) {
- delete(this.vars.Bool, name)
- this.changed = true
- }
- }
|