123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- package sessions
- import (
- "crypto/sha1"
- "encoding/json"
- "errors"
- "fmt"
- "math/rand"
- "net/http"
- "os"
- "strconv"
- "time"
- )
- type Vars struct {
- FInt map[string]int
- FString map[string]string
- FBool map[string]bool
- }
- type Session struct {
- w *http.ResponseWriter
- r *http.Request
- vhost string
- vhosthome string
- remoteip string
- vars *Vars
- Ident string
- }
- func New(w *http.ResponseWriter, r *http.Request, vhost string, vhosthome string, remoteip string) *Session {
- return &Session{w, r, vhost, vhosthome, remoteip, &Vars{}, ""}
- }
- func (s *Session) Load() {
- var session, err = s.r.Cookie("fsession")
- if err == nil && len(session.Value) == 40 {
- // Load session
- s.Ident = session.Value
- StartNewSession := true
- fsessfile := s.vhosthome + "/tmp/" + s.Ident
- file, ferr := os.Open(fsessfile)
- if ferr == nil {
- defer file.Close()
- dec := json.NewDecoder(file)
- ferr = dec.Decode(&s.vars)
- if ferr == nil {
- StartNewSession = false
- }
- }
- if StartNewSession {
- sessdata := Vars{}
- sessdata.FInt = map[string]int{}
- sessdata.FString = map[string]string{}
- sessdata.FBool = map[string]bool{}
- s.vars = &sessdata
- }
- } else {
- // Create new session
- // Generate unique hash
- rand.Seed(time.Now().Unix())
- rnd := rand.Intn(9999999-99) + 99
- userstr := s.vhost + s.remoteip + s.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)))
- s.Ident = userhashstr
- // Try to create session file
- sessdata := Vars{}
- sessdata.FInt = map[string]int{}
- sessdata.FString = map[string]string{}
- sessdata.FBool = map[string]bool{}
- s.vars = &sessdata
- // Set session cookie
- expiration := time.Now().Add(365 * 24 * time.Hour)
- cookie := http.Cookie{Name: "fsession", Value: userhashstr, Expires: expiration}
- http.SetCookie(*s.w, &cookie)
- }
- }
- func (s *Session) Save() bool {
- // TODO: Save session to file only if any var was modified
- fsessfile := s.vhosthome + "/tmp/" + s.Ident
- r, err := json.Marshal(s.vars)
- if err == nil {
- file, ferr := os.Create(fsessfile)
- if ferr == nil {
- defer file.Close()
- _, ferr = file.WriteString(string(r))
- return true
- }
- }
- return false
- }
- func (s *Session) IsSetInt(name string) bool {
- if _, ok := s.vars.FInt[name]; ok {
- return true
- } else {
- return false
- }
- }
- func (s *Session) IsSetString(name string) bool {
- if _, ok := s.vars.FString[name]; ok {
- return true
- } else {
- return false
- }
- }
- func (s *Session) IsSetBool(name string) bool {
- if _, ok := s.vars.FBool[name]; ok {
- return true
- } else {
- return false
- }
- }
- func (s *Session) SetInt(name string, value int) {
- s.vars.FInt[name] = value
- }
- func (s *Session) SetString(name string, value string) {
- s.vars.FString[name] = value
- }
- func (s *Session) SetBool(name string, value bool) {
- s.vars.FBool[name] = value
- }
- func (s *Session) GetInt(name string) (int, error) {
- if s.IsSetInt(name) {
- return s.vars.FInt[name], nil
- } else {
- return 0, errors.New("Variable is not found")
- }
- }
- func (s *Session) GetString(name string) (string, error) {
- if s.IsSetString(name) {
- return s.vars.FString[name], nil
- } else {
- return "", errors.New("Variable is not found")
- }
- }
- func (s *Session) GetBool(name string) (bool, error) {
- if s.IsSetBool(name) {
- return s.vars.FBool[name], nil
- } else {
- return false, errors.New("Variable is not found")
- }
- }
- func (s *Session) DelInt(name string) {
- if s.IsSetInt(name) {
- delete(s.vars.FInt, name)
- }
- }
- func (s *Session) DelString(name string) {
- if s.IsSetString(name) {
- delete(s.vars.FString, name)
- }
- }
- func (s *Session) DelBool(name string) {
- if s.IsSetBool(name) {
- delete(s.vars.FBool, name)
- }
- }
|