Commit 35d49f8e authored by huni's avatar huni
parent b9f1163c
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
package org.jivesoftware.openfire.http; package org.jivesoftware.openfire.http;
import org.jivesoftware.util.JiveConstants;
import org.mortbay.util.ajax.Continuation; import org.mortbay.util.ajax.Continuation;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
...@@ -185,7 +186,7 @@ public class HttpConnection { ...@@ -185,7 +186,7 @@ public class HttpConnection {
} }
private String waitForResponse() throws HttpBindTimeoutException { private String waitForResponse() throws HttpBindTimeoutException {
if (continuation.suspend(session.getWait() * 1000)) { if (continuation.suspend(session.getWait() * JiveConstants.SECOND)) {
String deliverable = (String) continuation.getObject(); String deliverable = (String) continuation.getObject();
// This will occur when the hold attribute of a session has been exceded. // This will occur when the hold attribute of a session has been exceded.
this.isDelivered = true; this.isDelivered = true;
......
...@@ -89,6 +89,7 @@ public class HttpSession extends LocalClientSession { ...@@ -89,6 +89,7 @@ public class HttpSession extends LocalClientSession {
private long lastActivity; private long lastActivity;
private long lastRequestID; private long lastRequestID;
private int maxRequests; private int maxRequests;
private int maxPause;
private PacketDeliverer backupDeliverer; private PacketDeliverer backupDeliverer;
private int majorVersion = -1; private int majorVersion = -1;
private int minorVersion = -1; private int minorVersion = -1;
...@@ -285,6 +286,28 @@ public class HttpSession extends LocalClientSession { ...@@ -285,6 +286,28 @@ public class HttpSession extends LocalClientSession {
return this.maxRequests; return this.maxRequests;
} }
/**
* Sets the maximum length of a temporary session pause (in seconds) that the client MAY
* request.
*
* @param maxPause the maximum length of a temporary session pause (in seconds) that the client
* MAY request.
*/
public void setMaxPause(int maxPause) {
this.maxPause = maxPause;
}
/**
* Returns the maximum length of a temporary session pause (in seconds) that the client MAY
* request.
*
* @return the maximum length of a temporary session pause (in seconds) that the client MAY
* request.
*/
public int getMaxPause() {
return this.maxPause;
}
/** /**
* Returns true if all connections on this session should be secured, and false if they should * Returns true if all connections on this session should be secured, and false if they should
* not. * not.
...@@ -296,6 +319,15 @@ public class HttpSession extends LocalClientSession { ...@@ -296,6 +319,15 @@ public class HttpSession extends LocalClientSession {
return isSecure; return isSecure;
} }
/**
* Returns true if this session is a polling session, i.e. wait or hold attribute is set to 0.
*
* @return true if this session is a polling session.
*/
public boolean isPollingSession() {
return (this.wait == 0 || this.hold == 0);
}
/** /**
* Adds a {@link org.jivesoftware.openfire.http.SessionListener} to this session. The listener * Adds a {@link org.jivesoftware.openfire.http.SessionListener} to this session. The listener
* will be notified of changes to the session. * will be notified of changes to the session.
...@@ -450,10 +482,10 @@ public class HttpSession extends LocalClientSession { ...@@ -450,10 +482,10 @@ public class HttpSession extends LocalClientSession {
} }
catch (HttpBindTimeoutException e) { catch (HttpBindTimeoutException e) {
// This connection timed out we need to increment the request count // This connection timed out we need to increment the request count
if (connection.getRequestId() != lastRequestID + 1) { /*if (connection.getRequestId() != lastRequestID + 1) {
throw new HttpBindException("Unexpected RID error.", throw new HttpBindException("Unexpected RID error.",
BoshBindingError.itemNotFound); BoshBindingError.itemNotFound);
} }*/
lastRequestID = connection.getRequestId(); lastRequestID = connection.getRequestId();
} }
if (response == null) { if (response == null) {
...@@ -546,9 +578,9 @@ public class HttpSession extends LocalClientSession { ...@@ -546,9 +578,9 @@ public class HttpSession extends LocalClientSession {
connection.deliverBody(createDeliverable(deliverable.deliverables)); connection.deliverBody(createDeliverable(deliverable.deliverables));
return connection; return connection;
} }
else if (rid > (lastRequestID + hold + 1)) { else if (rid > (lastRequestID + maxRequests)) {
// TODO handle the case of greater RID which basically has it wait // TODO handle the case of greater RID which basically has it wait
Log.warn("Request " + rid + " > " + (lastRequestID + hold + 1) + ", ending session."); Log.warn("Request " + rid + " > " + (lastRequestID + maxRequests) + ", ending session.");
throw new HttpBindException("Unexpected RID error.", throw new HttpBindException("Unexpected RID error.",
BoshBindingError.itemNotFound); BoshBindingError.itemNotFound);
} }
...@@ -589,10 +621,12 @@ public class HttpSession extends LocalClientSession { ...@@ -589,10 +621,12 @@ public class HttpSession extends LocalClientSession {
connection.setSession(this); connection.setSession(this);
// We aren't supposed to hold connections open or we already have some packets waiting // We aren't supposed to hold connections open or we already have some packets waiting
// to be sent to the client. // to be sent to the client.
if (hold <= 0 || (pendingElements.size() > 0 && connection.getRequestId() == lastRequestID + 1)) { if (hold <= 0 || wait <= 0 || (pendingElements.size() > 0 && connection.getRequestId() == lastRequestID + 1)) {
deliver(connection, pendingElements); deliver(connection, pendingElements);
lastRequestID = connection.getRequestId(); lastRequestID = connection.getRequestId();
pendingElements.clear(); pendingElements.clear();
connectionQueue.add(connection);
Collections.sort(connectionQueue, connectionComparator);
} }
else { else {
// With this connection we need to check if we will have too many connections open, // With this connection we need to check if we will have too many connections open,
...@@ -600,7 +634,9 @@ public class HttpSession extends LocalClientSession { ...@@ -600,7 +634,9 @@ public class HttpSession extends LocalClientSession {
// Number of current connections open plus the current one tells us how many that // Number of current connections open plus the current one tells us how many that
// we need to close. // we need to close.
int connectionsToClose = (getOpenConnectionCount() + 1) - hold; connectionQueue.add(connection);
Collections.sort(connectionQueue, connectionComparator);
int connectionsToClose = getOpenConnectionCount() - hold;
int closed = 0; int closed = 0;
for (int i = 0; i < connectionQueue.size() && closed < connectionsToClose; i++) { for (int i = 0; i < connectionQueue.size() && closed < connectionsToClose; i++) {
HttpConnection toClose = connectionQueue.get(i); HttpConnection toClose = connectionQueue.get(i);
...@@ -611,8 +647,6 @@ public class HttpSession extends LocalClientSession { ...@@ -611,8 +647,6 @@ public class HttpSession extends LocalClientSession {
} }
} }
} }
connectionQueue.add(connection);
Collections.sort(connectionQueue, connectionComparator);
fireConnectionOpened(connection); fireConnectionOpened(connection);
} }
......
...@@ -131,7 +131,15 @@ public class HttpSessionManager { ...@@ -131,7 +131,15 @@ public class HttpSessionManager {
session.setSecure(connection.isSecure()); session.setSecure(connection.isSecure());
session.setMaxPollingInterval(getPollingInterval()); session.setMaxPollingInterval(getPollingInterval());
session.setMaxRequests(getMaxRequests()); session.setMaxRequests(getMaxRequests());
session.setMaxPause(getMaxPause());
if(session.isPollingSession()) {
session.setInactivityTimeout(getPollingInactivityTimeout());
}
else {
session.setInactivityTimeout(getInactivityTimeout()); session.setInactivityTimeout(getInactivityTimeout());
}
// Store language and version information in the connection. // Store language and version information in the connection.
session.setLanaguage(language); session.setLanaguage(language);
...@@ -154,6 +162,17 @@ public class HttpSessionManager { ...@@ -154,6 +162,17 @@ public class HttpSessionManager {
} }
/**
* Returns the maximum length of a temporary session pause (in seconds) that the client MAY
* request.
*
* @return the maximum length of a temporary session pause (in seconds) that the client MAY
* request.
*/
public int getMaxPause() {
return JiveGlobals.getIntProperty("xmpp.httpbind.client.maxpause", 300);
}
/** /**
* Returns the longest time (in seconds) that Openfire is allowed to wait before responding to * Returns the longest time (in seconds) that Openfire is allowed to wait before responding to
* any request during the session. This enables the client to prevent its TCP connection from * any request during the session. This enables the client to prevent its TCP connection from
...@@ -196,7 +215,7 @@ public class HttpSessionManager { ...@@ -196,7 +215,7 @@ public class HttpSessionManager {
} }
/** /**
* Seconds a session has to be idle to be closed. Default is 30 minutes. Sending stanzas to the * Seconds a session has to be idle to be closed. Default is 30. Sending stanzas to the
* client is not considered as activity. We are only considering the connection active when the * client is not considered as activity. We are only considering the connection active when the
* client sends some data or hearbeats (i.e. whitespaces) to the server. The reason for this is * client sends some data or hearbeats (i.e. whitespaces) to the server. The reason for this is
* that sending data will fail if the connection is closed. And if the thread is blocked while * that sending data will fail if the connection is closed. And if the thread is blocked while
...@@ -209,6 +228,20 @@ public class HttpSessionManager { ...@@ -209,6 +228,20 @@ public class HttpSessionManager {
return JiveGlobals.getIntProperty("xmpp.httpbind.client.idle", 30); return JiveGlobals.getIntProperty("xmpp.httpbind.client.idle", 30);
} }
/**
* Seconds a polling session has to be idle to be closed. Default is 60. Sending stanzas to the
* client is not considered as activity. We are only considering the connection active when the
* client sends some data or hearbeats (i.e. whitespaces) to the server. The reason for this is
* that sending data will fail if the connection is closed. And if the thread is blocked while
* sending data (because the socket is closed) then the clean up thread will close the socket
* anyway.
*
* @return Seconds a polling session has to be idle to be closed.
*/
public int getPollingInactivityTimeout() {
return JiveGlobals.getIntProperty("xmpp.httpbind.client.idle.polling", 60);
}
/** /**
* Forwards a client request, which is related to a session, to the server. A connection is * Forwards a client request, which is related to a session, to the server. A connection is
* created and queued up in the provided session. When a connection reaches the top of a queue * created and queued up in the provided session. When a connection reaches the top of a queue
...@@ -286,6 +319,7 @@ public class HttpSessionManager { ...@@ -286,6 +319,7 @@ public class HttpSessionManager {
response.addAttribute("inactivity", String.valueOf(session.getInactivityTimeout())); response.addAttribute("inactivity", String.valueOf(session.getInactivityTimeout()));
response.addAttribute("polling", String.valueOf(session.getMaxPollingInterval())); response.addAttribute("polling", String.valueOf(session.getMaxPollingInterval()));
response.addAttribute("wait", String.valueOf(session.getWait())); response.addAttribute("wait", String.valueOf(session.getWait()));
response.addAttribute("maxpause", String.valueOf(session.getMaxPause()));
if ((session.getMajorVersion() == 1 && session.getMinorVersion() >= 6) || if ((session.getMajorVersion() == 1 && session.getMinorVersion() >= 6) ||
session.getMajorVersion() > 1) { session.getMajorVersion() > 1) {
response.addAttribute("hold", String.valueOf(session.getHold())); response.addAttribute("hold", String.valueOf(session.getHold()));
......
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