Commit bde9a920 authored by huni's avatar huni

Fixed the issue where BOSH session dropped when requests are received out of order. JM-1412.

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/branches@10600 b35dd754-fafc-0310-a699-88a17e54d16e
parent 35d49f8e
...@@ -482,10 +482,10 @@ public class HttpSession extends LocalClientSession { ...@@ -482,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) {
...@@ -578,9 +578,8 @@ public class HttpSession extends LocalClientSession { ...@@ -578,9 +578,8 @@ public class HttpSession extends LocalClientSession {
connection.deliverBody(createDeliverable(deliverable.deliverables)); connection.deliverBody(createDeliverable(deliverable.deliverables));
return connection; return connection;
} }
else if (rid > (lastRequestID + maxRequests)) { else if (rid > (lastRequestID + maxRequests + 5)) {
// TODO handle the case of greater RID which basically has it wait Log.warn("Request " + rid + " > " + (lastRequestID + maxRequests + 5) + ", 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);
} }
...@@ -621,7 +620,7 @@ public class HttpSession extends LocalClientSession { ...@@ -621,7 +620,7 @@ 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 || wait <= 0 || (pendingElements.size() > 0 && connection.getRequestId() == lastRequestID + 1)) { if (isPollingSession() || (pendingElements.size() > 0 && connection.getRequestId() == lastRequestID + 1)) {
deliver(connection, pendingElements); deliver(connection, pendingElements);
lastRequestID = connection.getRequestId(); lastRequestID = connection.getRequestId();
pendingElements.clear(); pendingElements.clear();
...@@ -632,17 +631,32 @@ public class HttpSession extends LocalClientSession { ...@@ -632,17 +631,32 @@ public class HttpSession extends LocalClientSession {
// 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,
// closing any extras. // closing any extras.
// Number of current connections open plus the current one tells us how many that
// we need to close.
connectionQueue.add(connection); connectionQueue.add(connection);
Collections.sort(connectionQueue, connectionComparator); Collections.sort(connectionQueue, connectionComparator);
int connectionsToClose = getOpenConnectionCount() - hold;
int connectionsToClose;
if(connectionQueue.get(connectionQueue.size() - 1) != connection) {
// Current connection does not have the greatest rid. That means
// requests were received out of order, respond to all.
connectionsToClose = connectionQueue.size();
}
else {
// Everything's fine, number of current connections open tells us
// how many that we need to close.
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);
if (!toClose.isClosed()) { if (!toClose.isClosed() && toClose.getRequestId() == lastRequestID + 1) {
lastRequestID = toClose.getRequestId(); if(toClose == connection) {
// Current connection has no continuation yet, just deliver.
deliver("");
}
else {
toClose.close(); toClose.close();
}
lastRequestID = toClose.getRequestId();
closed++; closed++;
} }
} }
......
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