JuliaComputing / AMQPClient.jl

A Julia AMQP (Advanced Message Queuing Protocol) / RabbitMQ Client.
Other
39 stars 21 forks source link

Byte order for arguments #57

Closed mfalt closed 2 years ago

mfalt commented 2 years ago

I think there is something wrong with how https://github.com/JuliaComputing/AMQPClient.jl/ encodes extra arguments, but I cant figure out exactly what. You can try it yourself with something like queue_declare(CHANNEL, QUEUE_NAME, arguments=Dict{String,Any}("x-expires"=>12345)) which by rabbit gets interpreted as a much larger number (close to the max of an Int64. I get similar problems if i try to send an Int32 or Int16)

The pattern I can find seems to be that the bytes are in some reversed order. Two examples with n_julia => n_rabbit 12345 => 959447040 54321 => 835977216 If we look at the binary representations (32bit): 00000000000000000011000000111001 => 00111001001100000000000000000000 00000000000000001101010000110001 => 00110001110101000000000000000000

It seems that the conversion is something like

> bitstring(Int32(12345)) |> ( x -> String([x[25:32]...;x[17:24]...;x[9:16]...;x[1:8]...]) ) == bitstring(Int32(959447040))
true
> bitstring(Int32(54321)) |> ( x -> String([x[25:32]...;x[17:24]...;x[9:16]...;x[1:8]...]) ) == bitstring(Int32(835977216))
true

PS: Some more research seems to indicate that it is actually a case of endian-ness "AMQP uses network byte order for all numeric values", so bswap(Int32(12345)) == 959447040 and the following works: queue_declare(CHANNEL, QUEUE_NAME, arguments=Dict{String,Any}("x-expires"=>bswap(Int32(12345))))

Edit: Seems that there are a lot of calls to hton in the code, so it is probably just missing or done twice for integer arguments.

tanmaykm commented 2 years ago

This does seem like a mismatch in endian-ness, but I wonder where.

queue_declare transmits a MethodPayload here with the arguments. The payload gets converted first to a MethodFrame and then to a GenericFrame before getting sent, and in the process the arguments should get converted to network byte order here. The reverse happens while reading here.

But I could be missing something.

tanmaykm commented 2 years ago

Ah, I think I have found the issue. Which is that FieldValuePair is missing the byte order conversion, and queue_declare arguments are sent as field value pairs.

Will put up a PR in a bit.