From b44fb8675a3b9983d3d3c1f2586006520b6f7281 Mon Sep 17 00:00:00 2001 From: Mike Rylander Date: Tue, 28 Aug 2018 14:32:02 -0400 Subject: [PATCH] LP#1703411: Move OpenSRF XMPP attrs to subelement Modern versions of Ejabberd strip custom XML attributes which appear outside of custom elements. To support OpenSRF's custom router and osrf_xid commands, move these attributes into a new custom XML element . Signed-off-by: Mike Rylander Signed-off-by: Bill Erickson Signed-off-by: Jason Stephenson --- src/java/org/opensrf/net/xmpp/XMPPReader.java | 8 ++ src/libopensrf/transport_message.c | 78 +++++++++++++++++-- src/libopensrf/transport_session.c | 21 +++-- .../Transport/SlimJabber/XMPPMessage.pm | 13 +++- .../Transport/SlimJabber/XMPPReader.pm | 9 ++- 5 files changed, 107 insertions(+), 22 deletions(-) diff --git a/src/java/org/opensrf/net/xmpp/XMPPReader.java b/src/java/org/opensrf/net/xmpp/XMPPReader.java index 406298a..cd620a6 100644 --- a/src/java/org/opensrf/net/xmpp/XMPPReader.java +++ b/src/java/org/opensrf/net/xmpp/XMPPReader.java @@ -248,6 +248,14 @@ public class XMPPReader implements Runnable { return; } + if("opensrf".equals(name)) { + /** add a special case for the opensrf "router_from" attribute */ + String rf = reader.getAttributeValue(null, "router_from"); + if( rf != null ) + msgFrom = rf; + return; + } + if("body".equals(name)) { xmlState = XMLState.IN_BODY; return; diff --git a/src/libopensrf/transport_message.c b/src/libopensrf/transport_message.c index dfe83d1..f95debc 100644 --- a/src/libopensrf/transport_message.c +++ b/src/libopensrf/transport_message.c @@ -123,6 +123,7 @@ transport_message* new_message_from_xml( const char* msg_xml ) { xmlChar* router_from = xmlGetProp( root, BAD_CAST "router_from" ); xmlChar* router_to = xmlGetProp( root, BAD_CAST "router_to" ); xmlChar* router_class = xmlGetProp( root, BAD_CAST "router_class" ); + xmlChar* router_command = xmlGetProp( root, BAD_CAST "router_command" ); xmlChar* broadcast = xmlGetProp( root, BAD_CAST "broadcast" ); xmlChar* osrf_xid = xmlGetProp( root, BAD_CAST "osrf_xid" ); @@ -170,6 +171,11 @@ transport_message* new_message_from_xml( const char* msg_xml ) { xmlFree(router_class); } + if(router_command) { + new_msg->router_command = strdup((const char*)router_command); + xmlFree(router_command); + } + if(broadcast) { if(strcmp((const char*) broadcast,"0") ) new_msg->broadcast = 1; @@ -191,6 +197,55 @@ transport_message* new_message_from_xml( const char* msg_xml ) { new_msg->subject = strdup( (const char*) search_node->children->content ); } + if( ! strcmp( (const char*) search_node->name, "opensrf" ) ) { + router_from = xmlGetProp( search_node, BAD_CAST "router_from" ); + router_to = xmlGetProp( search_node, BAD_CAST "router_to" ); + router_class = xmlGetProp( search_node, BAD_CAST "router_class" ); + router_command = xmlGetProp( search_node, BAD_CAST "router_command" ); + broadcast = xmlGetProp( search_node, BAD_CAST "broadcast" ); + osrf_xid = xmlGetProp( search_node, BAD_CAST "osrf_xid" ); + + if( osrf_xid ) { + message_set_osrf_xid( new_msg, (char*) osrf_xid); + xmlFree(osrf_xid); + } + + if( router_from ) { + new_msg->sender = strdup((const char*)router_from); + } else { + if( sender ) { + new_msg->sender = strdup((const char*)sender); + xmlFree(sender); + } + } + + if(router_from) { + new_msg->router_from = strdup((const char*)router_from); + xmlFree(router_from); + } + + if(router_to) { + new_msg->router_to = strdup((const char*)router_to); + xmlFree(router_to); + } + + if(router_class) { + new_msg->router_class = strdup((const char*)router_class); + xmlFree(router_class); + } + + if(router_command) { + new_msg->router_command = strdup((const char*)router_command); + xmlFree(router_command); + } + + if(broadcast) { + if(strcmp((const char*) broadcast,"0") ) + new_msg->broadcast = 1; + xmlFree(broadcast); + } + } + if( ! strcmp( (const char*) search_node->name, "body" ) ) { if( search_node->children && search_node->children->content ) new_msg->body = strdup((const char*) search_node->children->content ); @@ -317,6 +372,7 @@ int message_prepare_xml( transport_message* msg ) { xmlNodePtr message_node; xmlNodePtr body_node; xmlNodePtr thread_node; + xmlNodePtr opensrf_node; xmlNodePtr subject_node; xmlNodePtr error_node; @@ -340,14 +396,20 @@ int message_prepare_xml( transport_message* msg ) { /* set from and to */ xmlNewProp( message_node, BAD_CAST "to", BAD_CAST msg->recipient ); xmlNewProp( message_node, BAD_CAST "from", BAD_CAST msg->sender ); - xmlNewProp( message_node, BAD_CAST "router_from", BAD_CAST msg->router_from ); - xmlNewProp( message_node, BAD_CAST "router_to", BAD_CAST msg->router_to ); - xmlNewProp( message_node, BAD_CAST "router_class", BAD_CAST msg->router_class ); - xmlNewProp( message_node, BAD_CAST "router_command", BAD_CAST msg->router_command ); - xmlNewProp( message_node, BAD_CAST "osrf_xid", BAD_CAST msg->osrf_xid ); - - if( msg->broadcast ) - xmlNewProp( message_node, BAD_CAST "broadcast", BAD_CAST "1" ); + + /* set from and to on a new node, also */ + opensrf_node = xmlNewChild(message_node, NULL, (xmlChar*) "opensrf", NULL ); + xmlNewProp( opensrf_node, BAD_CAST "router_from", BAD_CAST msg->router_from ); + xmlNewProp( opensrf_node, BAD_CAST "router_to", BAD_CAST msg->router_to ); + xmlNewProp( opensrf_node, BAD_CAST "router_class", BAD_CAST msg->router_class ); + xmlNewProp( opensrf_node, BAD_CAST "router_command", BAD_CAST msg->router_command ); + xmlNewProp( opensrf_node, BAD_CAST "osrf_xid", BAD_CAST msg->osrf_xid ); + + xmlAddChild(message_node, opensrf_node); + + if( msg->broadcast ) { + xmlNewProp( opensrf_node, BAD_CAST "broadcast", BAD_CAST "1" ); + } /* Now add nodes where appropriate */ char* body = msg->body; diff --git a/src/libopensrf/transport_session.c b/src/libopensrf/transport_session.c index 4d2f7f6..7ea15d5 100644 --- a/src/libopensrf/transport_session.c +++ b/src/libopensrf/transport_session.c @@ -573,20 +573,25 @@ static void startElementHandler( ses->state_machine->in_message = 1; buffer_add( ses->from_buffer, get_xml_attr( atts, "from" ) ); buffer_add( ses->recipient_buffer, get_xml_attr( atts, "to" ) ); - buffer_add( ses->router_from_buffer, get_xml_attr( atts, "router_from" ) ); - buffer_add( ses->osrf_xid_buffer, get_xml_attr( atts, "osrf_xid" ) ); - buffer_add( ses->router_to_buffer, get_xml_attr( atts, "router_to" ) ); - buffer_add( ses->router_class_buffer, get_xml_attr( atts, "router_class" ) ); - buffer_add( ses->router_command_buffer, get_xml_attr( atts, "router_command" ) ); - const char* broadcast = get_xml_attr( atts, "broadcast" ); - if( broadcast ) - ses->router_broadcast = atoi( broadcast ); return; } if( ses->state_machine->in_message ) { + if( strcmp( (char*) name, "opensrf" ) == 0 ) { + buffer_add( ses->router_from_buffer, get_xml_attr( atts, "router_from" ) ); + buffer_add( ses->osrf_xid_buffer, get_xml_attr( atts, "osrf_xid" ) ); + buffer_add( ses->router_to_buffer, get_xml_attr( atts, "router_to" ) ); + buffer_add( ses->router_class_buffer, get_xml_attr( atts, "router_class" ) ); + buffer_add( ses->router_command_buffer, get_xml_attr( atts, "router_command" ) ); + const char* broadcast = get_xml_attr( atts, "broadcast" ); + if( broadcast ) + ses->router_broadcast = atoi( broadcast ); + + return; + } + if( strcmp( (char*) name, "body" ) == 0 ) { ses->state_machine->in_message_body = 1; return; diff --git a/src/perl/lib/OpenSRF/Transport/SlimJabber/XMPPMessage.pm b/src/perl/lib/OpenSRF/Transport/SlimJabber/XMPPMessage.pm index 9bd5328..44e2040 100644 --- a/src/perl/lib/OpenSRF/Transport/SlimJabber/XMPPMessage.pm +++ b/src/perl/lib/OpenSRF/Transport/SlimJabber/XMPPMessage.pm @@ -6,7 +6,8 @@ use strict; use warnings; use XML::LibXML; use constant JABBER_MESSAGE => - "". + "". "%s%s"; sub new { @@ -120,14 +121,18 @@ sub parse_xml { throw $err if $err; my $root = $doc->documentElement; + my $osrf_node = $root->findnodes('/opensrf')->shift; $self->{body} = $root->findnodes('/message/body').''; $self->{thread} = $root->findnodes('/message/thread').''; - $self->{from} = $root->getAttribute('router_from'); + + $self->{from} = $osrf_node->getAttribute('router_from'); $self->{from} = $root->getAttribute('from') unless $self->{from}; + $self->{to} = $root->getAttribute('to'); - $self->{type} = $root->getAttribute('type'); - $self->{osrf_xid} = $root->getAttribute('osrf_xid'); + + $self->{type} = $osrf_node->getAttribute('type'); + $self->{osrf_xid} = $osrf_node->getAttribute('osrf_xid'); } diff --git a/src/perl/lib/OpenSRF/Transport/SlimJabber/XMPPReader.pm b/src/perl/lib/OpenSRF/Transport/SlimJabber/XMPPReader.pm index 9e15ecd..737cf96 100644 --- a/src/perl/lib/OpenSRF/Transport/SlimJabber/XMPPReader.pm +++ b/src/perl/lib/OpenSRF/Transport/SlimJabber/XMPPReader.pm @@ -306,8 +306,13 @@ sub start_element { my $msg = $self->{message}; $msg->{to} = $attrs{'to'}; - $msg->{from} = $attrs{router_from} if $attrs{router_from}; - $msg->{from} = $attrs{from} unless $msg->{from}; + $msg->{from} = $attrs{from}; + + } elsif($name eq 'opensrf') { + + # These will be authoritative if they exist + my $msg = $self->{message}; + $msg->{from} = $attrs{router_from}; $msg->{osrf_xid} = $attrs{'osrf_xid'}; $msg->{type} = $attrs{type}; -- 2.43.2