Skip to content

Commit

Permalink
Break out the CC to a method on it's own, and ensure we don't CC a me…
Browse files Browse the repository at this point in the history
…ssage that is already CC'd
  • Loading branch information
GregDThomas authored and guusdk committed Mar 21, 2020
1 parent 592a348 commit e754449
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,12 @@
* @author Christian Schudt
*/
public final class Received extends PacketExtension {

public static final String NAME = "received";
public static final String NAMESPACE = "urn:xmpp:carbons:2";

public Received(Forwarded forwarded) {
super("received", "urn:xmpp:carbons:2");
super(NAME, NAMESPACE);
element.add(forwarded.getElement());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ else if (packet instanceof Presence) {
private boolean routeToLocalDomain(JID jid, Packet packet,
boolean fromServer) {
boolean routed = false;
Element privateElement = packet.getElement().element(QName.get("private", "urn:xmpp:carbons:2"));
Element privateElement = packet.getElement().element(QName.get("private", Received.NAMESPACE));
boolean isPrivate = privateElement != null;
// The receiving server and SHOULD remove the <private/> element before delivering to the recipient.
packet.getElement().remove(privateElement);
Expand All @@ -339,49 +339,8 @@ private boolean routeToLocalDomain(JID jid, Packet packet,
routed = false;
} else {
if (localRoutingTable.isLocalRoute(jid)) {
if (packet instanceof Message) {
Message message = (Message) packet;
if (message.getType() == Message.Type.chat && !isPrivate) {
List<JID> routes = getRoutes(jid.asBareJID(), null);
for (JID ccJid : routes) {
// The receiving server MUST NOT send a forwarded copy to the full JID the original <message/> stanza was addressed to, as that recipient receives the original <message/> stanza.
if (!ccJid.equals(jid)) {
ClientSession clientSession = getClientRoute(ccJid);
if (clientSession.isMessageCarbonsEnabled()) {
Message carbon = new Message();
// The wrapping message SHOULD maintain the same 'type' attribute value;
carbon.setType(message.getType());
// the 'from' attribute MUST be the Carbons-enabled user's bare JID
carbon.setFrom(ccJid.asBareJID());
// and the 'to' attribute MUST be the full JID of the resource receiving the copy
carbon.setTo(ccJid);
// The content of the wrapping message MUST contain a <received/> element qualified by the namespace "urn:xmpp:carbons:2", which itself contains a <forwarded/> element qualified by the namespace "urn:xmpp:forward:0" that contains the original <message/>.
carbon.addExtension(new Received(new Forwarded(message)));

try {
final RoutableChannelHandler localRoute = localRoutingTable.getRoute(ccJid);
if (localRoute != null) {
// This session is on a local cluster node
localRoute.process(carbon);
} else {
// The session is not on a local cluster node, so try a remote
final ClientRoute remoteRoute = getClientRouteForLocalUser(ccJid);
if (remotePacketRouter != null // If we're in a cluster
&& remoteRoute != null // and we've found a route to the other node
&& !remoteRoute.getNodeID().equals(XMPPServer.getInstance().getNodeID())) { // and it really is a remote node
// Try and route the packet to the remote session
remotePacketRouter.routePacket(remoteRoute.getNodeID().toByteArray(), ccJid, carbon);
} else {
Log.warn("Unable to find route to CC remote user {}", ccJid);
}
}
} catch (UnauthorizedException e) {
Log.error("Unable to route packet " + packet.toXML(), e);
}
}
}
}
}
if (!isPrivate && packet instanceof Message) {
ccMessage(jid, (Message) packet);
}

// This is a route to a local user hosted in this node
Expand All @@ -408,6 +367,53 @@ private boolean routeToLocalDomain(JID jid, Packet packet,
return routed;
}

private void ccMessage(JID originalRecipient, Message message) {
// We don't want to CC a message that is already a CC
final Element receivedElement = message.getChildElement(Received.NAME, Received.NAMESPACE);
final boolean isCC = receivedElement != null;
if (message.getType() == Message.Type.chat && !isCC) {
List<JID> routes = getRoutes(originalRecipient.asBareJID(), null);
for (JID ccJid : routes) {
// The receiving server MUST NOT send a forwarded copy to the full JID the original <message/> stanza was addressed to, as that recipient receives the original <message/> stanza.
if (!ccJid.equals(originalRecipient)) {
ClientSession clientSession = getClientRoute(ccJid);
if (clientSession.isMessageCarbonsEnabled()) {
Message carbon = new Message();
// The wrapping message SHOULD maintain the same 'type' attribute value;
carbon.setType(message.getType());
// the 'from' attribute MUST be the Carbons-enabled user's bare JID
carbon.setFrom(ccJid.asBareJID());
// and the 'to' attribute MUST be the full JID of the resource receiving the copy
carbon.setTo(ccJid);
// The content of the wrapping message MUST contain a <received/> element qualified by the namespace "urn:xmpp:carbons:2", which itself contains a <forwarded/> element qualified by the namespace "urn:xmpp:forward:0" that contains the original <message/>.
carbon.addExtension(new Received(new Forwarded(message)));

try {
final RoutableChannelHandler localRoute = localRoutingTable.getRoute(ccJid);
if (localRoute != null) {
// This session is on a local cluster node
localRoute.process(carbon);
} else {
// The session is not on a local cluster node, so try a remote
final ClientRoute remoteRoute = getClientRouteForLocalUser(ccJid);
if (remotePacketRouter != null // If we're in a cluster
&& remoteRoute != null // and we've found a route to the other node
&& !remoteRoute.getNodeID().equals(XMPPServer.getInstance().getNodeID())) { // and it really is a remote node
// Try and route the packet to the remote session
remotePacketRouter.routePacket(remoteRoute.getNodeID().toByteArray(), ccJid, carbon);
} else {
Log.warn("Unable to find route to CC remote user {}", ccJid);
}
}
} catch (UnauthorizedException e) {
Log.error("Unable to route packet {}", message, e);
}
}
}
}
}
}

private ClientRoute getClientRouteForLocalUser(JID jid) {
ClientRoute clientRoute = usersCache.get(jid.toString());
if (clientRoute == null) {
Expand Down

0 comments on commit e754449

Please sign in to comment.