Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ably-go should not convert []byte messages to strings #574

Open
amnonbc opened this issue Dec 22, 2022 · 5 comments · May be fixed by #581
Open

ably-go should not convert []byte messages to strings #574

amnonbc opened this issue Dec 22, 2022 · 5 comments · May be fixed by #581

Comments

@amnonbc
Copy link
Contributor

amnonbc commented Dec 22, 2022

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
}

┆Issue is synchronized with this Jira Task by Unito

@sync-by-unito
Copy link

sync-by-unito bot commented Dec 22, 2022

➤ Automation for Jira commented:

The link to the corresponding Jira issue is https://ably.atlassian.net/browse/SDK-3196

@sync-by-unito
Copy link

sync-by-unito bot commented Jan 4, 2023

➤ 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)
}

@amnonbc
Copy link
Contributor Author

amnonbc commented Jan 6, 2023

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/codec@v1.1.9/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)
	}
}

@amnonbc
Copy link
Contributor Author

amnonbc commented Jan 11, 2023

I added a bug report to ugorji/go#387

@amnonbc
Copy link
Contributor Author

amnonbc commented Mar 7, 2023

See #581 as a sample fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.

1 participant