mirror of
https://github.com/fumiama/go-registry.git
synced 2026-06-26 13:57:24 +08:00
add method cat & md5
This commit is contained in:
@@ -6,7 +6,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestRegedit(t *testing.T) {
|
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()
|
err := reg.Connect()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -3,3 +3,5 @@ module github.com/fumiama/go-registry
|
|||||||
go 1.17
|
go 1.17
|
||||||
|
|
||||||
require github.com/fumiama/gofastTEA v0.0.10
|
require github.com/fumiama/gofastTEA v0.0.10
|
||||||
|
|
||||||
|
require github.com/fumiama/go-simple-protobuf v0.1.0
|
||||||
|
|||||||
2
go.sum
2
go.sum
@@ -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 h1:JJJ+brWD4kie+mmK2TkspDXKzqq0IjXm89aGYfoGhhQ=
|
||||||
github.com/fumiama/gofastTEA v0.0.10/go.mod h1:RIdbYZyB4MbH6ZBlPymRaXn3cD6SedlCu5W/HHfMPBk=
|
github.com/fumiama/gofastTEA v0.0.10/go.mod h1:RIdbYZyB4MbH6ZBlPymRaXn3cD6SedlCu5W/HHfMPBk=
|
||||||
|
|||||||
108
reg.go
108
reg.go
@@ -1,12 +1,16 @@
|
|||||||
package registry
|
package registry
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/md5"
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
spb "github.com/fumiama/go-simple-protobuf"
|
||||||
tea "github.com/fumiama/gofastTEA"
|
tea "github.com/fumiama/gofastTEA"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -19,18 +23,21 @@ var (
|
|||||||
ErrSetValTooLong = errors.New("set val too long")
|
ErrSetValTooLong = errors.New("set val too long")
|
||||||
ErrUnknownAck = errors.New("unknown ack error")
|
ErrUnknownAck = errors.New("unknown ack error")
|
||||||
ErrNoSuchKey = errors.New("no such key")
|
ErrNoSuchKey = errors.New("no such key")
|
||||||
|
ErrRawDataTooLong = errors.New("raw data too long")
|
||||||
|
ErrMd5NotEqual = errors.New("md5 not equal")
|
||||||
)
|
)
|
||||||
|
|
||||||
type Regedit struct {
|
type Regedit struct {
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
conn net.Conn
|
conn net.Conn
|
||||||
addr string
|
addr string
|
||||||
tp tea.TEA
|
tp tea.TEA
|
||||||
ts *tea.TEA
|
ts *tea.TEA
|
||||||
seq byte
|
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
|
var tp, ts [16]byte
|
||||||
if len(pwd) > 15 {
|
if len(pwd) > 15 {
|
||||||
pwd = pwd[:15]
|
pwd = pwd[:15]
|
||||||
@@ -41,16 +48,16 @@ func NewRegedit(addr, pwd, sps string) *Regedit {
|
|||||||
copy(tp[:], StringToBytes(pwd))
|
copy(tp[:], StringToBytes(pwd))
|
||||||
copy(ts[:], StringToBytes(sps))
|
copy(ts[:], StringToBytes(sps))
|
||||||
s := tea.NewTeaCipherLittleEndian(ts[:])
|
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
|
var tp [16]byte
|
||||||
if len(pwd) > 15 {
|
if len(pwd) > 15 {
|
||||||
pwd = pwd[:15]
|
pwd = pwd[:15]
|
||||||
}
|
}
|
||||||
copy(tp[:], StringToBytes(pwd))
|
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) {
|
func (r *Regedit) Connect() (err error) {
|
||||||
@@ -116,6 +123,89 @@ func (r *Regedit) Get(key string) (string, error) {
|
|||||||
return a, nil
|
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 {
|
func (r *Regedit) Set(key, value string) error {
|
||||||
if r.ts == nil {
|
if r.ts == nil {
|
||||||
return ErrPermissionDenied
|
return ErrPermissionDenied
|
||||||
|
|||||||
31
reg_test.go
31
reg_test.go
@@ -5,7 +5,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestReg(t *testing.T) {
|
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()
|
err := r.Connect()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -33,6 +33,33 @@ func TestReg(t *testing.T) {
|
|||||||
if err != ErrNoSuchKey {
|
if err != ErrNoSuchKey {
|
||||||
t.Fatal(err)
|
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()
|
err = r.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -40,7 +67,7 @@ func TestReg(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPush(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()
|
err := r.Connect()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
|||||||
16
storage.go
Normal file
16
storage.go
Normal 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
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user