Commit 01d67e45 authored by Dave Cridland's avatar Dave Cridland

OF-1335 Strip namespaces differently

parent daf92ff2
......@@ -377,14 +377,39 @@ public class XMPPPacketReader {
QName qname = (pp.getPrefix() == null) ? df.createQName(pp.getName(), pp.getNamespace()) : df.createQName(pp.getName(), pp.getPrefix(), pp.getNamespace());
Element newElement;
// Do not qualify stanza element with certain namespaces. This makes those stanzas re-usable between,
// for example, c2s and s2s. This code prevents such qualification only for elements that have no
// default namespace declared
final boolean defaultNamespaceDeclared = parent == null || !parent.getNamespaceForPrefix("").getURI().equals("");
if ( !defaultNamespaceDeclared && IGNORED_NAMESPACE_ON_STANZA.contains( qname.getNamespaceURI() ) ) {
// Strip namespace from all default-namespaced elements if
// all ancestors have the same namespace and it's a content
// namespace.
boolean dropNamespace = false;
System.out.println("* Processing start element {" + pp.getNamespace() + "}" + pp.getName());
if (pp.getPrefix() == null && IGNORED_NAMESPACE_ON_STANZA.contains(qname.getNamespaceURI())) {
System.out.println("Prefix null on element " + qname.getName() + " in ns " + qname.getNamespaceURI());
// Default namespaced element which is in a content namespace,
// so we'll drop. Example, stanzas, <message><body/></message>
dropNamespace = true;
for (Element el = parent; el != null; el = el.getParent()) {
final String defaultNS = el.getNamespaceForPrefix("").getURI();
System.out.println(" Parent defaultNS is " + defaultNS);
if (defaultNS.equals("")) {
// We've cleared this one already, just bail.
System.out.println(" --> Stop; dropNS");
break;
}
if (!defaultNS.equals(qname.getNamespaceURI())) {
// But if there's an ancestor element, we shouldn't drop
// after all. Example: forwarded message.
dropNamespace = false;
System.out.println(" --> Stop; NOT dropNS");
break;
}
}
}
if ( dropNamespace ) {
System.out.println("New element, no namespace");
newElement = df.createElement(pp.getName());
}
else {
System.out.println("New element, with namespace");
newElement = df.createElement(qname);
}
int nsStart = pp.getNamespaceCount(pp.getDepth() - 1);
......@@ -392,11 +417,16 @@ public class XMPPPacketReader {
for (int i = nsStart; i < nsEnd; i++) {
final String namespacePrefix = pp.getNamespacePrefix( i );
final String namespaceUri = pp.getNamespaceUri( i );
System.out.println("Considering {" + namespacePrefix + "} -> {" + namespaceUri + "}");
if ( namespacePrefix != null ) {
newElement.addNamespace( namespacePrefix, namespaceUri );
} else if ( !( pp.getDepth() <= 2 && IGNORED_NAMESPACE_ON_STANZA.contains(namespaceUri) ) ) {
newElement.addNamespace(namespacePrefix, namespaceUri);
System.out.println(" Copying.");
} else if ( parent == null && IGNORED_NAMESPACE_ON_STANZA.contains( namespaceUri ) ) {
// Don't copy.
} else if ( !(dropNamespace && namespaceUri.equals( qname.getNamespaceURI() ) ) ) {
// Do not include certain default namespace on the root-element ('stream') or stanza level. This makes stanzas re-usable between, for example, c2s and s2s.
newElement.addNamespace( "", namespaceUri );
System.out.println(" Copying no prefix.");
}
}
for (int i = 0; i < pp.getAttributeCount(); i++) {
......
......@@ -55,7 +55,9 @@ public class XMPPPacketReaderTest
final String input = "<stream:stream to='example.com' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'><message from='juliet@example.com' to='romeo@example.net' xml:lang='en'><body>Art thou not Romeo, and a Montague?</body></message></stream:stream>";
// Execute system under test.
System.out.println("** " + input);
final Document result = packetReader.read( new StringReader( input ) );
System.out.println("** " + result.asXML());
// Verify result.
Assert.assertFalse( result.asXML().contains( "jabber:client" ) );
......@@ -76,7 +78,9 @@ public class XMPPPacketReaderTest
final String input = "<stream:stream to='example.com' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'><message xmlns='jabber:client' from='juliet@example.com' to='romeo@example.net' xml:lang='en'><body>Art thou not Romeo, and a Montague?</body></message></stream:stream>";
// Execute system under test.
System.out.println("** " + input);
final Document result = packetReader.read( new StringReader( input ) );
System.out.println("** " + result.asXML());
// Verify result.
Assert.assertFalse( result.asXML().contains( "jabber:client" ) );
......@@ -105,7 +109,9 @@ public class XMPPPacketReaderTest
" </message>" +
"</stream:stream>";
System.out.println("** " + input);
final Document result = packetReader.read( new StringReader( input ) );
System.out.println("** " + result.asXML());
// Verify result.
Assert.assertFalse( "'jabber:client' should not occur before 'something:else'", result.asXML().substring( 0, result.asXML().indexOf("something:else") ).contains( "jabber:client" ) );
......@@ -135,7 +141,31 @@ public class XMPPPacketReaderTest
" </message>" +
"</stream:stream>";
System.out.println("** " + input);
final Document result = packetReader.read( new StringReader( input ) );
System.out.println("** " + result.asXML());
// Verify result.
Assert.assertFalse( "'jabber:client' should not occur before 'something:else'", result.asXML().substring( 0, result.asXML().indexOf("something:else") ).contains( "jabber:client" ) );
Assert.assertTrue( "'jabber:client' should occur after 'something:else'", result.asXML().substring( result.asXML().indexOf("something:else") ).contains( "jabber:client" ) );
}
/**
* Check that a websocket connection woudl also work.
*/
@Test
public void testStripNamespacesForWebsocket() throws Exception
{
final String input_header = "<open xmlns='urn:ietf:params:xml:ns:xmpp-framing' to='example.com' version='1.0' />";
final Document doc_header = packetReader.read( new StringReader( input_header ) );
final String input = " <message xmlns='jabber:client'>" +
" <other xmlns='something:else'>" +
" <message xmlns='jabber:client'/>" +
" </other>" +
" </message>";
System.out.println("** " + input);
final Document result = packetReader.read( new StringReader( input ) );
System.out.println("** " + result.asXML());
// Verify result.
Assert.assertFalse( "'jabber:client' should not occur before 'something:else'", result.asXML().substring( 0, result.asXML().indexOf("something:else") ).contains( "jabber:client" ) );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment