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 {
* 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.
*/
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
* '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
* '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)
* 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
* 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
* of the expected window, (4) connection manager is unable to resend response, (5) 'key'
* 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
* terminate.
*/
otherRequest(Type.terminal, "other-request"),
otherRequest(Type.terminate, "other-request"),
/**
* The client has broken the session rules (polling too frequently, requesting too frequently,
* too many simultaneous requests).
*/
policyViolation(Type.terminal, "policy-violation",
policyViolation(Type.terminate, "policy-violation",
HttpServletResponse.SC_FORBIDDEN),
/**
* The connection manager was unable to connect to, or unable to connect securely to, or has
* 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.
*/
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
* 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
* 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
* 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
* application-specific information in the content of the <body> wrapper.
*/
undefinedCondition(Type.terminal, "undefined-condition");
undefinedCondition(Type.terminate, "undefined-condition");
private Type errorType;
private String condition;
......@@ -127,10 +127,10 @@ public enum BoshBindingError {
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.
*/
terminal(null),
terminate(null),
/**
* 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
......
......@@ -28,6 +28,6 @@ public class HttpBindException extends Exception {
}
public boolean shouldCloseSession() {
return error.getErrorType() == BoshBindingError.Type.terminal;
return error.getErrorType() == BoshBindingError.Type.terminate;
}
}
......@@ -12,10 +12,7 @@
package org.jivesoftware.openfire.http;
import org.apache.commons.lang.StringEscapeUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.*;
import org.dom4j.io.XMPPPacketReader;
import org.jivesoftware.openfire.auth.UnauthorizedException;
import org.jivesoftware.openfire.net.MXParser;
......@@ -192,7 +189,7 @@ public class HttpBindServlet extends HttpServlet {
}
}
finally {
if (bindingError.getErrorType() == BoshBindingError.Type.terminal) {
if (bindingError.getErrorType() == BoshBindingError.Type.terminate) {
session.close();
}
}
......@@ -242,12 +239,21 @@ public class HttpBindServlet extends HttpServlet {
}
String type = rootNode.attributeValue("type");
String restartStream = rootNode.attributeValue(new QName("restart", rootNode.getNamespaceForPrefix("xmpp")));
int pauseDuration = getIntAttribue(rootNode.attributeValue("pause"), -1);
if ("terminate".equals(type)) {
session.close();
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()) {
session.pause(pauseDuration);
respond(session, response, createEmptyBody(), request.getMethod());
......@@ -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,
Element rootNode)
throws IOException
......
......@@ -127,10 +127,12 @@ public class HttpSession extends LocalClientSession {
public Collection<Element> getAvailableStreamFeaturesElements() {
List<Element> elements = new ArrayList<Element>();
if (getAuthToken() == null) {
Element sasl = SASLAuthentication.getSASLMechanismsElement(this);
if (sasl != null) {
elements.add(sasl);
}
}
// Include Stream Compression Mechanism
if (conn.getCompressionPolicy() != Connection.CompressionPolicy.disabled &&
......
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