1
0
mirror of https://github.com/fumiama/go-registry.git synced 2026-06-04 23:40:27 +08:00

add method cat & md5

This commit is contained in:
源文雨
2022-10-27 16:33:55 +08:00
parent 9963c35b7d
commit bc01e93330
6 changed files with 149 additions and 12 deletions

View File

@@ -6,7 +6,7 @@ import (
)
func TestRegedit(t *testing.T) {
reg := NewRegedit("127.0.0.1:8888", "testpwd", "testsps")
reg := NewRegedit("127.0.0.1:8888", "testpwd", "testsps", 127, 127)
err := reg.Connect()
if err != nil {
t.Fatal(err)

2
go.mod
View File

@@ -3,3 +3,5 @@ module github.com/fumiama/go-registry
go 1.17
require github.com/fumiama/gofastTEA v0.0.10
require github.com/fumiama/go-simple-protobuf v0.1.0

2
go.sum
View File

@@ -1,2 +1,4 @@
github.com/fumiama/go-simple-protobuf v0.1.0 h1:rLzJgNqB6LHNDVMl81yyNt6ZKziWtVfu+ioF0edlEVw=
github.com/fumiama/go-simple-protobuf v0.1.0/go.mod h1:5yYNapXq1tQMOZg9bOIVhQlZk9pQqpuFIO4DZLbsdy4=
github.com/fumiama/gofastTEA v0.0.10 h1:JJJ+brWD4kie+mmK2TkspDXKzqq0IjXm89aGYfoGhhQ=
github.com/fumiama/gofastTEA v0.0.10/go.mod h1:RIdbYZyB4MbH6ZBlPymRaXn3cD6SedlCu5W/HHfMPBk=

108
reg.go
View File

@@ -1,12 +1,16 @@
package registry
import (
"bytes"
"crypto/md5"
"errors"
"io"
"net"
"strconv"
"sync"
"time"
spb "github.com/fumiama/go-simple-protobuf"
tea "github.com/fumiama/gofastTEA"
)
@@ -19,18 +23,21 @@ var (
ErrSetValTooLong = errors.New("set val too long")
ErrUnknownAck = errors.New("unknown ack error")
ErrNoSuchKey = errors.New("no such key")
ErrRawDataTooLong = errors.New("raw data too long")
ErrMd5NotEqual = errors.New("md5 not equal")
)
type Regedit struct {
sync.Mutex
conn net.Conn
addr string
tp tea.TEA
ts *tea.TEA
seq byte
conn net.Conn
addr string
tp tea.TEA
ts *tea.TEA
dksz, ddsz int
seq byte
}
func NewRegedit(addr, pwd, sps string) *Regedit {
func NewRegedit(addr, pwd, sps string, dksz, ddsz int) *Regedit {
var tp, ts [16]byte
if len(pwd) > 15 {
pwd = pwd[:15]
@@ -41,16 +48,16 @@ func NewRegedit(addr, pwd, sps string) *Regedit {
copy(tp[:], StringToBytes(pwd))
copy(ts[:], StringToBytes(sps))
s := tea.NewTeaCipherLittleEndian(ts[:])
return &Regedit{addr: addr, tp: tea.NewTeaCipherLittleEndian(tp[:]), ts: &s}
return &Regedit{addr: addr, tp: tea.NewTeaCipherLittleEndian(tp[:]), ts: &s, dksz: dksz, ddsz: ddsz}
}
func NewRegReader(addr, pwd string) *Regedit {
func NewRegReader(addr, pwd string, dksz, ddsz int) *Regedit {
var tp [16]byte
if len(pwd) > 15 {
pwd = pwd[:15]
}
copy(tp[:], StringToBytes(pwd))
return &Regedit{addr: addr, tp: tea.NewTeaCipherLittleEndian(tp[:])}
return &Regedit{addr: addr, tp: tea.NewTeaCipherLittleEndian(tp[:]), dksz: dksz, ddsz: ddsz}
}
func (r *Regedit) Connect() (err error) {
@@ -116,6 +123,89 @@ func (r *Regedit) Get(key string) (string, error) {
return a, nil
}
func (r *Regedit) Cat() (*Storage, error) {
p := NewCmdPacket(CMDCAT, []byte("fill"), &r.tp)
defer p.Put()
r.Lock()
r.conn.Write(p.Encrypt(r.seq))
r.seq++
seq := r.seq
r.seq++
r.Unlock()
var buf [64]byte
i := 0
for {
_, err := r.conn.Read(buf[i : i+1])
if err != nil {
return nil, err
}
if buf[i] == '$' {
break
}
i++
if i >= 64 {
return nil, ErrRawDataTooLong
}
}
n, err := strconv.ParseUint(BytesToString(buf[:i]), 10, 64)
if err != nil {
return nil, err
}
data := make([]byte, n)
_, err = r.conn.Read(data)
if err != nil {
return nil, err
}
setseq(&r.tp, seq)
data = r.tp.DecryptLittleEndian(data, sumtable)
s := new(Storage)
s.m = make(map[string]string, 256)
s.Md5 = md5.Sum(data)
rd := bytes.NewReader(data)
for i = 0; i < len(data); {
sp, err := spb.NewSimplePB(rd)
if err == io.EOF {
break
}
if err != nil {
return nil, err
}
s.m[BytesToString(sp.Target[0])] = BytesToString(sp.Target[1])
i += int(sp.RealLen)
}
return s, nil
}
func (r *Regedit) IsMd5Equal(m [md5.Size]byte) (bool, error) {
p := NewCmdPacket(CMDMD5, m[:], &r.tp)
defer p.Put()
r.Lock()
r.conn.Write(p.Encrypt(r.seq))
r.seq++
err := r.ack(p)
if err != nil {
r.Unlock()
return false, err
}
err = p.Decrypt(r.seq)
r.seq++
r.Unlock()
if err != nil {
return false, ErrDecAck
}
a := string(p.Data)
if a == "erro" && p.cmd == ACKERRO {
return false, ErrInternalServer
}
if a == "nequ" && p.cmd == ACKNEQU {
return false, ErrNoSuchKey
}
if a == "null" && p.cmd == ACKNULL {
return true, nil
}
return false, ErrUnknownAck
}
func (r *Regedit) Set(key, value string) error {
if r.ts == nil {
return ErrPermissionDenied

View File

@@ -5,7 +5,7 @@ import (
)
func TestReg(t *testing.T) {
r := NewRegedit("127.0.0.1:8888", "testpwd", "testsps")
r := NewRegedit("127.0.0.1:8888", "testpwd", "testsps", 127, 127)
err := r.Connect()
if err != nil {
t.Fatal(err)
@@ -33,6 +33,33 @@ func TestReg(t *testing.T) {
if err != ErrNoSuchKey {
t.Fatal(err)
}
err = r.Set("test", "测试")
if err != nil {
t.Fatal(err)
}
s, err := r.Cat()
if err != nil {
t.Fatal(err)
}
v, err = s.Get("test")
if err != nil {
t.Fatal(err)
}
if v != "测试" {
t.Fatal("invalid test key value in store")
}
_, err = r.IsMd5Equal(s.Md5)
if err != nil {
t.Fatal(err)
}
err = r.Del("test")
if err != nil {
t.Fatal(err)
}
_, err = r.IsMd5Equal(s.Md5)
if err == nil {
t.Fatal("md5 has not been renewed")
}
err = r.Close()
if err != nil {
t.Fatal(err)
@@ -40,7 +67,7 @@ func TestReg(t *testing.T) {
}
func TestPush(t *testing.T) {
r := NewRegedit("reilia.fumiama.top:32664", "fumiama", "--")
r := NewRegedit("reilia.fumiama.top:32664", "fumiama", "--", 127, 127)
err := r.Connect()
if err != nil {
t.Fatal(err)

16
storage.go Normal file
View File

@@ -0,0 +1,16 @@
package registry
import "crypto/md5"
type Storage struct {
Md5 [md5.Size]byte
m map[string]string
}
func (s *Storage) Get(key string) (string, error) {
v, ok := s.m[key]
if ok {
return v, nil
}
return "", ErrNoSuchKey
}