ferristseng / rust-ipfs-api

IPFS HTTP client in Rust
Apache License 2.0
247 stars 68 forks source link

PubSub #55

Closed SionoiS closed 2 years ago

SionoiS commented 4 years ago

Hello!

I tried to send and receive messages locally but sending "hello world" I received "aGVsbG8gd29ybGQ=". If I use the CLI ipfs pubsub sub It work as expected which makes me thing there's a bug somewhere.

I'll look around and see if I can fix it.

Otherwise great API!

jcaesar commented 4 years ago

I guess this is in base64 because the answer is returned in JSON, and that can't handle arbitrary binary data?

SionoiS commented 4 years ago
{
  "data": "<base64-string>",
  "from": "<base64-string>",
  "seqno": "<base64-string>",
  "topicIDs": [
    "<string>"
  ]
}

edit: I'm blind...

I tried decoding the data value with multibase and it failed so IDK...

Also, notice the = sign at the end, no multibase base have that char in their alphabet.

SionoiS commented 4 years ago

Ok I was wrong there's no bug...

I decoded the string but had to add a 'm' at the start to signify to multibase that it was base64 string.

jcaesar commented 4 years ago

I don't know... I think base64 is part of the format of the request, maybe the library should decode it.

SionoiS commented 4 years ago

I don't know... I think base64 is part of the format of the request, maybe the library should decode it.

The docs tell us that it should be base64.

In reality it's base64 with padding. I used multibase crate with Base64Pad as setting.

+1 for having the lib decode it, it's a little confusing right now.

Tails commented 3 years ago

I had trouble here too, as did this StackOverflow poster. I was confused too. I started trying to decode the 'from' field but it kept failing. Until I realized that the decoded 'from' result is actually binary, and that the 'data' and 'seqno' were fine. This worked for me:

String::from_utf8(multibase::decode(format!("M{}", s)).unwrap().1)
SionoiS commented 3 years ago

I use this for the from field

let encoded = match response.from.as_ref()?;

let decoded = Base::decode(&Base::Base64Pad, encoded).expect("Decoding sender failed");

let cid = Cid::try_from(decoded).expect("CID from decoded sender failed");

and this for message

let encoded = response.data.as_ref()?;

let decoded = Base::decode(&Base::Base64Pad, encoded).expect("Decoding message failed");

let msg_str = match str::from_utf8(&decoded) {
        Ok(data) => data,
        Err(_) => {
            eprintln!("Chat message invalid UTF-8");
            return None;
        }
};

I hope it helps!

Tails commented 3 years ago

Does anyone know what the topicIds variable contains? Is it the topic ids when subscribing to a wildcard? Or is it the topic ids that a peer is subscribed to in total?

SionoiS commented 3 years ago

Test it but I'm pretty sure it's the topic the message was send on.