java: Close broken connections [THRIFT-73]
Fixes a bug where TNonblockingServer (and by extension THsHaServer) could
permanently lose track of client connections if the message on-wire was
malformed. If the client sends a bad message now, the server will close the
transport at its earliest convenience.
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@676456 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/java/src/com/facebook/thrift/server/TNonblockingServer.java b/lib/java/src/com/facebook/thrift/server/TNonblockingServer.java
index d09ec67..1e1284f 100644
--- a/lib/java/src/com/facebook/thrift/server/TNonblockingServer.java
+++ b/lib/java/src/com/facebook/thrift/server/TNonblockingServer.java
@@ -423,6 +423,8 @@
private static final int WRITING = 6;
// another thread wants this framebuffer to go back to reading
private static final int AWAITING_REGISTER_READ = 7;
+ // we want our transport and selection key invalidated in the selector thread
+ private static final int AWAITING_CLOSE = 8;
//
// Instance variables
@@ -548,6 +550,9 @@
state_ = WRITING;
} else if (state_ == AWAITING_REGISTER_READ) {
prepareRead();
+ } else if (state_ == AWAITING_CLOSE){
+ close();
+ selectionKey_.cancel();
} else {
LOGGER.severe(
"changeSelectInterest was called, but state is invalid ("
@@ -607,9 +612,15 @@
try {
processorFactory_.getProcessor(inTrans).process(inProt, outProt);
responseReady();
+ return;
} catch (TException te) {
LOGGER.log(Level.WARNING, "Exception while invoking!", te);
+ } catch (Exception e) {
+ LOGGER.log(Level.SEVERE, "Unexpected exception while invoking!", e);
}
+ // This will only be reached when there is an exception.
+ state_ = AWAITING_CLOSE;
+ requestSelectInterestChange();
}
/**