Commit 37e9fc8a authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gato

Added xmpp:restart (BOSH) support. JM-1438

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@10702 b35dd754-fafc-0310-a699-88a17e54d16e
parent 060a5193
...@@ -21,70 +21,70 @@ public enum BoshBindingError { ...@@ -21,70 +21,70 @@ public enum BoshBindingError {
* The format of an HTTP header or binding element received from the client is unacceptable * The format of an HTTP header or binding element received from the client is unacceptable
* (e.g., syntax error), or Script Syntax is not supported. * (e.g., syntax error), or Script Syntax is not supported.
*/ */
badRequest(Type.terminal, "bad-request", HttpServletResponse.SC_BAD_REQUEST), badRequest(Type.terminate, "bad-request", HttpServletResponse.SC_BAD_REQUEST),
/** /**
* The target domain specified in the 'to' attribute or the target host or port specified in the * The target domain specified in the 'to' attribute or the target host or port specified in the
* 'route' attribute is no longer serviced by the connection manager. * 'route' attribute is no longer serviced by the connection manager.
*/ */
hostGone(Type.terminal, "host-gone"), hostGone(Type.terminate, "host-gone"),
/** /**
* The target domain specified in the 'to' attribute or the target host or port specified in the * The target domain specified in the 'to' attribute or the target host or port specified in the
* 'route' attribute is unknown to the connection manager. * 'route' attribute is unknown to the connection manager.
*/ */
hostUnknown(Type.terminal, "host-unknown"), hostUnknown(Type.terminate, "host-unknown"),
/** /**
* The initialization element lacks a 'to' or 'route' attribute (or the attribute has no value) * The initialization element lacks a 'to' or 'route' attribute (or the attribute has no value)
* but the connection manager requires one. * but the connection manager requires one.
*/ */
improperAddressing(Type.terminal, "improper-addressing"), improperAddressing(Type.terminate, "improper-addressing"),
/** /**
* The connection manager has experienced an internal error that prevents it from servicing the * The connection manager has experienced an internal error that prevents it from servicing the
* request. * request.
*/ */
internalServerError(Type.terminal, "internal-server-error"), internalServerError(Type.terminate, "internal-server-error"),
/** /**
* (1) 'sid' is not valid, (2) 'stream' is not valid, (3) 'rid' is larger than the upper limit * (1) 'sid' is not valid, (2) 'stream' is not valid, (3) 'rid' is larger than the upper limit
* of the expected window, (4) connection manager is unable to resend response, (5) 'key' * of the expected window, (4) connection manager is unable to resend response, (5) 'key'
* sequence is invalid (6) script syntax is not enabled * sequence is invalid (6) script syntax is not enabled
*/ */
itemNotFound(Type.terminal, "item-not-found", HttpServletResponse.SC_NOT_FOUND), itemNotFound(Type.terminate, "item-not-found", HttpServletResponse.SC_NOT_FOUND),
/** /**
* Another request being processed at the same time as this request caused the session to * Another request being processed at the same time as this request caused the session to
* terminate. * terminate.
*/ */
otherRequest(Type.terminal, "other-request"), otherRequest(Type.terminate, "other-request"),
/** /**
* The client has broken the session rules (polling too frequently, requesting too frequently, * The client has broken the session rules (polling too frequently, requesting too frequently,
* too many simultaneous requests). * too many simultaneous requests).
*/ */
policyViolation(Type.terminal, "policy-violation", policyViolation(Type.terminate, "policy-violation",
HttpServletResponse.SC_FORBIDDEN), HttpServletResponse.SC_FORBIDDEN),
/** /**
* The connection manager was unable to connect to, or unable to connect securely to, or has * The connection manager was unable to connect to, or unable to connect securely to, or has
* lost its connection to, the server. * lost its connection to, the server.
*/ */
remoteConnectionFailed(Type.terminal, "remote-connection-failed"), remoteConnectionFailed(Type.terminate, "remote-connection-failed"),
/** /**
* Encapsulates an error in the protocol being transported. * Encapsulates an error in the protocol being transported.
*/ */
remoteStreamError(Type.terminal, "remote-stream-error"), remoteStreamError(Type.terminate, "remote-stream-error"),
/** /**
* The connection manager does not operate at this URI (e.g., the connection manager accepts * The connection manager does not operate at this URI (e.g., the connection manager accepts
* only SSL or TLS connections at some https: URI rather than the http: URI requested by the * only SSL or TLS connections at some https: URI rather than the http: URI requested by the
* client). The client may try POSTing to the URI in the content of the <uri/> child * client). The client may try POSTing to the URI in the content of the <uri/> child
* element. * element.
*/ */
seeOtherUri(Type.terminal, "see-other-uri"), seeOtherUri(Type.terminate, "see-other-uri"),
/** /**
* The connection manager is being shut down. All active HTTP sessions are being terminated. No * The connection manager is being shut down. All active HTTP sessions are being terminated. No
* new sessions can be created. * new sessions can be created.
*/ */
systemShutdown(Type.terminal, "system-shutdown"), systemShutdown(Type.terminate, "system-shutdown"),
/** /**
* The error is not one of those defined herein; the connection manager SHOULD include * The error is not one of those defined herein; the connection manager SHOULD include
* application-specific information in the content of the <body> wrapper. * application-specific information in the content of the <body> wrapper.
*/ */
undefinedCondition(Type.terminal, "undefined-condition"); undefinedCondition(Type.terminate, "undefined-condition");
private Type errorType; private Type errorType;
private String condition; private String condition;
...@@ -127,10 +127,10 @@ public enum BoshBindingError { ...@@ -127,10 +127,10 @@ public enum BoshBindingError {
public enum Type { public enum Type {
/** /**
* The terminal error condition prevents the client from making any further requests until a * The terminate error condition prevents the client from making any further requests until a
* new session is established. * new session is established.
*/ */
terminal(null), terminate(null),
/** /**
* In the case of a recoverable binding error the client MUST repeat the HTTP request and * In the case of a recoverable binding error the client MUST repeat the HTTP request and
* all the preceding HTTP requests that have not received responses. The content of these * all the preceding HTTP requests that have not received responses. The content of these
......
...@@ -28,6 +28,6 @@ public class HttpBindException extends Exception { ...@@ -28,6 +28,6 @@ public class HttpBindException extends Exception {
} }
public boolean shouldCloseSession() { public boolean shouldCloseSession() {
return error.getErrorType() == BoshBindingError.Type.terminal; return error.getErrorType() == BoshBindingError.Type.terminate;
} }
} }
...@@ -12,10 +12,7 @@ ...@@ -12,10 +12,7 @@
package org.jivesoftware.openfire.http; package org.jivesoftware.openfire.http;
import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.StringEscapeUtils;
import org.dom4j.Document; import org.dom4j.*;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
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;
...@@ -192,7 +189,7 @@ public class HttpBindServlet extends HttpServlet { ...@@ -192,7 +189,7 @@ public class HttpBindServlet extends HttpServlet {
} }
} }
finally { finally {
if (bindingError.getErrorType() == BoshBindingError.Type.terminal) { if (bindingError.getErrorType() == BoshBindingError.Type.terminate) {
session.close(); session.close();
} }
} }
...@@ -242,12 +239,21 @@ public class HttpBindServlet extends HttpServlet { ...@@ -242,12 +239,21 @@ public class HttpBindServlet extends HttpServlet {
} }
String type = rootNode.attributeValue("type"); String type = rootNode.attributeValue("type");
String restartStream = rootNode.attributeValue(new QName("restart", rootNode.getNamespaceForPrefix("xmpp")));
int pauseDuration = getIntAttribue(rootNode.attributeValue("pause"), -1); int pauseDuration = getIntAttribue(rootNode.attributeValue("pause"), -1);
if ("terminate".equals(type)) { if ("terminate".equals(type)) {
session.close(); session.close();
respond(session, response, createEmptyBody(), request.getMethod()); respond(session, response, createEmptyBody(), request.getMethod());
} }
else if ("true".equals(restartStream) && rootNode.nodeCount() == 0) {
try {
respond(session, response, createSessionRestartResponse(session), request.getMethod());
}
catch (DocumentException e) {
Log.error("Error sending session restart response to client.", e);
}
}
else if (pauseDuration > 0 && pauseDuration <= session.getMaxPause()) { else if (pauseDuration > 0 && pauseDuration <= session.getMaxPause()) {
session.pause(pauseDuration); session.pause(pauseDuration);
respond(session, response, createEmptyBody(), request.getMethod()); respond(session, response, createEmptyBody(), request.getMethod());
...@@ -269,6 +275,19 @@ public class HttpBindServlet extends HttpServlet { ...@@ -269,6 +275,19 @@ public class HttpBindServlet extends HttpServlet {
} }
} }
private String createSessionRestartResponse(HttpSession session) throws DocumentException {
Element response = DocumentHelper.createElement("body");
response.addNamespace("", "http://jabber.org/protocol/httpbind");
response.addNamespace("stream", "http://etherx.jabber.org/streams");
Element features = response.addElement("stream:features");
for (Element feature : session.getAvailableStreamFeaturesElements()) {
features.add(feature);
}
return response.asXML();
}
private void createNewSession(HttpServletRequest request, HttpServletResponse response, private void createNewSession(HttpServletRequest request, HttpServletResponse response,
Element rootNode) Element rootNode)
throws IOException throws IOException
......
...@@ -127,9 +127,11 @@ public class HttpSession extends LocalClientSession { ...@@ -127,9 +127,11 @@ public class HttpSession extends LocalClientSession {
public Collection<Element> getAvailableStreamFeaturesElements() { public Collection<Element> getAvailableStreamFeaturesElements() {
List<Element> elements = new ArrayList<Element>(); List<Element> elements = new ArrayList<Element>();
Element sasl = SASLAuthentication.getSASLMechanismsElement(this); if (getAuthToken() == null) {
if (sasl != null) { Element sasl = SASLAuthentication.getSASLMechanismsElement(this);
elements.add(sasl); if (sasl != null) {
elements.add(sasl);
}
} }
// Include Stream Compression Mechanism // Include Stream Compression Mechanism
......
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