mirror of
https://github.com/chatmail/core.git
synced 2026-04-28 19:06:35 +03:00
fix: assign iroh gossip topic to pre-message when post-message is received
Iroh-Gossip-Topic is sent in a post-message. Post-message goes to trash, so topic should be associated with the existing pre-message that is updated rather than with the post-message.
This commit is contained in:
@@ -24,6 +24,13 @@ def path_to_webxdc(request):
|
||||
return str(p)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def path_to_large_webxdc(request):
|
||||
p = request.path.parent.parent.parent.joinpath("test-data/webxdc/realtime-check.xdc")
|
||||
assert p.exists()
|
||||
return str(p)
|
||||
|
||||
|
||||
def log(msg):
|
||||
logging.info(msg)
|
||||
|
||||
@@ -227,3 +234,29 @@ def test_advertisement_after_chatting(acfactory, path_to_webxdc):
|
||||
ac2_webxdc_msg.send_webxdc_realtime_advertisement()
|
||||
event = ac1.wait_for_event(EventType.WEBXDC_REALTIME_ADVERTISEMENT_RECEIVED)
|
||||
assert event.msg_id == ac1_webxdc_msg.id
|
||||
|
||||
|
||||
def test_realtime_large_webxdc(acfactory, path_to_large_webxdc):
|
||||
"""Tests initializing realtime channel on a large webxdc.
|
||||
|
||||
This is a regression test for a bug that existed in version 2.42.0.
|
||||
Large webxdc is split into pre- and post- message,
|
||||
and this previously resulted in failure to initialize realtime.
|
||||
"""
|
||||
ac1, ac2 = acfactory.get_online_accounts(2)
|
||||
ac1.set_config("webxdc_realtime_enabled", "1")
|
||||
ac2.set_config("webxdc_realtime_enabled", "1")
|
||||
|
||||
ac2.create_chat(ac1)
|
||||
ac1_ac2_chat = ac1.create_chat(ac2)
|
||||
ac1_webxdc_msg = ac1_ac2_chat.send_message(text="realtime check", file=path_to_large_webxdc)
|
||||
|
||||
# Receive pre-message.
|
||||
ac2_webxdc_msg = ac2.wait_for_incoming_msg()
|
||||
|
||||
# Receive post-message.
|
||||
ac2_webxdc_msg = ac2.wait_for_msg(EventType.MSGS_CHANGED)
|
||||
|
||||
ac2_webxdc_msg.send_webxdc_realtime_advertisement()
|
||||
event = ac1.wait_for_event(EventType.WEBXDC_REALTIME_ADVERTISEMENT_RECEIVED)
|
||||
assert event.msg_id == ac1_webxdc_msg.id
|
||||
|
||||
@@ -521,6 +521,18 @@ pub(crate) async fn create_iroh_header(ctx: &Context, msg_id: MsgId) -> Result<S
|
||||
Ok(topic_string)
|
||||
}
|
||||
|
||||
/// Converts `Iroh-Gossip-Header` contents to iroh topic ID.
|
||||
pub(crate) fn iroh_topic_from_str(topic: &str) -> Result<TopicId> {
|
||||
let mut topic_raw = [0u8; 32];
|
||||
BASE32_NOPAD
|
||||
.decode_mut(topic.to_ascii_uppercase().as_bytes(), &mut topic_raw)
|
||||
.map_err(|e| e.error)
|
||||
.context("Wrong gossip topic header")?;
|
||||
|
||||
let topic = TopicId::from_bytes(topic_raw);
|
||||
Ok(topic)
|
||||
}
|
||||
|
||||
async fn subscribe_loop(
|
||||
context: &Context,
|
||||
mut stream: iroh_gossip::net::GossipReceiver,
|
||||
|
||||
@@ -6,12 +6,10 @@ use std::iter;
|
||||
use std::sync::LazyLock;
|
||||
|
||||
use anyhow::{Context as _, Result, ensure};
|
||||
use data_encoding::BASE32_NOPAD;
|
||||
use deltachat_contact_tools::{
|
||||
ContactAddress, addr_cmp, addr_normalize, may_be_valid_addr, sanitize_bidi_characters,
|
||||
sanitize_single_line,
|
||||
};
|
||||
use iroh_gossip::proto::TopicId;
|
||||
use mailparse::SingleInfo;
|
||||
use num_traits::FromPrimitive;
|
||||
use regex::Regex;
|
||||
@@ -39,7 +37,7 @@ use crate::mimeparser::{
|
||||
AvatarAction, GossipedKey, MimeMessage, PreMessageMode, SystemMessage, parse_message_ids,
|
||||
};
|
||||
use crate::param::{Param, Params};
|
||||
use crate::peer_channels::{add_gossip_peer_from_header, insert_topic_stub};
|
||||
use crate::peer_channels::{add_gossip_peer_from_header, insert_topic_stub, iroh_topic_from_str};
|
||||
use crate::reaction::{Reaction, set_msg_reaction};
|
||||
use crate::rusqlite::OptionalExtension;
|
||||
use crate::securejoin::{
|
||||
@@ -2298,21 +2296,12 @@ RETURNING id
|
||||
|
||||
// Maybe set logging xdc and add gossip topics for webxdcs.
|
||||
for (part, msg_id) in mime_parser.parts.iter().zip(&created_db_entries) {
|
||||
// check if any part contains a webxdc topic id
|
||||
if part.typ == Viewtype::Webxdc {
|
||||
if let Some(topic) = mime_parser.get_header(HeaderDef::IrohGossipTopic) {
|
||||
// default encoding of topic ids is `hex`.
|
||||
let mut topic_raw = [0u8; 32];
|
||||
BASE32_NOPAD
|
||||
.decode_mut(topic.to_ascii_uppercase().as_bytes(), &mut topic_raw)
|
||||
.map_err(|e| e.error)
|
||||
.context("Wrong gossip topic header")?;
|
||||
|
||||
let topic = TopicId::from_bytes(topic_raw);
|
||||
insert_topic_stub(context, *msg_id, topic).await?;
|
||||
} else {
|
||||
warn!(context, "webxdc doesn't have a gossip topic")
|
||||
}
|
||||
if mime_parser.pre_message != PreMessageMode::Post
|
||||
&& part.typ == Viewtype::Webxdc
|
||||
&& let Some(topic) = mime_parser.get_header(HeaderDef::IrohGossipTopic)
|
||||
{
|
||||
let topic = iroh_topic_from_str(topic)?;
|
||||
insert_topic_stub(context, *msg_id, topic).await?;
|
||||
}
|
||||
|
||||
maybe_set_logging_xdc_inner(
|
||||
@@ -2517,6 +2506,13 @@ async fn handle_post_message(
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if part.typ == Viewtype::Webxdc
|
||||
&& let Some(topic) = mime_parser.get_header(HeaderDef::IrohGossipTopic)
|
||||
{
|
||||
let topic = iroh_topic_from_str(topic)?;
|
||||
insert_topic_stub(context, msg_id, topic).await?;
|
||||
}
|
||||
|
||||
let mut new_params = original_msg.param.clone();
|
||||
new_params
|
||||
.merge_in_params(part.param.clone())
|
||||
|
||||
BIN
test-data/webxdc/realtime-check.xdc
Normal file
BIN
test-data/webxdc/realtime-check.xdc
Normal file
Binary file not shown.
Reference in New Issue
Block a user