From 348de02780f952e7a3d875e6c44b66e4dda6b81e Mon Sep 17 00:00:00 2001 From: Volodymyr Tkach Date: Tue, 28 Jun 2022 03:10:24 +0300 Subject: [PATCH] Return error on init --- README.md | 9 ++++++-- main.go | 9 ++++++-- session/session.go | 42 +++++++++++++++++++++++----------- session/session_test.go | 50 ++++++++++++++++++++--------------------- 4 files changed, 68 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index 5600da8..bdfcd8f 100644 --- a/README.md +++ b/README.md @@ -20,8 +20,13 @@ import ( func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - // Init session - sess := session.New(w, r, "./tmp") + // Create new or load saved session + var sess *session.Session + var err error + sess, err = session.New(w, r, "./tmp") + if err != nil { + fmt.Printf("%s\n", err.Error()) + } defer sess.Close() if r.URL.Path == "/" { diff --git a/main.go b/main.go index 7f99c32..59009e6 100644 --- a/main.go +++ b/main.go @@ -9,8 +9,13 @@ import ( func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - // Init session - sess := session.New(w, r, "./tmp") + // Create new or load saved session + var sess *session.Session + var err error + sess, err = session.New(w, r, "./tmp") + if err != nil { + fmt.Printf("%s\n", err.Error()) + } defer sess.Close() if r.URL.Path == "/" { diff --git a/session/session.go b/session/session.go index 52f1461..7c4056d 100644 --- a/session/session.go +++ b/session/session.go @@ -4,6 +4,7 @@ import ( "crypto/sha1" "encoding/json" "fmt" + "io/fs" "math/rand" "net/http" "os" @@ -29,8 +30,9 @@ type Session struct { hash string } -// New to create new session -func New(w http.ResponseWriter, r *http.Request, tmpdir string) *Session { +// New to create new or load saved session, +// returns error if can't load saved session +func New(w http.ResponseWriter, r *http.Request, tmpdir string) (*Session, error) { s := Session{ w: w, r: r, @@ -50,16 +52,30 @@ func New(w http.ResponseWriter, r *http.Request, tmpdir string) *Session { // Load from file s.hash = cookie.Value fname := strings.Join([]string{s.tmpdir, s.hash}, string(os.PathSeparator)) - if f, err := os.Open(fname); err == nil { - defer f.Close() - dec := json.NewDecoder(f) - if err := dec.Decode(&s.varlist); err == nil { - // Update file last modify time - if info, err := os.Stat(fname); err == nil { - if time.Since(info.ModTime()) > 30*time.Minute { - _ = os.Chtimes(fname, time.Now(), time.Now()) - } - } + var f *os.File + f, err = os.Open(fname) + if err != nil { + return &s, err + } + defer f.Close() + + dec := json.NewDecoder(f) + err = dec.Decode(&s.varlist) + if err != nil { + return &s, err + } + + // Update file last modify time + + var info fs.FileInfo + info, err = os.Stat(fname) + if err != nil { + return &s, err + } + + if time.Since(info.ModTime()) > 30*time.Minute { + if err := os.Chtimes(fname, time.Now(), time.Now()); err != nil { + return &s, err } } } else { @@ -86,7 +102,7 @@ func New(w http.ResponseWriter, r *http.Request, tmpdir string) *Session { }) } - return &s + return &s, nil } // Close to close session and save data to local file diff --git a/session/session_test.go b/session/session_test.go index 70897ae..2fd80cc 100644 --- a/session/session_test.go +++ b/session/session_test.go @@ -20,7 +20,7 @@ func TestSessionBool(t *testing.T) { request.Header.Set("Cookie", "session="+SessionId) recorder := httptest.NewRecorder() http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - sess := New(w, r, "./../tmp") + sess, _ := New(w, r, "./../tmp") defer sess.Close() if r.URL.Path == "/isset" { if _, err := w.Write([]byte(fmt.Sprintf("%v", sess.IsSetBool("some_bool")))); err != nil { @@ -44,7 +44,7 @@ func TestSessionBool(t *testing.T) { } recorder = httptest.NewRecorder() http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - sess := New(w, r, "./../tmp") + sess, _ := New(w, r, "./../tmp") defer sess.Close() if r.URL.Path == "/set" { sess.SetBool("some_bool", true) @@ -75,7 +75,7 @@ func TestSessionBool(t *testing.T) { request.Header.Set("Cookie", "session="+SessionId) recorder = httptest.NewRecorder() http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - sess := New(w, r, "./../tmp") + sess, _ := New(w, r, "./../tmp") defer sess.Close() if r.URL.Path == "/get" { if _, err := w.Write([]byte(fmt.Sprintf("%v", sess.GetBool("some_bool", false)))); err != nil { @@ -100,7 +100,7 @@ func TestSessionBool(t *testing.T) { request.Header.Set("Cookie", "session="+SessionId) recorder = httptest.NewRecorder() http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - sess := New(w, r, "./../tmp") + sess, _ := New(w, r, "./../tmp") defer sess.Close() if r.URL.Path == "/isset" { if _, err := w.Write([]byte(fmt.Sprintf("%v", sess.IsSetBool("some_bool")))); err != nil { @@ -125,7 +125,7 @@ func TestSessionBool(t *testing.T) { request.Header.Set("Cookie", "session="+SessionId) recorder = httptest.NewRecorder() http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - sess := New(w, r, "./../tmp") + sess, _ := New(w, r, "./../tmp") defer sess.Close() if r.URL.Path == "/del" { sess.DelBool("some_bool") @@ -153,7 +153,7 @@ func TestSessionInt(t *testing.T) { request.Header.Set("Cookie", "session="+SessionId) recorder := httptest.NewRecorder() http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - sess := New(w, r, "./../tmp") + sess, _ := New(w, r, "./../tmp") defer sess.Close() if r.URL.Path == "/isset" { if _, err := w.Write([]byte(fmt.Sprintf("%v", sess.IsSetInt("some_int")))); err != nil { @@ -178,7 +178,7 @@ func TestSessionInt(t *testing.T) { request.Header.Set("Cookie", "session="+SessionId) recorder = httptest.NewRecorder() http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - sess := New(w, r, "./../tmp") + sess, _ := New(w, r, "./../tmp") defer sess.Close() if r.URL.Path == "/set" { sess.SetInt("some_int", 5) @@ -209,7 +209,7 @@ func TestSessionInt(t *testing.T) { request.Header.Set("Cookie", "session="+SessionId) recorder = httptest.NewRecorder() http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - sess := New(w, r, "./../tmp") + sess, _ := New(w, r, "./../tmp") defer sess.Close() if r.URL.Path == "/get" { if _, err := w.Write([]byte(fmt.Sprintf("%d", sess.GetInt("some_int", 0)))); err != nil { @@ -234,7 +234,7 @@ func TestSessionInt(t *testing.T) { request.Header.Set("Cookie", "session="+SessionId) recorder = httptest.NewRecorder() http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - sess := New(w, r, "./../tmp") + sess, _ := New(w, r, "./../tmp") defer sess.Close() if r.URL.Path == "/isset" { if _, err := w.Write([]byte(fmt.Sprintf("%v", sess.IsSetInt("some_int")))); err != nil { @@ -259,7 +259,7 @@ func TestSessionInt(t *testing.T) { request.Header.Set("Cookie", "session="+SessionId) recorder = httptest.NewRecorder() http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - sess := New(w, r, "./../tmp") + sess, _ := New(w, r, "./../tmp") defer sess.Close() if r.URL.Path == "/del" { sess.DelInt("some_int") @@ -287,7 +287,7 @@ func TestSessionInt64(t *testing.T) { request.Header.Set("Cookie", "session="+SessionId) recorder := httptest.NewRecorder() http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - sess := New(w, r, "./../tmp") + sess, _ := New(w, r, "./../tmp") defer sess.Close() if r.URL.Path == "/isset" { if _, err := w.Write([]byte(fmt.Sprintf("%v", sess.IsSetInt64("some_int64")))); err != nil { @@ -312,7 +312,7 @@ func TestSessionInt64(t *testing.T) { request.Header.Set("Cookie", "session="+SessionId) recorder = httptest.NewRecorder() http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - sess := New(w, r, "./../tmp") + sess, _ := New(w, r, "./../tmp") defer sess.Close() if r.URL.Path == "/set" { sess.SetInt64("some_int64", 10) @@ -343,7 +343,7 @@ func TestSessionInt64(t *testing.T) { request.Header.Set("Cookie", "session="+SessionId) recorder = httptest.NewRecorder() http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - sess := New(w, r, "./../tmp") + sess, _ := New(w, r, "./../tmp") defer sess.Close() if r.URL.Path == "/get" { if _, err := w.Write([]byte(fmt.Sprintf("%d", sess.GetInt64("some_int64", 0)))); err != nil { @@ -368,7 +368,7 @@ func TestSessionInt64(t *testing.T) { request.Header.Set("Cookie", "session="+SessionId) recorder = httptest.NewRecorder() http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - sess := New(w, r, "./../tmp") + sess, _ := New(w, r, "./../tmp") defer sess.Close() if r.URL.Path == "/isset" { if _, err := w.Write([]byte(fmt.Sprintf("%v", sess.IsSetInt64("some_int64")))); err != nil { @@ -393,7 +393,7 @@ func TestSessionInt64(t *testing.T) { request.Header.Set("Cookie", "session="+SessionId) recorder = httptest.NewRecorder() http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - sess := New(w, r, "./../tmp") + sess, _ := New(w, r, "./../tmp") defer sess.Close() if r.URL.Path == "/del" { sess.DelInt64("some_int64") @@ -421,7 +421,7 @@ func TestSessionString(t *testing.T) { request.Header.Set("Cookie", "session="+SessionId) recorder := httptest.NewRecorder() http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - sess := New(w, r, "./../tmp") + sess, _ := New(w, r, "./../tmp") defer sess.Close() if r.URL.Path == "/isset" { if _, err := w.Write([]byte(fmt.Sprintf("%v", sess.IsSetString("some_str")))); err != nil { @@ -446,7 +446,7 @@ func TestSessionString(t *testing.T) { request.Header.Set("Cookie", "session="+SessionId) recorder = httptest.NewRecorder() http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - sess := New(w, r, "./../tmp") + sess, _ := New(w, r, "./../tmp") defer sess.Close() if r.URL.Path == "/set" { sess.SetString("some_str", "test") @@ -477,7 +477,7 @@ func TestSessionString(t *testing.T) { request.Header.Set("Cookie", "session="+SessionId) recorder = httptest.NewRecorder() http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - sess := New(w, r, "./../tmp") + sess, _ := New(w, r, "./../tmp") defer sess.Close() if r.URL.Path == "/get" { if _, err := w.Write([]byte(sess.GetString("some_str", ""))); err != nil { @@ -502,7 +502,7 @@ func TestSessionString(t *testing.T) { request.Header.Set("Cookie", "session="+SessionId) recorder = httptest.NewRecorder() http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - sess := New(w, r, "./../tmp") + sess, _ := New(w, r, "./../tmp") defer sess.Close() if r.URL.Path == "/isset" { if _, err := w.Write([]byte(fmt.Sprintf("%v", sess.IsSetString("some_str")))); err != nil { @@ -527,7 +527,7 @@ func TestSessionString(t *testing.T) { request.Header.Set("Cookie", "session="+SessionId) recorder = httptest.NewRecorder() http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - sess := New(w, r, "./../tmp") + sess, _ := New(w, r, "./../tmp") defer sess.Close() if r.URL.Path == "/del" { sess.DelString("some_str") @@ -572,7 +572,7 @@ func TestSessionDoNotCreateSessionFileForDefValues(t *testing.T) { } recorder := httptest.NewRecorder() http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - sess := New(w, r, "./../tmp") + sess, _ := New(w, r, "./../tmp") defer sess.Close() if r.URL.Path == "/set" { sess.SetBool("some_bool", false) @@ -610,7 +610,7 @@ func TestSessionDoNotCreateSessionFileForDefValues(t *testing.T) { request.Header.Set("Cookie", "session="+sessId) recorder = httptest.NewRecorder() http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - sess := New(w, r, "./../tmp") + sess, _ := New(w, r, "./../tmp") defer sess.Close() if r.URL.Path == "/get" { if _, err := w.Write([]byte(fmt.Sprintf( @@ -650,7 +650,7 @@ func TestSessionDestroy(t *testing.T) { } recorder := httptest.NewRecorder() http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - sess := New(w, r, "./../tmp") + sess, _ := New(w, r, "./../tmp") defer sess.Close() if r.URL.Path == "/set" { sess.SetInt("some_var", 1) @@ -685,7 +685,7 @@ func TestSessionDestroy(t *testing.T) { request.Header.Set("Cookie", "session="+sessId) recorder = httptest.NewRecorder() http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - sess := New(w, r, "./../tmp") + sess, _ := New(w, r, "./../tmp") defer sess.Close() if r.URL.Path == "/get" { if _, err := w.Write([]byte(fmt.Sprintf("%v", sess.GetInt("some_var", 0)))); err != nil { @@ -710,7 +710,7 @@ func TestSessionDestroy(t *testing.T) { request.Header.Set("Cookie", "session="+sessId) recorder = httptest.NewRecorder() http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - sess := New(w, r, "./../tmp") + sess, _ := New(w, r, "./../tmp") defer sess.Close() if r.URL.Path == "/get" { sess.SetInt("some_var", 2)