ably-go
ably-go copied to clipboard
ably-go should not convert `[]byte` messages to strings
The code below send a message of type []byte.
But the subscriber receives the message of type string.
https://go.dev/play/p/VUqZbF7B6Wv
2022/12/22 14:03:06 sending message [1 2 3 4] of type []uint8
2022/12/22 14:03:06 Received message of type: string
According to the Spec (RSL6a) All messages received will be decoded automatically based on the encoding field and the payloads will be converted into the format they were originally sent using i.e. binary, string, or JSON
In this case the message was sent as []byte so should have been received as as []byte.
package main
import (
"context"
"github.com/ably/ably-go/ably"
"log"
"os"
)
func sub(client *ably.Realtime, done chan struct{}) {
channel := client.Channels.Get("quickstart")
_, err := channel.Subscribe(context.Background(), "greeting", func(msg *ably.Message) {
log.Printf("Received message %v of type: %T", msg.Data, msg.Data)
close(done)
})
if err != nil {
panic(err)
}
}
func main() {
key := os.Getenv("ABLY_KEY")
client, err := ably.NewRealtime(ably.WithKey(key))
if err != nil {
panic(err)
}
done := make(chan struct{})
go sub(client, done)
channel := client.Channels.Get("quickstart")
data := []byte{1, 2, 3, 4}
log.Printf("sending message %v of type %T", data, data)
err = channel.Publish(context.Background(), "greeting", data)
if err != nil {
panic(err)
}
<-done
}
➤ Automation for Jira commented:
The link to the corresponding Jira issue is https://ably.atlassian.net/browse/SDK-3196
➤ Amnon Cohen commented:
The problem is in the codec, as you can see in this failing test:
func TestSmallByteData(t *testing.T) {
src := []byte("abc")
encodedBytes, err := ablyutil.MarshalMsgpack(src)
assert.NoError(t, err)
var decoded interface{}
err = ablyutil.UnmarshalMsgpack(encodedBytes, &decoded)
assert.NoError(t, err)
assert.IsType(t, src, decoded)
}
func TestUnmarshallByte(t *testing.T) {
buf := []byte{
0xc4, // bin8
2, // len
'a', 'a', // bytes
}
var target interface{}
err := UnmarshalMsgpack(buf, &target)
require.NoError(t, err)
assert.IsType(t, []byte{}, target,
"bin8 should be decoded as []byte, but instead we got %T", target)
}
In github.com/ugorji/go/[email protected]/msgpack.go:494
case bd == mpBin8, bd == mpBin16, bd == mpBin32:
fauxUnionReadRawBytes(d, &d.d, n, d.h.RawToString)
which calls
func fauxUnionReadRawBytes(dr decDriver, d *Decoder, n *fauxUnion, rawToString bool) {
if rawToString {
n.v = valueTypeString
n.s = string(dr.DecodeBytes(d.b[:], true))
} else {
n.v = valueTypeBytes
n.l = dr.DecodeBytes(nil, false)
}
}
I added a bug report to https://github.com/ugorji/go/issues/387
See https://github.com/ably/ably-go/pull/581 as a sample fix.