core (xmpp/messages): only send "origin" request for printable messages:

"Origin" request are disco requests to know if a message sender is a bot or coming from a
gateway. It was sending request on every message, including pubsub/PEP events, resulting
in requests done to many entities, including ones not cacheables (bare entities or third
party servers, without caps mechanisms).

To avoid that, the requests is now done only for printable messages. To use
`client.is_message_printable` correctly, origin check has be moved to the end, after
`message_parse` trigger, so attachments are added to data.
This commit is contained in:
Goffi 2026-05-03 16:46:15 +02:00
commit 779d58d5ff

View file

@ -1647,39 +1647,6 @@ class SatMessageProtocol(xmppim.MessageProtocol):
if getattr(message_elt, "_is_from_archive", False):
extra["is_from_archive"] = True
# origin
if not from_jid_bare in (client.jid.userhostJID(), client.server_jid):
try:
# For bare JIDs, query the server instead: bare jids are not cached by
# XEP-0115, so we'll have an actual disco request each time. On the other
# hand, server disco is cached after first request, and should gives us
# the gateway/origin info we need.
# FIXME: Check if this cause trouble in practice.
query_jid = from_jid if from_jid.resource else jid.JID(from_jid.host)
disco_infos = await G.host.memory.disco.get_infos(client, query_jid)
if from_jid_bare.user:
domain_disco_infos = await G.host.memory.disco.get_infos(
client, jid.JID(from_jid_bare.host)
)
else:
domain_disco_infos = disco_infos
if ("client", "bot") in disco_infos.identities:
extra["is-bot"] = True
for (
category,
type_,
), identities_map in domain_disco_infos.identities.items():
for lang, identity in identities_map.items():
if category == "gateway":
extra["origin"] = identity.type
if identity.name:
extra["origin_name"] = identity.name
except exceptions.ExternalRequestError:
log.warning(
f"Disco query failed for {from_jid.full()}, skipping identity "
"detection"
)
# message
for e in message_elt.elements(C.NS_CLIENT, "body"):
message[e.getAttribute((C.NS_XML, "lang"), "")] = str(e)
@ -1721,6 +1688,48 @@ class SatMessageProtocol(xmppim.MessageProtocol):
data["delay_sender"] = parsed_delay.sender.full()
G.host.trigger.point("message_parse", client, message_elt, data)
# origin
# We set it after "message_parse" trigger, so attachments are added by plugins
# (needed for "is_message_printable")
if (
from_jid_bare not in (client.jid.userhostJID(), client.server_jid)
# We only want messages with printable contents to avoid making requests for
# nothing to entities (which may not be in cache or cacheable)
and client.is_message_printable(data)
):
try:
# For bare JIDs, query the server instead: bare jids are not cached by
# XEP-0115, so we'll have an actual disco request each time. On the other
# hand, server disco is cached after first request, and should gives us
# the gateway/origin info we need.
# FIXME: Check if this cause trouble in practice.
query_jid = from_jid if from_jid.resource else jid.JID(from_jid.host)
disco_infos = await G.host.memory.disco.get_infos(client, query_jid)
if from_jid_bare.user:
domain_disco_infos = await G.host.memory.disco.get_infos(
client, jid.JID(from_jid_bare.host)
)
else:
domain_disco_infos = disco_infos
if ("client", "bot") in disco_infos.identities:
extra["is-bot"] = True
for (
category,
type_,
), identities_map in domain_disco_infos.identities.items():
for lang, identity in identities_map.items():
if category == "gateway":
extra["origin"] = identity.type
if identity.name:
extra["origin_name"] = identity.name
except exceptions.ExternalRequestError:
log.warning(
f"Disco query failed for {from_jid.full()}, skipping identity "
"detection"
)
return data
def onMessage(self, message: domish.Element) -> None: