feat: 实现 internal/protocol 帧类型、编解码、校验与请求指纹
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
package protocol
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type typePeek struct {
|
||||
V int `json:"v"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
// Decode 解析一帧 MQTT/应用 JSON,返回具体类型。
|
||||
func Decode(data []byte) (any, error) {
|
||||
var peek typePeek
|
||||
if err := Unmarshal(data, &peek); err != nil {
|
||||
return nil, badRequest("invalid json")
|
||||
}
|
||||
if peek.V != 0 && peek.V != Version {
|
||||
return nil, badRequest("unsupported version")
|
||||
}
|
||||
if peek.Type == "" {
|
||||
return nil, badRequest("missing type")
|
||||
}
|
||||
|
||||
var out any
|
||||
switch peek.Type {
|
||||
case TypeHello:
|
||||
out = &Hello{}
|
||||
case TypeResp:
|
||||
out = &Resp{}
|
||||
case TypeSend:
|
||||
out = &Send{}
|
||||
case TypeMsg:
|
||||
out = &Msg{}
|
||||
case TypeAck:
|
||||
out = &Ack{}
|
||||
case TypeRecall:
|
||||
out = &Recall{}
|
||||
case TypeStatus:
|
||||
out = &Status{}
|
||||
case TypeReceipt:
|
||||
out = &Receipt{}
|
||||
case TypeReceiptAck:
|
||||
out = &ReceiptAck{}
|
||||
case TypeRevoked:
|
||||
out = &Revoked{}
|
||||
case TypePresenceGet:
|
||||
out = &PresenceGet{}
|
||||
case TypeDirectoryList:
|
||||
out = &DirectoryList{}
|
||||
case TypePresenceWatch:
|
||||
out = &PresenceWatch{}
|
||||
case TypePresence:
|
||||
out = &Presence{}
|
||||
case TypeUnlock:
|
||||
out = &Unlock{}
|
||||
case TypeSelfGet:
|
||||
out = &SelfGet{}
|
||||
case TypeSelfUpdate:
|
||||
out = &SelfUpdate{}
|
||||
case TypeSelfTalkPassword:
|
||||
out = &SelfTalkPassword{}
|
||||
case TypeSelfLoginPassword:
|
||||
out = &SelfLoginPassword{}
|
||||
case TypeSelfLogout:
|
||||
out = &SelfLogout{}
|
||||
case TypeGroupCreate:
|
||||
out = &GroupCreate{}
|
||||
case TypeGroupAdd:
|
||||
out = &GroupAdd{}
|
||||
case TypeGroupRemove:
|
||||
out = &GroupRemove{}
|
||||
case TypeGroupLeave:
|
||||
out = &GroupLeave{}
|
||||
case TypeGroupTransfer:
|
||||
out = &GroupTransfer{}
|
||||
case TypeGroupRename:
|
||||
out = &GroupRename{}
|
||||
case TypeGroupDissolve:
|
||||
out = &GroupDissolve{}
|
||||
case TypeGroupList:
|
||||
out = &GroupList{}
|
||||
case TypeGroupGet:
|
||||
out = &GroupGet{}
|
||||
case TypeGroupEvent:
|
||||
out = &GroupEvent{}
|
||||
case TypeFatal:
|
||||
out = &Fatal{}
|
||||
default:
|
||||
return nil, badRequest(fmt.Sprintf("unknown type %q", peek.Type))
|
||||
}
|
||||
if err := Unmarshal(data, out); err != nil {
|
||||
return nil, badRequest("invalid json for type")
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// DecodeRegister 解析注册 HTTP 请求体。
|
||||
func DecodeRegister(data []byte) (*RegisterRequest, error) {
|
||||
var req RegisterRequest
|
||||
if err := Unmarshal(data, &req); err != nil {
|
||||
return nil, badRequest("invalid json")
|
||||
}
|
||||
return &req, nil
|
||||
}
|
||||
|
||||
// MustRaw 将值编码为 json.RawMessage(用于填 Resp.Data)。
|
||||
func MustRaw(v any) json.RawMessage {
|
||||
b, err := Marshal(v)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return b
|
||||
}
|
||||
Reference in New Issue
Block a user