Skip to content

Commit

Permalink
feat(session): add initial session engine structure
Browse files Browse the repository at this point in the history
Refs: #8
  • Loading branch information
piraz committed Jan 20, 2025
1 parent ac5a25c commit af1873c
Show file tree
Hide file tree
Showing 2 changed files with 190 additions and 0 deletions.
131 changes: 131 additions & 0 deletions session/session.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package session

import (
"encoding/json"
"errors"
"fmt"
"os"
"path/filepath"
"time"
)

type Engine interface {
Read(string, any) error
Start() error
Stop() error
Store(string, any) error
Encode() error
Decode() error
}

type FileEngine struct {
Dir string
Encoder
PurgeDuration time.Duration
}

func NewFileEngine() *FileEngine {
dir := filepath.Join(os.TempDir(), "httpok", "sess")
return &FileEngine{
Dir: dir,
Encoder: &JsonEncoder{},
PurgeDuration: 2 * time.Minute,
}
}

func (e *FileEngine) Read(sess string, v any) error {
sessFile := filepath.Join(e.Dir, fmt.Sprintf("%s.sess", sess))
file, err := os.Open(sessFile)
if err != nil {
return err
}

defer file.Close()

buffer := make([]byte, 1024)
n, err := file.Read(buffer)

if err != nil {
return err
}
err = e.Encoder.Decode(buffer[:n], v)
if err != nil {
return err
}

return nil
}

func (e *FileEngine) Start() error {
fileInfo, err := os.Stat(e.Dir)
if err != nil {
if os.IsNotExist(err) {
err := os.MkdirAll(e.Dir, 0o774)
if err != nil {
return errors.New(
fmt.Sprintf("error creating session dir %s: %v", e.Dir,
err),
)
}
return nil
}
return errors.New(
fmt.Sprintf("error stating session dir %s: %v", e.Dir, err),
)
}

if fileInfo.Mode().IsRegular() {
return errors.New(
fmt.Sprintf("there is a file named as %s it is not possible to "+
"create the sesssion dir", e.Dir),
)
}

return nil
}

func (e *FileEngine) Stop() error {
return nil
}

func (e *FileEngine) Store(sess string, v any) error {
sessFile := filepath.Join(e.Dir, fmt.Sprintf("%s.sess", sess))
file, err := os.OpenFile(sessFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
if err != nil {
return err
}
defer file.Close()

data, err := e.Encoder.Encode(v)

_, err = file.Write(data)
if err != nil {
return err
}

return nil
}

func (e *FileEngine) Encode() error {
return nil
}

func (e *FileEngine) Decode() error {
return nil
}

type Encoder interface {
Encode(any) ([]byte, error)
Decode([]byte, any) error
}

type JsonEncoder struct {
}

func (e *JsonEncoder) Encode(v any) ([]byte, error) {
return json.Marshal(v)
}

func (e *JsonEncoder) Decode(data []byte, v any) error {
return json.Unmarshal(data, v)
}
59 changes: 59 additions & 0 deletions session/session_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright 2023-2025 Flavio Garcia
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package session

import (
"fmt"
"os"
"path/filepath"
"testing"

"github.com/candango/httpok/util"
"github.com/stretchr/testify/assert"
)

// TODO: We need to keep building the session engine tests
func TestSessionServer(t *testing.T) {
engine := NewFileEngine()
err := engine.Start()
if err != nil {
t.Error(err)
}

sess := util.RandomString(16)

err = engine.Store(sess, map[string]interface{}{
"key": "value",
})
if err != nil {
t.Error(err)
}
var sessData map[string]interface{}

err = engine.Read(sess, &sessData)
if err != nil {
t.Error(err)
}

assert.Equal(t, "value", sessData["key"])
defer func() {
sessFile := filepath.Join(engine.Dir, fmt.Sprintf("%s.sess", sess))
err := os.Remove(sessFile)
if err != nil {
t.Error(err)
}

}()
}

0 comments on commit af1873c

Please sign in to comment.