diff options
author | Hank Shen <swh@admpub.com> | 2023-12-06 06:51:36 +0300 |
---|---|---|
committer | Hank Shen <swh@admpub.com> | 2023-12-06 06:51:36 +0300 |
commit | 75a1bf157648c5b5c155ac81e4950bff5315c0ae (patch) | |
tree | 0002e25150c8949a660884f9aa753f5adac16f13 | |
parent | 3faf6fc167dd8a00d6516ad3ad70012869348603 (diff) |
update
-rw-r--r-- | errors.go | 12 | ||||
-rw-r--r-- | setter.go | 2 | ||||
-rw-r--r-- | unsafecodec.go | 56 | ||||
-rw-r--r-- | unsafecodec_test.go | 20 |
4 files changed, 90 insertions, 0 deletions
@@ -2,6 +2,18 @@ package securecookie import "errors" +func NewUsageError(err error) *cookieError { + return &cookieError{cause: err, typ: usageError} +} + +func NewInternalError(err error) *cookieError { + return &cookieError{cause: err, typ: internalError} +} + +func NewDecodeError(err error) *cookieError { + return &cookieError{cause: err, typ: decodeError} +} + func IsValueTooLong(err error) bool { return errors.Is(err, errEncodedValueTooLong) || errors.Is(err, errValueToDecodeTooLong) } @@ -49,6 +49,8 @@ func SetSerializer(codecs []Codec, sz Serializer) { for _, c := range codecs { if codec, ok := c.(*SecureCookie); ok { codec.SetSerializer(sz) + } else if codec, ok := c.(*UnsafeCodec); ok { + codec.SetSerializer(sz) } } } diff --git a/unsafecodec.go b/unsafecodec.go new file mode 100644 index 0000000..6853658 --- /dev/null +++ b/unsafecodec.go @@ -0,0 +1,56 @@ +package securecookie + +import "fmt" + +var _ Codec = (*UnsafeCodec)(nil) + +func NewUnsafeCodec() *UnsafeCodec { + s := &UnsafeCodec{ + sz: GobEncoder{}, + } + return s +} + +// UnsafeCodec encodes and decodes +type UnsafeCodec struct { + err error + sz Serializer +} + +// Encoding sets the encoding/serialization method for cookies. +// +// Default is encoding/gob. To encode special structures using encoding/gob, +// they must be registered first using gob.Register(). +func (s *UnsafeCodec) SetSerializer(sz Serializer) *UnsafeCodec { + s.sz = sz + + return s +} + +// Encode encodes a value. +func (s *UnsafeCodec) Encode(name string, value interface{}) (string, error) { + if s.err != nil { + return "", s.err + } + var err error + var b []byte + // Serialize. + if b, err = s.sz.Serialize(value); err != nil { + return "", cookieError{cause: fmt.Errorf(`%w: %s`, err, name), typ: usageError} + } + // Done. + return string(b), nil +} + +// Decode decodes a value. The dst argument must be a pointer. +func (s *UnsafeCodec) Decode(name, value string, dst interface{}, _ ...int) error { + if s.err != nil { + return s.err + } + // Deserialize. + if err := s.sz.Deserialize([]byte(value), dst); err != nil { + return cookieError{cause: fmt.Errorf(`%w: %s`, err, name), typ: decodeError} + } + // Done. + return nil +} diff --git a/unsafecodec_test.go b/unsafecodec_test.go new file mode 100644 index 0000000..d295907 --- /dev/null +++ b/unsafecodec_test.go @@ -0,0 +1,20 @@ +package securecookie + +import "testing" + +func TestUnsafeCodec(t *testing.T) { + c := NewUnsafeCodec() + str := `TestUnsafeCodec` + encoded, err := c.Encode(`name`, str) + if err != nil { + t.Error(err) + } + var decoded string + err = c.Decode(`name`, encoded, &decoded) + if err != nil { + t.Error(err) + } + if decoded != str { + t.Fatalf("expected %s, got: %#v", str, decoded) + } +} |