Commit ce92522d authored by huni's avatar huni

Implemented overactivity checking.

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/branches@10609 b35dd754-fafc-0310-a699-88a17e54d16e
parent ac0d0320
...@@ -247,9 +247,11 @@ public class HttpBindServlet extends HttpServlet { ...@@ -247,9 +247,11 @@ public class HttpBindServlet extends HttpServlet {
else if (pauseDuration > 0 && pauseDuration <= session.getMaxPause()) { else if (pauseDuration > 0 && pauseDuration <= session.getMaxPause()) {
session.pause(pauseDuration); session.pause(pauseDuration);
respond(response, createEmptyBody(), request.getMethod()); respond(response, createEmptyBody(), request.getMethod());
session.setLastResponseEmpty(true);
} }
else { else {
session.resetInactivityTimeout(); session.resetInactivityTimeout();
session.setLastResponseEmpty(false);
connection.setContinuation(ContinuationSupport.getContinuation(request, connection)); connection.setContinuation(ContinuationSupport.getContinuation(request, connection));
request.setAttribute("request-session", connection.getSession()); request.setAttribute("request-session", connection.getSession());
request.setAttribute("request", connection.getRequestId()); request.setAttribute("request", connection.getRequestId());
...@@ -302,6 +304,7 @@ public class HttpBindServlet extends HttpServlet { ...@@ -302,6 +304,7 @@ public class HttpBindServlet extends HttpServlet {
} }
catch (HttpBindTimeoutException e) { catch (HttpBindTimeoutException e) {
content = createEmptyBody(); content = createEmptyBody();
connection.getSession().setLastResponseEmpty(false);
} }
respond(response, content, method); respond(response, content, method);
......
...@@ -26,6 +26,7 @@ import org.jivesoftware.openfire.net.MXParser; ...@@ -26,6 +26,7 @@ import org.jivesoftware.openfire.net.MXParser;
import org.jivesoftware.openfire.net.SASLAuthentication; import org.jivesoftware.openfire.net.SASLAuthentication;
import org.jivesoftware.openfire.net.VirtualConnection; import org.jivesoftware.openfire.net.VirtualConnection;
import org.jivesoftware.openfire.session.LocalClientSession; import org.jivesoftware.openfire.session.LocalClientSession;
import org.jivesoftware.util.JiveConstants;
import org.jivesoftware.util.Log; import org.jivesoftware.util.Log;
import org.jivesoftware.util.JiveGlobals; import org.jivesoftware.util.JiveGlobals;
import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException;
...@@ -89,6 +90,7 @@ public class HttpSession extends LocalClientSession { ...@@ -89,6 +90,7 @@ public class HttpSession extends LocalClientSession {
private int defaultInactivityTimeout; private int defaultInactivityTimeout;
private long lastActivity; private long lastActivity;
private long lastRequestID; private long lastRequestID;
private boolean lastResponseEmpty;
private int maxRequests; private int maxRequests;
private int maxPause; private int maxPause;
private PacketDeliverer backupDeliverer; private PacketDeliverer backupDeliverer;
...@@ -528,6 +530,16 @@ public class HttpSession extends LocalClientSession { ...@@ -528,6 +530,16 @@ public class HttpSession extends LocalClientSession {
return 5; return 5;
} }
} }
/**
* lastResponseEmpty true if last response of this session is an empty body element. This
* is used in overactivity checking.
*
* @param lastResponseEmpty true if last response of this session is an empty body element.
*/
public void setLastResponseEmpty(boolean lastResponseEmpty) {
this.lastResponseEmpty = lastResponseEmpty;
}
public String getResponse(long requestID) throws HttpBindException { public String getResponse(long requestID) throws HttpBindException {
for (HttpConnection connection : connectionQueue) { for (HttpConnection connection : connectionQueue) {
...@@ -560,6 +572,7 @@ public class HttpSession extends LocalClientSession { ...@@ -560,6 +572,7 @@ public class HttpSession extends LocalClientSession {
} }
if (response == null) { if (response == null) {
response = createEmptyBody(); response = createEmptyBody();
setLastResponseEmpty(true);
} }
return response; return response;
} }
...@@ -676,9 +689,7 @@ public class HttpSession extends LocalClientSession { ...@@ -676,9 +689,7 @@ public class HttpSession extends LocalClientSession {
throw new IllegalArgumentException("Connection cannot be null."); throw new IllegalArgumentException("Connection cannot be null.");
} }
if (isPoll) { checkOveractivity(isPoll);
checkPollingInterval();
}
if (isSecure && !connection.isSecure()) { if (isSecure && !connection.isSecure()) {
throw new HttpBindException("Session was started from secure connection, all " + throw new HttpBindException("Session was started from secure connection, all " +
...@@ -763,19 +774,47 @@ public class HttpSession extends LocalClientSession { ...@@ -763,19 +774,47 @@ public class HttpSession extends LocalClientSession {
listener.connectionOpened(this, connection); listener.connectionOpened(this, connection);
} }
} }
private void checkPollingInterval() throws HttpBindException { /**
long time = System.currentTimeMillis(); * @see {@link http://www.xmpp.org/extensions/xep-0124.html#overactive}.
if (((time - lastPoll) / 1000) < maxPollingInterval) { */
Log.debug("Too frequent polling minimum interval is " private void checkOveractivity(boolean isPoll) throws HttpBindException {
+ maxPollingInterval + ", current interval " + ((time - lastPoll) / 1000)); int pendingConnections = 0;
if (!JiveGlobals.getBooleanProperty("xmpp.httpbind.client.requests.ignorePollingCap", false)) { boolean overactivity = false;
throw new HttpBindException("Too frequent polling minimum interval is " String errorMessage = "Overactivity detected";
+ maxPollingInterval + ", current interval " + ((time - lastPoll) / 1000),
BoshBindingError.policyViolation); for (int i = 0; i < connectionQueue.size(); i++) {
HttpConnection conn = connectionQueue.get(i);
if (!conn.isClosed()) {
pendingConnections++;
}
}
if(pendingConnections >= maxRequests) {
overactivity = true;
errorMessage += ", too many simultaneous requests.";
}
else if(isPoll) {
long time = System.currentTimeMillis();
if (time - lastPoll < maxPollingInterval * JiveConstants.SECOND) {
if(isPollingSession()) {
overactivity = lastResponseEmpty;
}
else {
overactivity = (pendingConnections >= maxRequests - 1);
}
}
lastPoll = time;
errorMessage += ", minimum polling interval is "
+ maxPollingInterval + ", current interval " + ((time - lastPoll) / 1000);
}
if(overactivity) {
Log.debug(errorMessage);
if (!JiveGlobals.getBooleanProperty("xmpp.httpbind.client.requests.ignoreOveractivity", false)) {
throw new HttpBindException(errorMessage, BoshBindingError.policyViolation);
} }
} }
lastPoll = time;
} }
private synchronized void deliver(String text) { private synchronized void deliver(String text) {
......
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