So I'm trying to get the string representation of a JSON message in Golang. I just want to receive the messagepack encoded JSON, modify some values and send it back.
I haven't found an easy way to do it. Most of the times, I can't know in advance what is the structure of the JSON (apart from having JSON structure), so want I want to do is to receive the binary message. Decode it as a JSON, print it as a string to the standard output, modify the content, convert it to MessagePack again and send it back.
I've been looking at these two packages, but I don't know how to properly use them for a simple task like that:
So I will receive something like this:
DF 00 00 00 01 A7 6D 65 73 73 61 67 65 A3 48 69 21
I want to print this:
{"message": "Hi!"}
Modify the "Hi!":
{"message": "Hello Sir!"}
Send it as messagepack:
DF 00 00 00 01 A7 6D 65 73 73 61 67 65 AA 48 65 6C 6C 6F 20 53 69 72 21
Current Python code I'm trying to port to Golang:
def decode_msgpack(jsonData):
packedStuff = 0
for key in jsonData.keys():
if type(jsonData[key]) is bytes:
packedStuff += 1
try:
jsonData[key] = umsgpack.unpackb(jsonData[key])
except umsgpack.InvalidStringException:
try:
jsonData[key] = umsgpack.unpackb(jsonData[key], allow_invalid_utf8=True)
except umsgpack.InsufficientDataException:
print("[!] InsufficientDataException")
jsonData[key] = base64.b64encode(jsonData[key]).decode('utf-8')
else:
jsonData[key] = base64.b64encode(jsonData[key]).decode('utf-8')
if packedStuff > 0:
return decode_msgpack(jsonData)
else:
return jsonData
Using the codec library and assuming that {"message": "Hi"}
is a map, the code would look something like this.
package main
import (
"fmt"
"github.com/ugorji/go/codec"
)
func main() {
var data []byte
original := map[string]string{"message": "Hi!"}
enc := codec.NewEncoderBytes(&data, new(codec.MsgpackHandle))
if err := enc.Encode(&original); err != nil {
panic(err)
}
fmt.Printf("Encoded: ")
for _, b := range data {
fmt.Printf("%X ", b)
}
fmt.Printf("\n")
decoded := make(map[string]string)
dec := codec.NewDecoderBytes(data, new(codec.MsgpackHandle))
if err := dec.Decode(&decoded); err != nil {
panic(err)
}
fmt.Printf("Decoded: %v\n", decoded)
decoded["message"] = "Hello Sir!"
/* reinitialize the encoder */
enc = codec.NewEncoderBytes(&data, new(codec.MsgpackHandle))
if err := enc.Encode(&decoded); err != nil {
panic(err)
}
fmt.Printf("Encoded: ")
for _, b := range data {
fmt.Printf("%X ", b)
}
fmt.Printf("\n")
}
That said, if you get {"message": "Hi"}
as a JSON string, you can use codec to decode the JSON into a map, update the map and then re-encode it as msgpack.