mirror of
https://github.com/nbd-wtf/go-nostr.git
synced 2025-03-17 13:22:56 +01:00
fix and improve envelope stuff again, deal with messages as strings on all envelope parsing steps.
This commit is contained in:
parent
42a2243b72
commit
cecc71cd81
104
envelopes.go
104
envelopes.go
@ -1,81 +1,75 @@
|
|||||||
package nostr
|
package nostr
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
"github.com/mailru/easyjson"
|
"github.com/mailru/easyjson"
|
||||||
jwriter "github.com/mailru/easyjson/jwriter"
|
jwriter "github.com/mailru/easyjson/jwriter"
|
||||||
"github.com/tidwall/gjson"
|
"github.com/tidwall/gjson"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var UnknownLabel = errors.New("unknown envelope label")
|
||||||
labelEvent = []byte("EVENT")
|
|
||||||
labelReq = []byte("REQ")
|
|
||||||
labelCount = []byte("COUNT")
|
|
||||||
labelNotice = []byte("NOTICE")
|
|
||||||
labelEose = []byte("EOSE")
|
|
||||||
labelOk = []byte("OK")
|
|
||||||
labelAuth = []byte("AUTH")
|
|
||||||
labelClosed = []byte("CLOSED")
|
|
||||||
labelClose = []byte("CLOSE")
|
|
||||||
|
|
||||||
UnknownLabel = errors.New("unknown envelope label")
|
|
||||||
)
|
|
||||||
|
|
||||||
type MessageParser interface {
|
type MessageParser interface {
|
||||||
// ParseMessage parses a message into an Envelope.
|
// ParseMessage parses a message into an Envelope.
|
||||||
ParseMessage([]byte) (Envelope, error)
|
ParseMessage(string) (Envelope, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deprecated: use NewMessageParser instead
|
// Deprecated: use NewMessageParser instead
|
||||||
func ParseMessage(message []byte) Envelope {
|
func ParseMessage(message string) Envelope {
|
||||||
firstComma := bytes.Index(message, []byte{','})
|
firstQuote := strings.IndexRune(message, '"')
|
||||||
if firstComma == -1 {
|
if firstQuote == -1 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
label := message[0:firstComma]
|
secondQuote := strings.IndexRune(message[firstQuote+1:], '"')
|
||||||
|
if secondQuote == -1 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
label := message[firstQuote+1 : firstQuote+1+secondQuote]
|
||||||
|
|
||||||
var v Envelope
|
var v Envelope
|
||||||
switch {
|
switch label {
|
||||||
case bytes.Contains(label, labelEvent):
|
case "EVENT":
|
||||||
v = &EventEnvelope{}
|
v = &EventEnvelope{}
|
||||||
case bytes.Contains(label, labelReq):
|
case "REQ":
|
||||||
v = &ReqEnvelope{}
|
v = &ReqEnvelope{}
|
||||||
case bytes.Contains(label, labelCount):
|
case "COUNT":
|
||||||
v = &CountEnvelope{}
|
v = &CountEnvelope{}
|
||||||
case bytes.Contains(label, labelNotice):
|
case "NOTICE":
|
||||||
x := NoticeEnvelope("")
|
x := NoticeEnvelope("")
|
||||||
v = &x
|
v = &x
|
||||||
case bytes.Contains(label, labelEose):
|
case "EOSE":
|
||||||
x := EOSEEnvelope("")
|
x := EOSEEnvelope("")
|
||||||
v = &x
|
v = &x
|
||||||
case bytes.Contains(label, labelOk):
|
case "OK":
|
||||||
v = &OKEnvelope{}
|
v = &OKEnvelope{}
|
||||||
case bytes.Contains(label, labelAuth):
|
case "AUTH":
|
||||||
v = &AuthEnvelope{}
|
v = &AuthEnvelope{}
|
||||||
case bytes.Contains(label, labelClosed):
|
case "CLOSED":
|
||||||
v = &ClosedEnvelope{}
|
v = &ClosedEnvelope{}
|
||||||
case bytes.Contains(label, labelClose):
|
case "CLOSE":
|
||||||
x := CloseEnvelope("")
|
x := CloseEnvelope("")
|
||||||
v = &x
|
v = &x
|
||||||
default:
|
default:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := v.UnmarshalJSON(message); err != nil {
|
if err := v.FromJSON(message); err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
// Envelope is the interface for all nostr message envelopes.
|
// Envelope is the interface for all nostr message envelopes.
|
||||||
type Envelope interface {
|
type Envelope interface {
|
||||||
Label() string
|
Label() string
|
||||||
UnmarshalJSON([]byte) error
|
FromJSON(string) error
|
||||||
MarshalJSON() ([]byte, error)
|
MarshalJSON() ([]byte, error)
|
||||||
String() string
|
String() string
|
||||||
}
|
}
|
||||||
@ -99,15 +93,15 @@ type EventEnvelope struct {
|
|||||||
|
|
||||||
func (_ EventEnvelope) Label() string { return "EVENT" }
|
func (_ EventEnvelope) Label() string { return "EVENT" }
|
||||||
|
|
||||||
func (v *EventEnvelope) UnmarshalJSON(data []byte) error {
|
func (v *EventEnvelope) FromJSON(data string) error {
|
||||||
r := gjson.ParseBytes(data)
|
r := gjson.Parse(data)
|
||||||
arr := r.Array()
|
arr := r.Array()
|
||||||
switch len(arr) {
|
switch len(arr) {
|
||||||
case 2:
|
case 2:
|
||||||
return easyjson.Unmarshal([]byte(arr[1].Raw), &v.Event)
|
return easyjson.Unmarshal(unsafe.Slice(unsafe.StringData(arr[1].Raw), len(arr[1].Raw)), &v.Event)
|
||||||
case 3:
|
case 3:
|
||||||
v.SubscriptionID = &arr[1].Str
|
v.SubscriptionID = &arr[1].Str
|
||||||
return easyjson.Unmarshal([]byte(arr[2].Raw), &v.Event)
|
return easyjson.Unmarshal(unsafe.Slice(unsafe.StringData(arr[2].Raw), len(arr[2].Raw)), &v.Event)
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("failed to decode EVENT envelope")
|
return fmt.Errorf("failed to decode EVENT envelope")
|
||||||
}
|
}
|
||||||
@ -134,8 +128,8 @@ type ReqEnvelope struct {
|
|||||||
|
|
||||||
func (_ ReqEnvelope) Label() string { return "REQ" }
|
func (_ ReqEnvelope) Label() string { return "REQ" }
|
||||||
|
|
||||||
func (v *ReqEnvelope) UnmarshalJSON(data []byte) error {
|
func (v *ReqEnvelope) FromJSON(data string) error {
|
||||||
r := gjson.ParseBytes(data)
|
r := gjson.Parse(data)
|
||||||
arr := r.Array()
|
arr := r.Array()
|
||||||
if len(arr) < 3 {
|
if len(arr) < 3 {
|
||||||
return fmt.Errorf("failed to decode REQ envelope: missing filters")
|
return fmt.Errorf("failed to decode REQ envelope: missing filters")
|
||||||
@ -144,7 +138,7 @@ func (v *ReqEnvelope) UnmarshalJSON(data []byte) error {
|
|||||||
v.Filters = make(Filters, len(arr)-2)
|
v.Filters = make(Filters, len(arr)-2)
|
||||||
f := 0
|
f := 0
|
||||||
for i := 2; i < len(arr); i++ {
|
for i := 2; i < len(arr); i++ {
|
||||||
if err := easyjson.Unmarshal([]byte(arr[i].Raw), &v.Filters[f]); err != nil {
|
if err := easyjson.Unmarshal(unsafe.Slice(unsafe.StringData(arr[i].Raw), len(arr[i].Raw)), &v.Filters[f]); err != nil {
|
||||||
return fmt.Errorf("%w -- on filter %d", err, f)
|
return fmt.Errorf("%w -- on filter %d", err, f)
|
||||||
}
|
}
|
||||||
f++
|
f++
|
||||||
@ -180,8 +174,8 @@ func (c CountEnvelope) String() string {
|
|||||||
return string(v)
|
return string(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *CountEnvelope) UnmarshalJSON(data []byte) error {
|
func (v *CountEnvelope) FromJSON(data string) error {
|
||||||
r := gjson.ParseBytes(data)
|
r := gjson.Parse(data)
|
||||||
arr := r.Array()
|
arr := r.Array()
|
||||||
if len(arr) < 3 {
|
if len(arr) < 3 {
|
||||||
return fmt.Errorf("failed to decode COUNT envelope: missing filters")
|
return fmt.Errorf("failed to decode COUNT envelope: missing filters")
|
||||||
@ -192,7 +186,7 @@ func (v *CountEnvelope) UnmarshalJSON(data []byte) error {
|
|||||||
Count *int64 `json:"count"`
|
Count *int64 `json:"count"`
|
||||||
HLL string `json:"hll"`
|
HLL string `json:"hll"`
|
||||||
}
|
}
|
||||||
if err := json.Unmarshal([]byte(arr[2].Raw), &countResult); err == nil && countResult.Count != nil {
|
if err := json.Unmarshal(unsafe.Slice(unsafe.StringData(arr[2].Raw), len(arr[2].Raw)), &countResult); err == nil && countResult.Count != nil {
|
||||||
v.Count = countResult.Count
|
v.Count = countResult.Count
|
||||||
if len(countResult.HLL) == 512 {
|
if len(countResult.HLL) == 512 {
|
||||||
v.HyperLogLog, err = hex.DecodeString(countResult.HLL)
|
v.HyperLogLog, err = hex.DecodeString(countResult.HLL)
|
||||||
@ -205,7 +199,7 @@ func (v *CountEnvelope) UnmarshalJSON(data []byte) error {
|
|||||||
|
|
||||||
f := 0
|
f := 0
|
||||||
for i := 2; i < len(arr); i++ {
|
for i := 2; i < len(arr); i++ {
|
||||||
item := []byte(arr[i].Raw)
|
item := unsafe.Slice(unsafe.StringData(arr[i].Raw), len(arr[i].Raw))
|
||||||
|
|
||||||
if err := easyjson.Unmarshal(item, &v.Filter); err != nil {
|
if err := easyjson.Unmarshal(item, &v.Filter); err != nil {
|
||||||
return fmt.Errorf("%w -- on filter %d", err, f)
|
return fmt.Errorf("%w -- on filter %d", err, f)
|
||||||
@ -249,8 +243,8 @@ func (n NoticeEnvelope) String() string {
|
|||||||
return string(v)
|
return string(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *NoticeEnvelope) UnmarshalJSON(data []byte) error {
|
func (v *NoticeEnvelope) FromJSON(data string) error {
|
||||||
r := gjson.ParseBytes(data)
|
r := gjson.Parse(data)
|
||||||
arr := r.Array()
|
arr := r.Array()
|
||||||
if len(arr) < 2 {
|
if len(arr) < 2 {
|
||||||
return fmt.Errorf("failed to decode NOTICE envelope")
|
return fmt.Errorf("failed to decode NOTICE envelope")
|
||||||
@ -276,8 +270,8 @@ func (e EOSEEnvelope) String() string {
|
|||||||
return string(v)
|
return string(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *EOSEEnvelope) UnmarshalJSON(data []byte) error {
|
func (v *EOSEEnvelope) FromJSON(data string) error {
|
||||||
r := gjson.ParseBytes(data)
|
r := gjson.Parse(data)
|
||||||
arr := r.Array()
|
arr := r.Array()
|
||||||
if len(arr) < 2 {
|
if len(arr) < 2 {
|
||||||
return fmt.Errorf("failed to decode EOSE envelope")
|
return fmt.Errorf("failed to decode EOSE envelope")
|
||||||
@ -303,8 +297,8 @@ func (c CloseEnvelope) String() string {
|
|||||||
return string(v)
|
return string(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *CloseEnvelope) UnmarshalJSON(data []byte) error {
|
func (v *CloseEnvelope) FromJSON(data string) error {
|
||||||
r := gjson.ParseBytes(data)
|
r := gjson.Parse(data)
|
||||||
arr := r.Array()
|
arr := r.Array()
|
||||||
switch len(arr) {
|
switch len(arr) {
|
||||||
case 2:
|
case 2:
|
||||||
@ -335,8 +329,8 @@ func (c ClosedEnvelope) String() string {
|
|||||||
return string(v)
|
return string(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *ClosedEnvelope) UnmarshalJSON(data []byte) error {
|
func (v *ClosedEnvelope) FromJSON(data string) error {
|
||||||
r := gjson.ParseBytes(data)
|
r := gjson.Parse(data)
|
||||||
arr := r.Array()
|
arr := r.Array()
|
||||||
switch len(arr) {
|
switch len(arr) {
|
||||||
case 3:
|
case 3:
|
||||||
@ -370,8 +364,8 @@ func (o OKEnvelope) String() string {
|
|||||||
return string(v)
|
return string(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *OKEnvelope) UnmarshalJSON(data []byte) error {
|
func (v *OKEnvelope) FromJSON(data string) error {
|
||||||
r := gjson.ParseBytes(data)
|
r := gjson.Parse(data)
|
||||||
arr := r.Array()
|
arr := r.Array()
|
||||||
if len(arr) < 4 {
|
if len(arr) < 4 {
|
||||||
return fmt.Errorf("failed to decode OK envelope: missing fields")
|
return fmt.Errorf("failed to decode OK envelope: missing fields")
|
||||||
@ -411,14 +405,14 @@ func (a AuthEnvelope) String() string {
|
|||||||
return string(v)
|
return string(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *AuthEnvelope) UnmarshalJSON(data []byte) error {
|
func (v *AuthEnvelope) FromJSON(data string) error {
|
||||||
r := gjson.ParseBytes(data)
|
r := gjson.Parse(data)
|
||||||
arr := r.Array()
|
arr := r.Array()
|
||||||
if len(arr) < 2 {
|
if len(arr) < 2 {
|
||||||
return fmt.Errorf("failed to decode Auth envelope: missing fields")
|
return fmt.Errorf("failed to decode Auth envelope: missing fields")
|
||||||
}
|
}
|
||||||
if arr[1].IsObject() {
|
if arr[1].IsObject() {
|
||||||
return easyjson.Unmarshal([]byte(arr[1].Raw), &v.Event)
|
return easyjson.Unmarshal(unsafe.Slice(unsafe.StringData(arr[1].Raw), len(arr[1].Raw)), &v.Event)
|
||||||
} else {
|
} else {
|
||||||
v.Challenge = &arr[1].Str
|
v.Challenge = &arr[1].Str
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
//go:build sonic
|
||||||
|
|
||||||
package nostr
|
package nostr
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -6,6 +8,7 @@ import (
|
|||||||
"math/rand/v2"
|
"math/rand/v2"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
func BenchmarkParseMessage(b *testing.B) {
|
func BenchmarkParseMessage(b *testing.B) {
|
||||||
@ -17,7 +20,7 @@ func BenchmarkParseMessage(b *testing.B) {
|
|||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
for _, msg := range messages {
|
for _, msg := range messages {
|
||||||
var v any
|
var v any
|
||||||
stdlibjson.Unmarshal(msg, &v)
|
stdlibjson.Unmarshal(unsafe.Slice(unsafe.StringData(msg), len(msg)), &v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -42,8 +45,8 @@ func BenchmarkParseMessage(b *testing.B) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateTestMessages(typ string) [][]byte {
|
func generateTestMessages(typ string) []string {
|
||||||
messages := make([][]byte, 0, 600)
|
messages := make([]string, 0, 600)
|
||||||
|
|
||||||
setup := map[string]map[int]func() []byte{
|
setup := map[string]map[int]func() []byte{
|
||||||
"client": {
|
"client": {
|
||||||
@ -62,7 +65,7 @@ func generateTestMessages(typ string) [][]byte {
|
|||||||
|
|
||||||
for count, generator := range setup {
|
for count, generator := range setup {
|
||||||
for range count {
|
for range count {
|
||||||
messages = append(messages, generator())
|
messages = append(messages, string(generator()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
package nostr
|
package nostr
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"errors"
|
"errors"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewMessageParser() MessageParser {
|
func NewMessageParser() MessageParser {
|
||||||
@ -13,41 +13,45 @@ func NewMessageParser() MessageParser {
|
|||||||
|
|
||||||
type messageParser struct{}
|
type messageParser struct{}
|
||||||
|
|
||||||
func (messageParser) ParseMessage(message []byte) (Envelope, error) {
|
func (messageParser) ParseMessage(message string) (Envelope, error) {
|
||||||
firstComma := bytes.Index(message, []byte{','})
|
firstQuote := strings.IndexRune(message, '"')
|
||||||
if firstComma == -1 {
|
if firstQuote == -1 {
|
||||||
return nil, errors.New("malformed json")
|
return nil, errors.New("malformed json")
|
||||||
}
|
}
|
||||||
label := message[0:firstComma]
|
secondQuote := strings.IndexRune(message[firstQuote+1:], '"')
|
||||||
|
if secondQuote == -1 {
|
||||||
|
return nil, errors.New("malformed json")
|
||||||
|
}
|
||||||
|
label := message[firstQuote+1 : firstQuote+1+secondQuote]
|
||||||
|
|
||||||
var v Envelope
|
var v Envelope
|
||||||
switch {
|
switch label {
|
||||||
case bytes.Contains(label, labelEvent):
|
case "EVENT":
|
||||||
v = &EventEnvelope{}
|
v = &EventEnvelope{}
|
||||||
case bytes.Contains(label, labelReq):
|
case "REQ":
|
||||||
v = &ReqEnvelope{}
|
v = &ReqEnvelope{}
|
||||||
case bytes.Contains(label, labelCount):
|
case "COUNT":
|
||||||
v = &CountEnvelope{}
|
v = &CountEnvelope{}
|
||||||
case bytes.Contains(label, labelNotice):
|
case "NOTICE":
|
||||||
x := NoticeEnvelope("")
|
x := NoticeEnvelope("")
|
||||||
v = &x
|
v = &x
|
||||||
case bytes.Contains(label, labelEose):
|
case "EOSE":
|
||||||
x := EOSEEnvelope("")
|
x := EOSEEnvelope("")
|
||||||
v = &x
|
v = &x
|
||||||
case bytes.Contains(label, labelOk):
|
case "OK":
|
||||||
v = &OKEnvelope{}
|
v = &OKEnvelope{}
|
||||||
case bytes.Contains(label, labelAuth):
|
case "AUTH":
|
||||||
v = &AuthEnvelope{}
|
v = &AuthEnvelope{}
|
||||||
case bytes.Contains(label, labelClosed):
|
case "CLOSED":
|
||||||
v = &ClosedEnvelope{}
|
v = &ClosedEnvelope{}
|
||||||
case bytes.Contains(label, labelClose):
|
case "CLOSE":
|
||||||
x := CloseEnvelope("")
|
x := CloseEnvelope("")
|
||||||
v = &x
|
v = &x
|
||||||
default:
|
default:
|
||||||
return nil, UnknownLabel
|
return nil, UnknownLabel
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := v.UnmarshalJSON(message); err != nil {
|
if err := v.FromJSON(message); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return v, nil
|
return v, nil
|
||||||
|
@ -551,11 +551,11 @@ func (smp *sonicMessageParser) doneWithIntSlice(slice []int) {
|
|||||||
// When an unexpected message (like ["NEG-OPEN", ...]) is found, the error UnknownLabel will be
|
// When an unexpected message (like ["NEG-OPEN", ...]) is found, the error UnknownLabel will be
|
||||||
// returned. Other errors will be returned if the JSON is malformed or the objects are not exactly
|
// returned. Other errors will be returned if the JSON is malformed or the objects are not exactly
|
||||||
// as they should.
|
// as they should.
|
||||||
func (smp sonicMessageParser) ParseMessage(message []byte) (Envelope, error) {
|
func (smp sonicMessageParser) ParseMessage(message string) (Envelope, error) {
|
||||||
sv := &sonicVisitor{smp: &smp}
|
sv := &sonicVisitor{smp: &smp}
|
||||||
sv.whereWeAre = inEnvelope
|
sv.whereWeAre = inEnvelope
|
||||||
|
|
||||||
err := ast.Preorder(unsafe.String(unsafe.SliceData(message), len(message)), sv, nil)
|
err := ast.Preorder(message, sv, nil)
|
||||||
|
|
||||||
return sv.mainEnvelope, err
|
return sv.mainEnvelope, err
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
//go:build sonic
|
||||||
|
|
||||||
package nostr
|
package nostr
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -11,97 +13,97 @@ import (
|
|||||||
func TestParseMessage(t *testing.T) {
|
func TestParseMessage(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
Name string
|
Name string
|
||||||
Message []byte
|
Message string
|
||||||
ExpectedEnvelope Envelope
|
ExpectedEnvelope Envelope
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
Name: "nil",
|
Name: "nil",
|
||||||
Message: nil,
|
Message: "",
|
||||||
ExpectedEnvelope: nil,
|
ExpectedEnvelope: nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "invalid string",
|
Name: "invalid string",
|
||||||
Message: []byte("invalid input"),
|
Message: "invalid input",
|
||||||
ExpectedEnvelope: nil,
|
ExpectedEnvelope: nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "invalid string with a comma",
|
Name: "invalid string with a comma",
|
||||||
Message: []byte("invalid, input"),
|
Message: "invalid, input",
|
||||||
ExpectedEnvelope: nil,
|
ExpectedEnvelope: nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "EVENT envelope with subscription id",
|
Name: "EVENT envelope with subscription id",
|
||||||
Message: []byte(`["EVENT","_",{"kind":1,"id":"dc90c95f09947507c1044e8f48bcf6350aa6bff1507dd4acfc755b9239b5c962","pubkey":"3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d","created_at":1644271588,"tags":[],"content":"now that https://blueskyweb.org/blog/2-7-2022-overview was announced we can stop working on nostr?","sig":"230e9d8f0ddaf7eb70b5f7741ccfa37e87a455c9a469282e3464e2052d3192cd63a167e196e381ef9d7e69e9ea43af2443b839974dc85d8aaab9efe1d9296524"}]`),
|
Message: `["EVENT","_",{"kind":1,"id":"dc90c95f09947507c1044e8f48bcf6350aa6bff1507dd4acfc755b9239b5c962","pubkey":"3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d","created_at":1644271588,"tags":[],"content":"now that https://blueskyweb.org/blog/2-7-2022-overview was announced we can stop working on nostr?","sig":"230e9d8f0ddaf7eb70b5f7741ccfa37e87a455c9a469282e3464e2052d3192cd63a167e196e381ef9d7e69e9ea43af2443b839974dc85d8aaab9efe1d9296524"}]`,
|
||||||
ExpectedEnvelope: &EventEnvelope{SubscriptionID: ptr("_"), Event: Event{Kind: 1, ID: "dc90c95f09947507c1044e8f48bcf6350aa6bff1507dd4acfc755b9239b5c962", PubKey: "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d", CreatedAt: 1644271588, Tags: Tags{}, Content: "now that https://blueskyweb.org/blog/2-7-2022-overview was announced we can stop working on nostr?", Sig: "230e9d8f0ddaf7eb70b5f7741ccfa37e87a455c9a469282e3464e2052d3192cd63a167e196e381ef9d7e69e9ea43af2443b839974dc85d8aaab9efe1d9296524"}},
|
ExpectedEnvelope: &EventEnvelope{SubscriptionID: ptr("_"), Event: Event{Kind: 1, ID: "dc90c95f09947507c1044e8f48bcf6350aa6bff1507dd4acfc755b9239b5c962", PubKey: "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d", CreatedAt: 1644271588, Tags: Tags{}, Content: "now that https://blueskyweb.org/blog/2-7-2022-overview was announced we can stop working on nostr?", Sig: "230e9d8f0ddaf7eb70b5f7741ccfa37e87a455c9a469282e3464e2052d3192cd63a167e196e381ef9d7e69e9ea43af2443b839974dc85d8aaab9efe1d9296524"}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "EVENT envelope without subscription id",
|
Name: "EVENT envelope without subscription id",
|
||||||
Message: []byte(`["EVENT",{"kind":1,"id":"dc90c95f09947507c1044e8f48bcf6350aa6bff1507dd4acfc755b9239b5c962","pubkey":"3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d","created_at":1644271588,"tags":[],"content":"now that https://blueskyweb.org/blog/2-7-2022-overview was announced we can stop working on nostr?","sig":"230e9d8f0ddaf7eb70b5f7741ccfa37e87a455c9a469282e3464e2052d3192cd63a167e196e381ef9d7e69e9ea43af2443b839974dc85d8aaab9efe1d9296524"}]`),
|
Message: `["EVENT",{"kind":1,"id":"dc90c95f09947507c1044e8f48bcf6350aa6bff1507dd4acfc755b9239b5c962","pubkey":"3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d","created_at":1644271588,"tags":[],"content":"now that https://blueskyweb.org/blog/2-7-2022-overview was announced we can stop working on nostr?","sig":"230e9d8f0ddaf7eb70b5f7741ccfa37e87a455c9a469282e3464e2052d3192cd63a167e196e381ef9d7e69e9ea43af2443b839974dc85d8aaab9efe1d9296524"}]`,
|
||||||
ExpectedEnvelope: &EventEnvelope{Event: Event{Kind: 1, ID: "dc90c95f09947507c1044e8f48bcf6350aa6bff1507dd4acfc755b9239b5c962", PubKey: "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d", CreatedAt: 1644271588, Tags: Tags{}, Content: "now that https://blueskyweb.org/blog/2-7-2022-overview was announced we can stop working on nostr?", Sig: "230e9d8f0ddaf7eb70b5f7741ccfa37e87a455c9a469282e3464e2052d3192cd63a167e196e381ef9d7e69e9ea43af2443b839974dc85d8aaab9efe1d9296524"}},
|
ExpectedEnvelope: &EventEnvelope{Event: Event{Kind: 1, ID: "dc90c95f09947507c1044e8f48bcf6350aa6bff1507dd4acfc755b9239b5c962", PubKey: "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d", CreatedAt: 1644271588, Tags: Tags{}, Content: "now that https://blueskyweb.org/blog/2-7-2022-overview was announced we can stop working on nostr?", Sig: "230e9d8f0ddaf7eb70b5f7741ccfa37e87a455c9a469282e3464e2052d3192cd63a167e196e381ef9d7e69e9ea43af2443b839974dc85d8aaab9efe1d9296524"}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "EVENT envelope with tags",
|
Name: "EVENT envelope with tags",
|
||||||
Message: []byte(`["EVENT",{"kind":3,"id":"9e662bdd7d8abc40b5b15ee1ff5e9320efc87e9274d8d440c58e6eed2dddfbe2","pubkey":"373ebe3d45ec91977296a178d9f19f326c70631d2a1b0bbba5c5ecc2eb53b9e7","created_at":1644844224,"tags":[["p","3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d"],["e","75fc5ac2487363293bd27fb0d14fb966477d0f1dbc6361d37806a6a740eda91e"],["p","46d0dfd3a724a302ca9175163bdf788f3606b3fd1bb12d5fe055d1e418cb60ea"]],"content":"{\"wss://nostr-pub.wellorder.net\":{\"read\":true,\"write\":true},\"wss://nostr.bitcoiner.social\":{\"read\":false,\"write\":true},\"wss://expensive-relay.fiatjaf.com\":{\"read\":true,\"write\":true},\"wss://relayer.fiatjaf.com\":{\"read\":true,\"write\":true},\"wss://relay.bitid.nz\":{\"read\":true,\"write\":true},\"wss://nostr.rocks\":{\"read\":true,\"write\":true}}","sig":"811355d3484d375df47581cb5d66bed05002c2978894098304f20b595e571b7e01b2efd906c5650080ffe49cf1c62b36715698e9d88b9e8be43029a2f3fa66be"}]`),
|
Message: `["EVENT",{"kind":3,"id":"9e662bdd7d8abc40b5b15ee1ff5e9320efc87e9274d8d440c58e6eed2dddfbe2","pubkey":"373ebe3d45ec91977296a178d9f19f326c70631d2a1b0bbba5c5ecc2eb53b9e7","created_at":1644844224,"tags":[["p","3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d"],["e","75fc5ac2487363293bd27fb0d14fb966477d0f1dbc6361d37806a6a740eda91e"],["p","46d0dfd3a724a302ca9175163bdf788f3606b3fd1bb12d5fe055d1e418cb60ea"]],"content":"{\"wss://nostr-pub.wellorder.net\":{\"read\":true,\"write\":true},\"wss://nostr.bitcoiner.social\":{\"read\":false,\"write\":true},\"wss://expensive-relay.fiatjaf.com\":{\"read\":true,\"write\":true},\"wss://relayer.fiatjaf.com\":{\"read\":true,\"write\":true},\"wss://relay.bitid.nz\":{\"read\":true,\"write\":true},\"wss://nostr.rocks\":{\"read\":true,\"write\":true}}","sig":"811355d3484d375df47581cb5d66bed05002c2978894098304f20b595e571b7e01b2efd906c5650080ffe49cf1c62b36715698e9d88b9e8be43029a2f3fa66be"}]`,
|
||||||
ExpectedEnvelope: &EventEnvelope{Event: Event{Kind: 3, ID: "9e662bdd7d8abc40b5b15ee1ff5e9320efc87e9274d8d440c58e6eed2dddfbe2", PubKey: "373ebe3d45ec91977296a178d9f19f326c70631d2a1b0bbba5c5ecc2eb53b9e7", CreatedAt: 1644844224, Tags: Tags{Tag{"p", "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d"}, Tag{"e", "75fc5ac2487363293bd27fb0d14fb966477d0f1dbc6361d37806a6a740eda91e"}, Tag{"p", "46d0dfd3a724a302ca9175163bdf788f3606b3fd1bb12d5fe055d1e418cb60ea"}}, Content: "{\"wss://nostr-pub.wellorder.net\":{\"read\":true,\"write\":true},\"wss://nostr.bitcoiner.social\":{\"read\":false,\"write\":true},\"wss://expensive-relay.fiatjaf.com\":{\"read\":true,\"write\":true},\"wss://relayer.fiatjaf.com\":{\"read\":true,\"write\":true},\"wss://relay.bitid.nz\":{\"read\":true,\"write\":true},\"wss://nostr.rocks\":{\"read\":true,\"write\":true}}", Sig: "811355d3484d375df47581cb5d66bed05002c2978894098304f20b595e571b7e01b2efd906c5650080ffe49cf1c62b36715698e9d88b9e8be43029a2f3fa66be"}},
|
ExpectedEnvelope: &EventEnvelope{Event: Event{Kind: 3, ID: "9e662bdd7d8abc40b5b15ee1ff5e9320efc87e9274d8d440c58e6eed2dddfbe2", PubKey: "373ebe3d45ec91977296a178d9f19f326c70631d2a1b0bbba5c5ecc2eb53b9e7", CreatedAt: 1644844224, Tags: Tags{Tag{"p", "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d"}, Tag{"e", "75fc5ac2487363293bd27fb0d14fb966477d0f1dbc6361d37806a6a740eda91e"}, Tag{"p", "46d0dfd3a724a302ca9175163bdf788f3606b3fd1bb12d5fe055d1e418cb60ea"}}, Content: "{\"wss://nostr-pub.wellorder.net\":{\"read\":true,\"write\":true},\"wss://nostr.bitcoiner.social\":{\"read\":false,\"write\":true},\"wss://expensive-relay.fiatjaf.com\":{\"read\":true,\"write\":true},\"wss://relayer.fiatjaf.com\":{\"read\":true,\"write\":true},\"wss://relay.bitid.nz\":{\"read\":true,\"write\":true},\"wss://nostr.rocks\":{\"read\":true,\"write\":true}}", Sig: "811355d3484d375df47581cb5d66bed05002c2978894098304f20b595e571b7e01b2efd906c5650080ffe49cf1c62b36715698e9d88b9e8be43029a2f3fa66be"}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "NOTICE envelope",
|
Name: "NOTICE envelope",
|
||||||
Message: []byte(`["NOTICE","kjasbdlasvdluiasvd\"kjasbdksab\\d"]`),
|
Message: `["NOTICE","kjasbdlasvdluiasvd\"kjasbdksab\\d"]`,
|
||||||
ExpectedEnvelope: ptr(NoticeEnvelope("kjasbdlasvdluiasvd\"kjasbdksab\\d")),
|
ExpectedEnvelope: ptr(NoticeEnvelope("kjasbdlasvdluiasvd\"kjasbdksab\\d")),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "EOSE envelope",
|
Name: "EOSE envelope",
|
||||||
Message: []byte(`["EOSE","kjasbdlasvdluiasvd\"kjasbdksab\\d"]`),
|
Message: `["EOSE","kjasbdlasvdluiasvd\"kjasbdksab\\d"]`,
|
||||||
ExpectedEnvelope: ptr(EOSEEnvelope("kjasbdlasvdluiasvd\"kjasbdksab\\d")),
|
ExpectedEnvelope: ptr(EOSEEnvelope("kjasbdlasvdluiasvd\"kjasbdksab\\d")),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "COUNT envelope",
|
Name: "COUNT envelope",
|
||||||
Message: []byte(`["COUNT","z",{"count":12}]`),
|
Message: `["COUNT","z",{"count":12}]`,
|
||||||
ExpectedEnvelope: &CountEnvelope{SubscriptionID: "z", Count: ptr(int64(12))},
|
ExpectedEnvelope: &CountEnvelope{SubscriptionID: "z", Count: ptr(int64(12))},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "COUNT envelope with HLL",
|
Name: "COUNT envelope with HLL",
|
||||||
Message: []byte(`["COUNT","sub1",{"count":42, "hll": "0100000101000000000000040000000001020000000002000000000200000003000002040000000101020001010000000000000007000004010000000200040000020400000000000102000002000004010000010000000301000102030002000301000300010000070000000001000004000102010000000400010002000000000103000100010001000001040100020001000000000000010000020000000000030100000001000400010000000000000901010100000000040000000b030000010100010000010000010000000003000000000000010003000100020000000000010000010100000100000104000200030001000300000001000101000102"}]`),
|
Message: `["COUNT","sub1",{"count":42, "hll": "0100000101000000000000040000000001020000000002000000000200000003000002040000000101020001010000000000000007000004010000000200040000020400000000000102000002000004010000010000000301000102030002000301000300010000070000000001000004000102010000000400010002000000000103000100010001000001040100020001000000000000010000020000000000030100000001000400010000000000000901010100000000040000000b030000010100010000010000010000000003000000000000010003000100020000000000010000010100000100000104000200030001000300000001000101000102"}]`,
|
||||||
ExpectedEnvelope: &CountEnvelope{SubscriptionID: "sub1", Count: ptr(int64(42)), HyperLogLog: []byte{1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 2, 4, 0, 0, 0, 1, 1, 2, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 4, 1, 0, 0, 0, 2, 0, 4, 0, 0, 2, 4, 0, 0, 0, 0, 0, 1, 2, 0, 0, 2, 0, 0, 4, 1, 0, 0, 1, 0, 0, 0, 3, 1, 0, 1, 2, 3, 0, 2, 0, 3, 1, 0, 3, 0, 1, 0, 0, 7, 0, 0, 0, 0, 1, 0, 0, 4, 0, 1, 2, 1, 0, 0, 0, 4, 0, 1, 0, 2, 0, 0, 0, 0, 1, 3, 0, 1, 0, 1, 0, 1, 0, 0, 1, 4, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 9, 1, 1, 1, 0, 0, 0, 0, 4, 0, 0, 0, 11, 3, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 1, 0, 3, 0, 1, 0, 2, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 4, 0, 2, 0, 3, 0, 1, 0, 3, 0, 0, 0, 1, 0, 1, 1, 0, 1, 2}},
|
ExpectedEnvelope: &CountEnvelope{SubscriptionID: "sub1", Count: ptr(int64(42)), HyperLogLog: []byte{1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 2, 4, 0, 0, 0, 1, 1, 2, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 4, 1, 0, 0, 0, 2, 0, 4, 0, 0, 2, 4, 0, 0, 0, 0, 0, 1, 2, 0, 0, 2, 0, 0, 4, 1, 0, 0, 1, 0, 0, 0, 3, 1, 0, 1, 2, 3, 0, 2, 0, 3, 1, 0, 3, 0, 1, 0, 0, 7, 0, 0, 0, 0, 1, 0, 0, 4, 0, 1, 2, 1, 0, 0, 0, 4, 0, 1, 0, 2, 0, 0, 0, 0, 1, 3, 0, 1, 0, 1, 0, 1, 0, 0, 1, 4, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 9, 1, 1, 1, 0, 0, 0, 0, 4, 0, 0, 0, 11, 3, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 1, 0, 3, 0, 1, 0, 2, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 4, 0, 2, 0, 3, 0, 1, 0, 3, 0, 0, 0, 1, 0, 1, 1, 0, 1, 2}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "OK envelope success",
|
Name: "OK envelope success",
|
||||||
Message: []byte(`["OK","3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefaaaaa",true,""]`),
|
Message: `["OK","3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefaaaaa",true,""]`,
|
||||||
ExpectedEnvelope: &OKEnvelope{EventID: "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefaaaaa", OK: true, Reason: ""},
|
ExpectedEnvelope: &OKEnvelope{EventID: "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefaaaaa", OK: true, Reason: ""},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "OK envelope failure",
|
Name: "OK envelope failure",
|
||||||
Message: []byte(`["OK","3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefaaaaa",false,"error: could not connect to the database"]`),
|
Message: `["OK","3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefaaaaa",false,"error: could not connect to the database"]`,
|
||||||
ExpectedEnvelope: &OKEnvelope{EventID: "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefaaaaa", OK: false, Reason: "error: could not connect to the database"},
|
ExpectedEnvelope: &OKEnvelope{EventID: "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefaaaaa", OK: false, Reason: "error: could not connect to the database"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "CLOSED envelope with underscore",
|
Name: "CLOSED envelope with underscore",
|
||||||
Message: []byte(`["CLOSED","_","error: something went wrong"]`),
|
Message: `["CLOSED","_","error: something went wrong"]`,
|
||||||
ExpectedEnvelope: &ClosedEnvelope{SubscriptionID: "_", Reason: "error: something went wrong"},
|
ExpectedEnvelope: &ClosedEnvelope{SubscriptionID: "_", Reason: "error: something went wrong"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "CLOSED envelope with colon",
|
Name: "CLOSED envelope with colon",
|
||||||
Message: []byte(`["CLOSED",":1","auth-required: take a selfie and send it to the CIA"]`),
|
Message: `["CLOSED",":1","auth-required: take a selfie and send it to the CIA"]`,
|
||||||
ExpectedEnvelope: &ClosedEnvelope{SubscriptionID: ":1", Reason: "auth-required: take a selfie and send it to the CIA"},
|
ExpectedEnvelope: &ClosedEnvelope{SubscriptionID: ":1", Reason: "auth-required: take a selfie and send it to the CIA"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "AUTH envelope with challenge",
|
Name: "AUTH envelope with challenge",
|
||||||
Message: []byte(`["AUTH","kjsabdlasb aslkd kasndkad \"as.kdnbskadb"]`),
|
Message: `["AUTH","kjsabdlasb aslkd kasndkad \"as.kdnbskadb"]`,
|
||||||
ExpectedEnvelope: &AuthEnvelope{Challenge: ptr("kjsabdlasb aslkd kasndkad \"as.kdnbskadb")},
|
ExpectedEnvelope: &AuthEnvelope{Challenge: ptr("kjsabdlasb aslkd kasndkad \"as.kdnbskadb")},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "AUTH envelope with event",
|
Name: "AUTH envelope with event",
|
||||||
Message: []byte(`["AUTH",{"kind":1,"id":"ae1fc7154296569d87ca4663f6bdf448c217d1590d28c85d158557b8b43b4d69","pubkey":"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798","created_at":1683660344,"tags":[],"content":"hello world","sig":"94e10947814b1ebe38af42300ecd90c7642763896c4f69506ae97bfdf54eec3c0c21df96b7d95daa74ff3d414b1d758ee95fc258125deebc31df0c6ba9396a51"}]`),
|
Message: `["AUTH",{"kind":1,"id":"ae1fc7154296569d87ca4663f6bdf448c217d1590d28c85d158557b8b43b4d69","pubkey":"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798","created_at":1683660344,"tags":[],"content":"hello world","sig":"94e10947814b1ebe38af42300ecd90c7642763896c4f69506ae97bfdf54eec3c0c21df96b7d95daa74ff3d414b1d758ee95fc258125deebc31df0c6ba9396a51"}]`,
|
||||||
ExpectedEnvelope: &AuthEnvelope{Event: Event{Kind: 1, ID: "ae1fc7154296569d87ca4663f6bdf448c217d1590d28c85d158557b8b43b4d69", PubKey: "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", CreatedAt: 1683660344, Tags: Tags{}, Content: "hello world", Sig: "94e10947814b1ebe38af42300ecd90c7642763896c4f69506ae97bfdf54eec3c0c21df96b7d95daa74ff3d414b1d758ee95fc258125deebc31df0c6ba9396a51"}},
|
ExpectedEnvelope: &AuthEnvelope{Event: Event{Kind: 1, ID: "ae1fc7154296569d87ca4663f6bdf448c217d1590d28c85d158557b8b43b4d69", PubKey: "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", CreatedAt: 1683660344, Tags: Tags{}, Content: "hello world", Sig: "94e10947814b1ebe38af42300ecd90c7642763896c4f69506ae97bfdf54eec3c0c21df96b7d95daa74ff3d414b1d758ee95fc258125deebc31df0c6ba9396a51"}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "REQ envelope",
|
Name: "REQ envelope",
|
||||||
Message: []byte(`["REQ","million", {"kinds": [1]}, {"kinds": [30023 ], "#d": ["buteko", "batuke"]}]`),
|
Message: `["REQ","million", {"kinds": [1]}, {"kinds": [30023 ], "#d": ["buteko", "batuke"]}]`,
|
||||||
ExpectedEnvelope: &ReqEnvelope{SubscriptionID: "million", Filters: Filters{{Kinds: []int{1}}, {Kinds: []int{30023}, Tags: TagMap{"d": []string{"buteko", "batuke"}}}}},
|
ExpectedEnvelope: &ReqEnvelope{SubscriptionID: "million", Filters: Filters{{Kinds: []int{1}}, {Kinds: []int{30023}, Tags: TagMap{"d": []string{"buteko", "batuke"}}}}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "CLOSE envelope",
|
Name: "CLOSE envelope",
|
||||||
Message: []byte(`["CLOSE","subscription123"]`),
|
Message: `["CLOSE","subscription123"]`,
|
||||||
ExpectedEnvelope: ptr(CloseEnvelope("subscription123")),
|
ExpectedEnvelope: ptr(CloseEnvelope("subscription123")),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -168,8 +170,8 @@ func TestParseMessagesFromFile(t *testing.T) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
standardEnvelope := ParseMessage(line)
|
standardEnvelope := ParseMessage(string(line))
|
||||||
sonicEnvelope, err := smp.ParseMessage(line)
|
sonicEnvelope, err := smp.ParseMessage(string(line))
|
||||||
|
|
||||||
if standardEnvelope == nil {
|
if standardEnvelope == nil {
|
||||||
require.Nil(t, sonicEnvelope, "line %d: standard parser returned nil but sonic parser didn't", lineNum)
|
require.Nil(t, sonicEnvelope, "line %d: standard parser returned nil but sonic parser didn't", lineNum)
|
||||||
|
25
helpers.go
25
helpers.go
@ -1,7 +1,6 @@
|
|||||||
package nostr
|
package nostr
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@ -119,35 +118,39 @@ func isLowerHex(thing string) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractSubID(jsonStr []byte) string {
|
func extractSubID(jsonStr string) string {
|
||||||
// look for "EVENT" pattern
|
// look for "EVENT" pattern
|
||||||
start := bytes.Index(jsonStr, []byte(`"EVENT"`))
|
start := strings.Index(jsonStr, `"EVENT"`)
|
||||||
if start == -1 {
|
if start == -1 {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// move to the next quote
|
// move to the next quote
|
||||||
offset := bytes.Index(jsonStr[start+7:], []byte{'"'})
|
offset := strings.Index(jsonStr[start+7:], `"`)
|
||||||
|
if offset == -1 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
start += 7 + offset + 1
|
start += 7 + offset + 1
|
||||||
|
|
||||||
// find the ending quote
|
// find the ending quote
|
||||||
end := bytes.Index(jsonStr[start:], []byte{'"'})
|
end := strings.Index(jsonStr[start:], `"`)
|
||||||
|
|
||||||
// get the contents
|
// get the contents
|
||||||
return unsafe.String(unsafe.SliceData(jsonStr[start:start+end]), end)
|
return jsonStr[start : start+end]
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractEventID(jsonStr []byte) string {
|
func extractEventID(jsonStr string) string {
|
||||||
// look for "id": pattern
|
// look for "id" pattern
|
||||||
start := bytes.Index(jsonStr, []byte(`"id":`))
|
start := strings.Index(jsonStr, `"id"`)
|
||||||
if start == -1 {
|
if start == -1 {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// move to the next quote
|
// move to the next quote
|
||||||
offset := bytes.Index(jsonStr[start+4:], []byte{'"'})
|
offset := strings.IndexRune(jsonStr[start+4:], '"')
|
||||||
start += 4 + offset + 1
|
start += 4 + offset + 1
|
||||||
|
|
||||||
// get 64 characters of the id
|
// get 64 characters of the id
|
||||||
return unsafe.String(unsafe.SliceData(jsonStr[start:start+64]), 64)
|
return jsonStr[start : start+64]
|
||||||
}
|
}
|
||||||
|
@ -27,18 +27,18 @@ func TestIsLower(t *testing.T) {
|
|||||||
|
|
||||||
func TestIDExtract(t *testing.T) {
|
func TestIDExtract(t *testing.T) {
|
||||||
{
|
{
|
||||||
data := []byte(`{"kind":1,"id":"6b5988e9471fa340880a40df815befc69c901420facfb670acd8308012088f16","pubkey":"67ada8e344532cbf82f0e702472e24c7896e0e1c96235eacbaaa4b8616052171","created_at":1736909072,"tags":[["e","cfdf18b78527455097515545be4ccbe17e9b88f64539a566c632e405e2c0d08a","","root"],["e","f1ec9c301383be082f1860f7e24e49164d855bfab67f8e5c3ed17f6f3f867cca","","reply"],["p","1afe0c74e3d7784eba93a5e3fa554a6eeb01928d12739ae8ba4832786808e36d"],["p","8aa642e26e65072139e10db59646a89aa7538a59965aab3ed89191d71967d6c3"],["p","f4d89779148ccd245c8d50914a284fd62d97cb0fb68b797a70f24a172b522db9"],["p","18905d0a5d623ab81a98ba98c582bd5f57f2506c6b808905fc599d5a0b229b08"],["p","9a0e2043afaa056a12b8bbe77ac4c3185c0e2bc46b12aac158689144323c0e3c"],["p","45f195cffcb8c9724efc248f0507a2fb65b579dfabe7cd35398598163cab7627"]],"content":"🫡","sig":"d21aaf43963b07a3cb5f85ac8809c2b2e4dd3269195f4d810e1b7650895178fe01cf685ab3ee93f193cdde1f8d17419ff05332c6e3fc7429bbbe3d70016b8638"}`)
|
data := `{"kind":1,"id":"6b5988e9471fa340880a40df815befc69c901420facfb670acd8308012088f16","pubkey":"67ada8e344532cbf82f0e702472e24c7896e0e1c96235eacbaaa4b8616052171","created_at":1736909072,"tags":[["e","cfdf18b78527455097515545be4ccbe17e9b88f64539a566c632e405e2c0d08a","","root"],["e","f1ec9c301383be082f1860f7e24e49164d855bfab67f8e5c3ed17f6f3f867cca","","reply"],["p","1afe0c74e3d7784eba93a5e3fa554a6eeb01928d12739ae8ba4832786808e36d"],["p","8aa642e26e65072139e10db59646a89aa7538a59965aab3ed89191d71967d6c3"],["p","f4d89779148ccd245c8d50914a284fd62d97cb0fb68b797a70f24a172b522db9"],["p","18905d0a5d623ab81a98ba98c582bd5f57f2506c6b808905fc599d5a0b229b08"],["p","9a0e2043afaa056a12b8bbe77ac4c3185c0e2bc46b12aac158689144323c0e3c"],["p","45f195cffcb8c9724efc248f0507a2fb65b579dfabe7cd35398598163cab7627"]],"content":"🫡","sig":"d21aaf43963b07a3cb5f85ac8809c2b2e4dd3269195f4d810e1b7650895178fe01cf685ab3ee93f193cdde1f8d17419ff05332c6e3fc7429bbbe3d70016b8638"}`
|
||||||
require.Equal(t, "6b5988e9471fa340880a40df815befc69c901420facfb670acd8308012088f16", extractEventID(data))
|
require.Equal(t, "6b5988e9471fa340880a40df815befc69c901420facfb670acd8308012088f16", extractEventID(data))
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
data := []byte(`{"kind":1,"pubkey":"67ada8e344532cbf82f0e702472e24c7896e0e1c96235eacbaaa4b8616052171","created_at":1736909072,"tags":[["e","cfdf18b78527455097515545be4ccbe17e9b88f64539a566c632e405e2c0d08a","","root"],["e","f1ec9c301383be082f1860f7e24e49164d855bfab67f8e5c3ed17f6f3f867cca","","reply"],["p","1afe0c74e3d7784eba93a5e3fa554a6eeb01928d12739ae8ba4832786808e36d"],["p","8aa642e26e65072139e10db59646a89aa7538a59965aab3ed89191d71967d6c3"],["p","f4d89779148ccd245c8d50914a284fd62d97cb0fb68b797a70f24a172b522db9"],["p","18905d0a5d623ab81a98ba98c582bd5f57f2506c6b808905fc599d5a0b229b08"],["p","9a0e2043afaa056a12b8bbe77ac4c3185c0e2bc46b12aac158689144323c0e3c"],["p","45f195cffcb8c9724efc248f0507a2fb65b579dfabe7cd35398598163cab7627"]],"content":"🫡","sig":"d21aaf43963b07a3cb5f85ac8809c2b2e4dd3269195f4d810e1b7650895178fe01cf685ab3ee93f193cdde1f8d17419ff05332c6e3fc7429bbbe3d70016b8638","id": "6b5988e9471fa340880a40df815befc69c901420facfb670acd8308012088f16" }`)
|
data := `{"kind":1,"pubkey":"67ada8e344532cbf82f0e702472e24c7896e0e1c96235eacbaaa4b8616052171","created_at":1736909072,"tags":[["e","cfdf18b78527455097515545be4ccbe17e9b88f64539a566c632e405e2c0d08a","","root"],["e","f1ec9c301383be082f1860f7e24e49164d855bfab67f8e5c3ed17f6f3f867cca","","reply"],["p","1afe0c74e3d7784eba93a5e3fa554a6eeb01928d12739ae8ba4832786808e36d"],["p","8aa642e26e65072139e10db59646a89aa7538a59965aab3ed89191d71967d6c3"],["p","f4d89779148ccd245c8d50914a284fd62d97cb0fb68b797a70f24a172b522db9"],["p","18905d0a5d623ab81a98ba98c582bd5f57f2506c6b808905fc599d5a0b229b08"],["p","9a0e2043afaa056a12b8bbe77ac4c3185c0e2bc46b12aac158689144323c0e3c"],["p","45f195cffcb8c9724efc248f0507a2fb65b579dfabe7cd35398598163cab7627"]],"content":"🫡","sig":"d21aaf43963b07a3cb5f85ac8809c2b2e4dd3269195f4d810e1b7650895178fe01cf685ab3ee93f193cdde1f8d17419ff05332c6e3fc7429bbbe3d70016b8638","id": "6b5988e9471fa340880a40df815befc69c901420facfb670acd8308012088f16" }`
|
||||||
require.Equal(t, "6b5988e9471fa340880a40df815befc69c901420facfb670acd8308012088f16", extractEventID(data))
|
require.Equal(t, "6b5988e9471fa340880a40df815befc69c901420facfb670acd8308012088f16", extractEventID(data))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSubIdExtract(t *testing.T) {
|
func TestSubIdExtract(t *testing.T) {
|
||||||
{
|
{
|
||||||
data := []byte(`["EVENT", "xxz" ,{"kind":1,"id":"6b5988e9471fa340880a40df815befc69c901420facfb670acd8308012088f16","pubkey":"67ada8e344532cbf82f0e702472e24c7896e0e1c96235eacbaaa4b8616052171","created_at":1736909072,"tags":[["e","cfdf18b78527455097515545be4ccbe17e9b88f64539a566c632e405e2c0d08a","","root"],["e","f1ec9c301383be082f1860f7e24e49164d855bfab67f8e5c3ed17f6f3f867cca","","reply"],["p","1afe0c74e3d7784eba93a5e3fa554a6eeb01928d12739ae8ba4832786808e36d"],["p","8aa642e26e65072139e10db59646a89aa7538a59965aab3ed89191d71967d6c3"],["p","f4d89779148ccd245c8d50914a284fd62d97cb0fb68b797a70f24a172b522db9"],["p","18905d0a5d623ab81a98ba98c582bd5f57f2506c6b808905fc599d5a0b229b08"],["p","9a0e2043afaa056a12b8bbe77ac4c3185c0e2bc46b12aac158689144323c0e3c"],["p","45f195cffcb8c9724efc248f0507a2fb65b579dfabe7cd35398598163cab7627"]],"content":"🫡","sig":"d21aaf43963b07a3cb5f85ac8809c2b2e4dd3269195f4d810e1b7650895178fe01cf685ab3ee93f193cdde1f8d17419ff05332c6e3fc7429bbbe3d70016b8638"}]`)
|
data := `["EVENT", "xxz" ,{"kind":1,"id":"6b5988e9471fa340880a40df815befc69c901420facfb670acd8308012088f16","pubkey":"67ada8e344532cbf82f0e702472e24c7896e0e1c96235eacbaaa4b8616052171","created_at":1736909072,"tags":[["e","cfdf18b78527455097515545be4ccbe17e9b88f64539a566c632e405e2c0d08a","","root"],["e","f1ec9c301383be082f1860f7e24e49164d855bfab67f8e5c3ed17f6f3f867cca","","reply"],["p","1afe0c74e3d7784eba93a5e3fa554a6eeb01928d12739ae8ba4832786808e36d"],["p","8aa642e26e65072139e10db59646a89aa7538a59965aab3ed89191d71967d6c3"],["p","f4d89779148ccd245c8d50914a284fd62d97cb0fb68b797a70f24a172b522db9"],["p","18905d0a5d623ab81a98ba98c582bd5f57f2506c6b808905fc599d5a0b229b08"],["p","9a0e2043afaa056a12b8bbe77ac4c3185c0e2bc46b12aac158689144323c0e3c"],["p","45f195cffcb8c9724efc248f0507a2fb65b579dfabe7cd35398598163cab7627"]],"content":"🫡","sig":"d21aaf43963b07a3cb5f85ac8809c2b2e4dd3269195f4d810e1b7650895178fe01cf685ab3ee93f193cdde1f8d17419ff05332c6e3fc7429bbbe3d70016b8638"}]`
|
||||||
require.Equal(t, "xxz", extractSubID(data))
|
require.Equal(t, "xxz", extractSubID(data))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,8 @@ package nip77
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
"github.com/mailru/easyjson"
|
"github.com/mailru/easyjson"
|
||||||
jwriter "github.com/mailru/easyjson/jwriter"
|
jwriter "github.com/mailru/easyjson/jwriter"
|
||||||
@ -10,28 +12,28 @@ import (
|
|||||||
"github.com/tidwall/gjson"
|
"github.com/tidwall/gjson"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ParseNegMessage(message []byte) nostr.Envelope {
|
func ParseNegMessage(message string) nostr.Envelope {
|
||||||
firstComma := bytes.Index(message, []byte{','})
|
firstComma := strings.Index(message, ",")
|
||||||
if firstComma == -1 {
|
if firstComma == -1 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
label := message[0:firstComma]
|
label := message[0:firstComma]
|
||||||
|
|
||||||
var v nostr.Envelope
|
var v nostr.Envelope
|
||||||
switch {
|
switch label {
|
||||||
case bytes.Contains(label, []byte("NEG-MSG")):
|
case "NEG-MSG":
|
||||||
v = &MessageEnvelope{}
|
v = &MessageEnvelope{}
|
||||||
case bytes.Contains(label, []byte("NEG-OPEN")):
|
case "NEG-OPEN":
|
||||||
v = &OpenEnvelope{}
|
v = &OpenEnvelope{}
|
||||||
case bytes.Contains(label, []byte("NEG-ERR")):
|
case "NEG-ERR":
|
||||||
v = &ErrorEnvelope{}
|
v = &ErrorEnvelope{}
|
||||||
case bytes.Contains(label, []byte("NEG-CLOSE")):
|
case "NEG-CLOSE":
|
||||||
v = &CloseEnvelope{}
|
v = &CloseEnvelope{}
|
||||||
default:
|
default:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := v.UnmarshalJSON(message); err != nil {
|
if err := v.FromJSON(message); err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return v
|
return v
|
||||||
@ -56,8 +58,8 @@ func (v OpenEnvelope) String() string {
|
|||||||
return string(b)
|
return string(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *OpenEnvelope) UnmarshalJSON(data []byte) error {
|
func (v *OpenEnvelope) FromJSON(data string) error {
|
||||||
r := gjson.ParseBytes(data)
|
r := gjson.Parse(data)
|
||||||
arr := r.Array()
|
arr := r.Array()
|
||||||
if len(arr) != 4 {
|
if len(arr) != 4 {
|
||||||
return fmt.Errorf("failed to decode NEG-OPEN envelope")
|
return fmt.Errorf("failed to decode NEG-OPEN envelope")
|
||||||
@ -65,7 +67,7 @@ func (v *OpenEnvelope) UnmarshalJSON(data []byte) error {
|
|||||||
|
|
||||||
v.SubscriptionID = arr[1].Str
|
v.SubscriptionID = arr[1].Str
|
||||||
v.Message = arr[3].Str
|
v.Message = arr[3].Str
|
||||||
return easyjson.Unmarshal([]byte(arr[2].Raw), &v.Filter)
|
return easyjson.Unmarshal(unsafe.Slice(unsafe.StringData(arr[2].Raw), len(arr[2].Raw)), &v.Filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v OpenEnvelope) MarshalJSON() ([]byte, error) {
|
func (v OpenEnvelope) MarshalJSON() ([]byte, error) {
|
||||||
@ -97,8 +99,8 @@ func (v MessageEnvelope) String() string {
|
|||||||
return string(b)
|
return string(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *MessageEnvelope) UnmarshalJSON(data []byte) error {
|
func (v *MessageEnvelope) FromJSON(data string) error {
|
||||||
r := gjson.ParseBytes(data)
|
r := gjson.Parse(data)
|
||||||
arr := r.Array()
|
arr := r.Array()
|
||||||
if len(arr) < 3 {
|
if len(arr) < 3 {
|
||||||
return fmt.Errorf("failed to decode NEG-MSG envelope")
|
return fmt.Errorf("failed to decode NEG-MSG envelope")
|
||||||
@ -130,8 +132,8 @@ func (v CloseEnvelope) String() string {
|
|||||||
return string(b)
|
return string(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *CloseEnvelope) UnmarshalJSON(data []byte) error {
|
func (v *CloseEnvelope) FromJSON(data string) error {
|
||||||
r := gjson.ParseBytes(data)
|
r := gjson.Parse(data)
|
||||||
arr := r.Array()
|
arr := r.Array()
|
||||||
if len(arr) < 2 {
|
if len(arr) < 2 {
|
||||||
return fmt.Errorf("failed to decode NEG-CLOSE envelope")
|
return fmt.Errorf("failed to decode NEG-CLOSE envelope")
|
||||||
@ -159,8 +161,8 @@ func (v ErrorEnvelope) String() string {
|
|||||||
return string(b)
|
return string(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *ErrorEnvelope) UnmarshalJSON(data []byte) error {
|
func (v *ErrorEnvelope) FromJSON(data string) error {
|
||||||
r := gjson.ParseBytes(data)
|
r := gjson.Parse(data)
|
||||||
arr := r.Array()
|
arr := r.Array()
|
||||||
if len(arr) < 3 {
|
if len(arr) < 3 {
|
||||||
return fmt.Errorf("failed to decode NEG-ERROR envelope")
|
return fmt.Errorf("failed to decode NEG-ERROR envelope")
|
||||||
|
@ -20,7 +20,7 @@ func FetchIDsOnly(
|
|||||||
result := make(chan error)
|
result := make(chan error)
|
||||||
|
|
||||||
var r *nostr.Relay
|
var r *nostr.Relay
|
||||||
r, err := nostr.RelayConnect(ctx, url, nostr.WithCustomHandler(func(data []byte) {
|
r, err := nostr.RelayConnect(ctx, url, nostr.WithCustomHandler(func(data string) {
|
||||||
envelope := ParseNegMessage(data)
|
envelope := ParseNegMessage(data)
|
||||||
if envelope == nil {
|
if envelope == nil {
|
||||||
return
|
return
|
||||||
|
@ -49,7 +49,7 @@ func NegentropySync(
|
|||||||
result := make(chan error)
|
result := make(chan error)
|
||||||
|
|
||||||
var r *nostr.Relay
|
var r *nostr.Relay
|
||||||
r, err = nostr.RelayConnect(ctx, url, nostr.WithCustomHandler(func(data []byte) {
|
r, err = nostr.RelayConnect(ctx, url, nostr.WithCustomHandler(func(data string) {
|
||||||
envelope := ParseNegMessage(data)
|
envelope := ParseNegMessage(data)
|
||||||
if envelope == nil {
|
if envelope == nil {
|
||||||
return
|
return
|
||||||
|
21
relay.go
21
relay.go
@ -13,6 +13,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
"github.com/puzpuzpuz/xsync/v3"
|
"github.com/puzpuzpuz/xsync/v3"
|
||||||
)
|
)
|
||||||
@ -35,7 +36,7 @@ type Relay struct {
|
|||||||
|
|
||||||
challenge string // NIP-42 challenge, we only keep the last
|
challenge string // NIP-42 challenge, we only keep the last
|
||||||
noticeHandler func(string) // NIP-01 NOTICEs
|
noticeHandler func(string) // NIP-01 NOTICEs
|
||||||
customHandler func([]byte) // nonstandard unparseable messages
|
customHandler func(string) // nonstandard unparseable messages
|
||||||
okCallbacks *xsync.MapOf[string, func(bool, string)]
|
okCallbacks *xsync.MapOf[string, func(bool, string)]
|
||||||
writeQueue chan writeRequest
|
writeQueue chan writeRequest
|
||||||
subscriptionChannelCloseQueue chan *Subscription
|
subscriptionChannelCloseQueue chan *Subscription
|
||||||
@ -104,7 +105,7 @@ func (nh WithNoticeHandler) ApplyRelayOption(r *Relay) {
|
|||||||
|
|
||||||
// WithCustomHandler must be a function that handles any relay message that couldn't be
|
// WithCustomHandler must be a function that handles any relay message that couldn't be
|
||||||
// parsed as a standard envelope.
|
// parsed as a standard envelope.
|
||||||
type WithCustomHandler func(data []byte)
|
type WithCustomHandler func(data string)
|
||||||
|
|
||||||
func (ch WithCustomHandler) ApplyRelayOption(r *Relay) {
|
func (ch WithCustomHandler) ApplyRelayOption(r *Relay) {
|
||||||
r.customHandler = ch
|
r.customHandler = ch
|
||||||
@ -212,6 +213,7 @@ func (r *Relay) ConnectWithTLS(ctx context.Context, tlsConfig *tls.Config) error
|
|||||||
// general message reader loop
|
// general message reader loop
|
||||||
go func() {
|
go func() {
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
|
mp := NewMessageParser()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
buf.Reset()
|
buf.Reset()
|
||||||
@ -222,7 +224,8 @@ func (r *Relay) ConnectWithTLS(ctx context.Context, tlsConfig *tls.Config) error
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
message := buf.Bytes()
|
msgb := buf.Bytes()
|
||||||
|
message := unsafe.String(unsafe.SliceData(msgb), len(msgb))
|
||||||
debugLogf("{%s} received %v\n", r.URL, message)
|
debugLogf("{%s} received %v\n", r.URL, message)
|
||||||
|
|
||||||
// if this is an "EVENT" we will have this preparser logic that should speed things up a little
|
// if this is an "EVENT" we will have this preparser logic that should speed things up a little
|
||||||
@ -235,9 +238,9 @@ func (r *Relay) ConnectWithTLS(ctx context.Context, tlsConfig *tls.Config) error
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
envelope := ParseMessage(message)
|
envelope, err := mp.ParseMessage(message)
|
||||||
if envelope == nil {
|
if envelope == nil {
|
||||||
if r.customHandler != nil {
|
if r.customHandler != nil && err == UnknownLabel {
|
||||||
r.customHandler(message)
|
r.customHandler(message)
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
@ -258,13 +261,13 @@ func (r *Relay) ConnectWithTLS(ctx context.Context, tlsConfig *tls.Config) error
|
|||||||
r.challenge = *env.Challenge
|
r.challenge = *env.Challenge
|
||||||
case *EventEnvelope:
|
case *EventEnvelope:
|
||||||
// we already have the subscription from the pre-check above, so we can just reuse it
|
// we already have the subscription from the pre-check above, so we can just reuse it
|
||||||
if subscription == nil {
|
if sub == nil {
|
||||||
// InfoLogger.Printf("{%s} no subscription with id '%s'\n", r.URL, *env.SubscriptionID)
|
// InfoLogger.Printf("{%s} no subscription with id '%s'\n", r.URL, *env.SubscriptionID)
|
||||||
continue
|
continue
|
||||||
} else {
|
} else {
|
||||||
// check if the event matches the desired filter, ignore otherwise
|
// check if the event matches the desired filter, ignore otherwise
|
||||||
if !subscription.match(&env.Event) {
|
if !sub.match(&env.Event) {
|
||||||
InfoLogger.Printf("{%s} filter does not match: %v ~ %v\n", r.URL, subscription.Filters, env.Event)
|
InfoLogger.Printf("{%s} filter does not match: %v ~ %v\n", r.URL, sub.Filters, env.Event)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,7 +280,7 @@ func (r *Relay) ConnectWithTLS(ctx context.Context, tlsConfig *tls.Config) error
|
|||||||
}
|
}
|
||||||
|
|
||||||
// dispatch this to the internal .events channel of the subscription
|
// dispatch this to the internal .events channel of the subscription
|
||||||
subscription.dispatchEvent(&env.Event)
|
sub.dispatchEvent(&env.Event)
|
||||||
}
|
}
|
||||||
case *EOSEEnvelope:
|
case *EOSEEnvelope:
|
||||||
if subscription, ok := r.Subscriptions.Load(subIdToSerial(string(*env))); ok {
|
if subscription, ok := r.Subscriptions.Load(subIdToSerial(string(*env))); ok {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user