Commit 45394287 authored by Dave Cridland's avatar Dave Cridland

Merge pull request #539 from guusdk/OF-1087

OF-1087: Default namespace handling in BOSH.
parents ce156fed e4b7a75b
...@@ -35,6 +35,7 @@ import org.apache.commons.lang.StringEscapeUtils; ...@@ -35,6 +35,7 @@ import org.apache.commons.lang.StringEscapeUtils;
import org.dom4j.Document; import org.dom4j.Document;
import org.dom4j.DocumentHelper; import org.dom4j.DocumentHelper;
import org.dom4j.Element; import org.dom4j.Element;
import org.dom4j.QName;
import org.dom4j.io.XMPPPacketReader; import org.dom4j.io.XMPPPacketReader;
import org.jivesoftware.openfire.auth.UnauthorizedException; import org.jivesoftware.openfire.auth.UnauthorizedException;
import org.jivesoftware.openfire.net.MXParser; import org.jivesoftware.openfire.net.MXParser;
...@@ -348,8 +349,7 @@ public class HttpBindServlet extends HttpServlet { ...@@ -348,8 +349,7 @@ public class HttpBindServlet extends HttpServlet {
} }
protected static String createErrorBody(String type, String condition) { protected static String createErrorBody(String type, String condition) {
final Element body = DocumentHelper.createElement("body"); final Element body = DocumentHelper.createElement( QName.get( "body", "http://jabber.org/protocol/httpbind" ) );
body.addNamespace("", "http://jabber.org/protocol/httpbind");
body.addAttribute("type", type); body.addAttribute("type", type);
body.addAttribute("condition", condition); body.addAttribute("condition", condition);
return body.asXML(); return body.asXML();
......
...@@ -1074,17 +1074,15 @@ public class HttpSession extends LocalClientSession { ...@@ -1074,17 +1074,15 @@ public class HttpSession extends LocalClientSession {
protected String createEmptyBody(boolean terminate) protected String createEmptyBody(boolean terminate)
{ {
final Element body = DocumentHelper.createElement("body"); final Element body = DocumentHelper.createElement( QName.get( "body", "http://jabber.org/protocol/httpbind" ) );
if (terminate) { body.addAttribute("type", "terminate"); } if (terminate) { body.addAttribute("type", "terminate"); }
body.addNamespace("", "http://jabber.org/protocol/httpbind");
body.addAttribute("ack", String.valueOf(getLastAcknowledged())); body.addAttribute("ack", String.valueOf(getLastAcknowledged()));
return body.asXML(); return body.asXML();
} }
private String createSessionRestartResponse() private String createSessionRestartResponse()
{ {
final Element response = DocumentHelper.createElement("body"); final Element response = DocumentHelper.createElement( QName.get( "body", "http://jabber.org/protocol/httpbind" ) );
response.addNamespace("", "http://jabber.org/protocol/httpbind");
response.addNamespace("stream", "http://etherx.jabber.org/streams"); response.addNamespace("stream", "http://etherx.jabber.org/streams");
final Element features = response.addElement("stream:features"); final Element features = response.addElement("stream:features");
...@@ -1154,7 +1152,7 @@ public class HttpSession extends LocalClientSession { ...@@ -1154,7 +1152,7 @@ public class HttpSession extends LocalClientSession {
} }
} }
private class Deliverable { static class Deliverable {
private final String text; private final String text;
private final Collection<String> packets; private final Collection<String> packets;
...@@ -1171,7 +1169,10 @@ public class HttpSession extends LocalClientSession { ...@@ -1171,7 +1169,10 @@ public class HttpSession extends LocalClientSession {
if (Namespace.NO_NAMESPACE.equals(packet.getElement().getNamespace())) { if (Namespace.NO_NAMESPACE.equals(packet.getElement().getNamespace())) {
// use string-based operation here to avoid cascading xmlns wonkery // use string-based operation here to avoid cascading xmlns wonkery
StringBuilder packetXml = new StringBuilder(packet.toXML()); StringBuilder packetXml = new StringBuilder(packet.toXML());
packetXml.insert(packetXml.indexOf(" "), " xmlns=\"jabber:client\""); final int noslash = packetXml.indexOf( ">" );
final int slash = packetXml.indexOf( "/>" );
final int insertAt = ( noslash - 1 == slash ? slash : noslash );
packetXml.insert( insertAt, " xmlns=\"jabber:client\"");
this.packets.add(packetXml.toString()); this.packets.add(packetXml.toString());
} else { } else {
this.packets.add(packet.toXML()); this.packets.add(packet.toXML());
......
...@@ -317,8 +317,7 @@ public class HttpSessionManager { ...@@ -317,8 +317,7 @@ public class HttpSessionManager {
} }
private static String createSessionCreationResponse(HttpSession session) throws DocumentException { private static String createSessionCreationResponse(HttpSession session) throws DocumentException {
Element response = DocumentHelper.createElement("body"); Element response = DocumentHelper.createElement( QName.get( "body", "http://jabber.org/protocol/httpbind" ) );
response.addNamespace("", "http://jabber.org/protocol/httpbind");
response.addNamespace("stream", "http://etherx.jabber.org/streams"); response.addNamespace("stream", "http://etherx.jabber.org/streams");
response.addAttribute("from", session.getServerName()); response.addAttribute("from", session.getServerName());
response.addAttribute("authid", session.getStreamID().getID()); response.addAttribute("authid", session.getStreamID().getID());
......
...@@ -5,6 +5,7 @@ import java.util.TimerTask; ...@@ -5,6 +5,7 @@ import java.util.TimerTask;
import org.dom4j.Attribute; import org.dom4j.Attribute;
import org.dom4j.Element; import org.dom4j.Element;
import org.dom4j.QName;
import org.dom4j.tree.DefaultAttribute; import org.dom4j.tree.DefaultAttribute;
import org.dom4j.tree.DefaultElement; import org.dom4j.tree.DefaultElement;
import org.jivesoftware.openfire.interceptor.InterceptorManager; import org.jivesoftware.openfire.interceptor.InterceptorManager;
...@@ -86,8 +87,7 @@ public class DiscoIQRegisteredProcessor extends AbstractRemoteRosterProcessor { ...@@ -86,8 +87,7 @@ public class DiscoIQRegisteredProcessor extends AbstractRemoteRosterProcessor {
askComponent.setTo(to); askComponent.setTo(to);
askComponent.setFrom(from); askComponent.setFrom(from);
askComponent.setType(IQ.Type.get); askComponent.setType(IQ.Type.get);
Element query = new DefaultElement("query"); Element query = new DefaultElement( QName.get( "query", "jabber:iq:register" ) );
query.addNamespace("", "jabber:iq:register");
askComponent.setChildElement(query); askComponent.setChildElement(query);
// Remove the package intercepter in 1sec // Remove the package intercepter in 1sec
......
...@@ -8,6 +8,7 @@ import java.util.TimerTask; ...@@ -8,6 +8,7 @@ import java.util.TimerTask;
import org.dom4j.Element; import org.dom4j.Element;
import org.dom4j.Node; import org.dom4j.Node;
import org.dom4j.QName;
import org.dom4j.tree.DefaultAttribute; import org.dom4j.tree.DefaultAttribute;
import org.dom4j.tree.DefaultElement; import org.dom4j.tree.DefaultElement;
import org.jivesoftware.openfire.SharedGroupException; import org.jivesoftware.openfire.SharedGroupException;
...@@ -76,7 +77,7 @@ public class IQRosterPayloadProcessor extends AbstractRemoteRosterProcessor { ...@@ -76,7 +77,7 @@ public class IQRosterPayloadProcessor extends AbstractRemoteRosterProcessor {
IQ response = IQ.createResultIQ(requestPacket); IQ response = IQ.createResultIQ(requestPacket);
response.setTo(subdomain); response.setTo(subdomain);
Element query = new DefaultElement("query"); Element query = new DefaultElement( QName.get("query","jabber:iq:roster"));
for (RosterItem i : items) { for (RosterItem i : items) {
String jid = i.getJid().toString(); String jid = i.getJid().toString();
if (!jid.equals(subdomain) && jid.contains(subdomain)) { if (!jid.equals(subdomain) && jid.contains(subdomain)) {
...@@ -93,8 +94,6 @@ public class IQRosterPayloadProcessor extends AbstractRemoteRosterProcessor { ...@@ -93,8 +94,6 @@ public class IQRosterPayloadProcessor extends AbstractRemoteRosterProcessor {
query.add(item); query.add(item);
} }
} }
query.addNamespace("", "jabber:iq:roster");
response.setChildElement(query); response.setChildElement(query);
dispatchPacket(response); dispatchPacket(response);
} }
...@@ -103,8 +102,7 @@ public class IQRosterPayloadProcessor extends AbstractRemoteRosterProcessor { ...@@ -103,8 +102,7 @@ public class IQRosterPayloadProcessor extends AbstractRemoteRosterProcessor {
IQ iq = (IQ) requestPacket; IQ iq = (IQ) requestPacket;
IQ response = IQ.createResultIQ(iq); IQ response = IQ.createResultIQ(iq);
response.setTo(subdomain); response.setTo(subdomain);
Element query = new DefaultElement("query"); Element query = new DefaultElement( QName.get("query","jabber:iq:roster") );
query.addNamespace("", "jabber:iq:roster");
response.setChildElement(query); response.setChildElement(query);
dispatchPacket(response); dispatchPacket(response);
} }
......
...@@ -268,8 +268,7 @@ public class RegistrationHandler implements ChannelHandler<IQ> { ...@@ -268,8 +268,7 @@ public class RegistrationHandler implements ChannelHandler<IQ> {
} }
// Add special indicator for rosterless gateway handling. // Add special indicator for rosterless gateway handling.
response.addElement("x") response.addElement( QName.get( "x", NameSpace.IQ_GATEWAY_REGISTER) );
.addNamespace("", NameSpace.IQ_GATEWAY_REGISTER);
result.setChildElement(response); result.setChildElement(response);
......
...@@ -44,11 +44,17 @@ ...@@ -44,11 +44,17 @@
Monitoring Plugin Changelog Monitoring Plugin Changelog
</h1> </h1>
<p><b>1.5.1</b> -- Feb 15, 2016</p>
<ul>
<li>[<a href='https://igniterealtime.org/issues/browse/OF-1087'>OF-1087</a>] - Fixed namespace handling (BOSH).</li>
</ul>
<p><b>1.5.0</b> -- October 12, 2015</p> <p><b>1.5.0</b> -- October 12, 2015</p>
<ul> <ul>
<li>[<a href='http://www.igniterealtime.org/issues/browse/OF-953'>OF-953</a>] - Updated JSP libraries.</li> <li>[<a href='http://www.igniterealtime.org/issues/browse/OF-953'>OF-953</a>] - Updated JSP libraries.</li>
<li>Requires Openfire 3.11.0.</li> <li>Requires Openfire 3.11.0.</li>
</ul> </ul>
<p><b>1.4.7</b> -- Oct 13, 2015</p> <p><b>1.4.7</b> -- Oct 13, 2015</p>
<ul> <ul>
<li>Fixed feature-not-implemented error</li> <li>Fixed feature-not-implemented error</li>
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
<name>Monitoring Service</name> <name>Monitoring Service</name>
<description>Monitors conversations and statistics of the server.</description> <description>Monitors conversations and statistics of the server.</description>
<author>Jive Software</author> <author>Jive Software</author>
<version>1.5.0</version> <version>1.5.1</version>
<date>10/12/2015</date> <date>2/15/2016</date>
<minServerVersion>4.0.0</minServerVersion> <minServerVersion>4.0.0</minServerVersion>
<databaseKey>monitoring</databaseKey> <databaseKey>monitoring</databaseKey>
<databaseVersion>3</databaseVersion> <databaseVersion>3</databaseVersion>
......
...@@ -177,6 +177,7 @@ public class IQQueryHandler extends AbstractIQHandler implements ...@@ -177,6 +177,7 @@ public class IQQueryHandler extends AbstractIQHandler implements
final QueryRequest queryRequest) { final QueryRequest queryRequest) {
Message finalMessage = new Message(); Message finalMessage = new Message();
finalMessage.setTo(session.getAddress());
Element fin = finalMessage.addChildElement("fin", NAMESPACE); Element fin = finalMessage.addChildElement("fin", NAMESPACE);
if(queryRequest.getQueryid() != null) { if(queryRequest.getQueryid() != null) {
fin.addAttribute("queryid", queryRequest.getQueryid()); fin.addAttribute("queryid", queryRequest.getQueryid());
......
package org.jivesoftware.openfire.http;
import org.dom4j.QName;
import org.junit.Test;
import org.xmpp.packet.Message;
import org.xmpp.packet.Packet;
import java.util.ArrayList;
import java.util.List;
import static org.junit.Assert.assertEquals;
/**
* Unit tests for {@link HttpSession.Deliverable}
*
* @author Guus der Kinderen, guus.der.kinderen@gmail.com
*/
public class HttpSessionDeliverable
{
/**
* Verifies that the default namespace is set on empty stanzas.
*
* @see <a href="https://igniterealtime.org/issues/browse/OF-1087">OF-1087</a>
*/
@Test
public void testNamespaceOnEmptyStanza() throws Exception
{
// Setup fixture
final Message message = new Message();
message.addChildElement( "unittest", "unit:test:namespace" );
final List<Packet> packets = new ArrayList<>();
packets.add( message );
// Execute system under test
final HttpSession.Deliverable deliverable = new HttpSession.Deliverable( packets );
final String result = deliverable.getDeliverable();
// verify results
// Note that this assertion depends on the Openfire XML parser-specific ordering of attributes.
assertEquals( "<message xmlns=\"jabber:client\"><unittest xmlns=\"unit:test:namespace\"/></message>", result );
}
/**
* Verifies that the default namespace is set on empty stanzas (that do not have a child element)
*
* @see <a href="https://igniterealtime.org/issues/browse/OF-1087">OF-1087</a>
*/
@Test
public void testNamespaceOnEmptyStanzaWithoutChildElement() throws Exception
{
// Setup fixture
final Message message = new Message();
final List<Packet> packets = new ArrayList<>();
packets.add( message );
// Execute system under test
final HttpSession.Deliverable deliverable = new HttpSession.Deliverable( packets );
final String result = deliverable.getDeliverable();
// verify results
// Note that this assertion depends on the Openfire XML parser-specific ordering of attributes.
assertEquals( "<message xmlns=\"jabber:client\"/>", result );
}
/**
* Verifies that the default namespace is set on (non-empty) stanzas.
*
* @see <a href="https://igniterealtime.org/issues/browse/OF-1087">OF-1087</a>
*/
@Test
public void testNamespaceOnStanza() throws Exception
{
// Setup fixture
final Message message = new Message();
message.setTo( "unittest@example.org/test" );
message.addChildElement( "unittest", "unit:test:namespace" );
final List<Packet> packets = new ArrayList<>();
packets.add( message );
// Execute system under test
final HttpSession.Deliverable deliverable = new HttpSession.Deliverable( packets );
final String result = deliverable.getDeliverable();
// verify results
// Note that this assertion depends on the Openfire XML parser-specific ordering of attributes.
assertEquals( "<message to=\"unittest@example.org/test\" xmlns=\"jabber:client\"><unittest xmlns=\"unit:test:namespace\"/></message>", result );
}
/**
* Verifies that the default namespace is not set on stanzas that already have defined a default namespace.
*
* @see <a href="https://igniterealtime.org/issues/browse/OF-1087">OF-1087</a>
*/
@Test
public void testNamespaceOnStanzaWithNamespace() throws Exception
{
// Setup fixture
final Message message = new Message();
message.getElement().setQName( QName.get( "message", "unit:test:preexisting:namespace" ) );
message.setTo( "unittest@example.org/test" );
message.addChildElement( "unittest", "unit:test:namespace" );
final List<Packet> packets = new ArrayList<>();
packets.add( message );
// Execute system under test
final HttpSession.Deliverable deliverable = new HttpSession.Deliverable( packets );
final String result = deliverable.getDeliverable();
// verify results
// Note that this assertion depends on the Openfire XML parser-specific ordering of attributes.
assertEquals( "<message xmlns=\"unit:test:preexisting:namespace\" to=\"unittest@example.org/test\"><unittest xmlns=\"unit:test:namespace\"/></message>", result );
}
}
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