Added check for key validity before changing interestOps to avoid pointless exception.
Modified message buffering code to not load the next message to be sent if we are waiting for more content from the current message (currently shouldn't happen).
This commit is contained in:
@@ -331,12 +331,12 @@ public class WebServer {
|
|||||||
|
|
||||||
if(requiresWrite) {
|
if(requiresWrite) {
|
||||||
if(!hasWrite) {
|
if(!hasWrite) {
|
||||||
key.interestOps(ops | SelectionKey.OP_WRITE);
|
if(key.isValid()) key.interestOps(ops | SelectionKey.OP_WRITE);
|
||||||
}//if//
|
}//if//
|
||||||
}//if//
|
}//if//
|
||||||
else {
|
else {
|
||||||
if(hasWrite) {
|
if(hasWrite) {
|
||||||
key.interestOps(ops ^ SelectionKey.OP_WRITE);
|
if(key.isValid()) key.interestOps(ops ^ SelectionKey.OP_WRITE);
|
||||||
}//if//
|
}//if//
|
||||||
}//else//
|
}//else//
|
||||||
}//synchronized//
|
}//synchronized//
|
||||||
@@ -352,12 +352,12 @@ public class WebServer {
|
|||||||
|
|
||||||
if(requiresRead) {
|
if(requiresRead) {
|
||||||
if(!hasRead) {
|
if(!hasRead) {
|
||||||
key.interestOps(ops | SelectionKey.OP_READ);
|
if(key.isValid()) key.interestOps(ops | SelectionKey.OP_READ);
|
||||||
}//if//
|
}//if//
|
||||||
}//if//
|
}//if//
|
||||||
else {
|
else {
|
||||||
if(hasRead) {
|
if(hasRead) {
|
||||||
key.interestOps(ops ^ SelectionKey.OP_READ);
|
if(key.isValid()) key.interestOps(ops ^ SelectionKey.OP_READ);
|
||||||
}//if//
|
}//if//
|
||||||
}//else//
|
}//else//
|
||||||
}//synchronized//
|
}//synchronized//
|
||||||
@@ -390,22 +390,22 @@ public class WebServer {
|
|||||||
}//if//
|
}//if//
|
||||||
}//else//
|
}//else//
|
||||||
|
|
||||||
key.interestOps(ops);
|
if(key.isValid()) key.interestOps(ops);
|
||||||
}//synchronized//
|
}//synchronized//
|
||||||
}//flagReadWrite()//
|
}//flagReadWrite()//
|
||||||
protected void flagReadWrite() {
|
protected void flagReadWrite() {
|
||||||
synchronized(key) {
|
synchronized(key) {
|
||||||
key.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
|
if(key.isValid()) key.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
|
||||||
}//synchronized//
|
}//synchronized//
|
||||||
}//flagReadWrite()//
|
}//flagReadWrite()//
|
||||||
protected void flagWriteOnly() {
|
protected void flagWriteOnly() {
|
||||||
synchronized(key) {
|
synchronized(key) {
|
||||||
key.interestOps(SelectionKey.OP_WRITE);
|
if(key.isValid()) key.interestOps(SelectionKey.OP_WRITE);
|
||||||
}//synchronized//
|
}//synchronized//
|
||||||
}//flagWriteOnly()//
|
}//flagWriteOnly()//
|
||||||
protected void flagReadOnly() {
|
protected void flagReadOnly() {
|
||||||
synchronized(key) {
|
synchronized(key) {
|
||||||
key.interestOps(SelectionKey.OP_READ);
|
if(key.isValid()) key.interestOps(SelectionKey.OP_READ);
|
||||||
}//synchronized//
|
}//synchronized//
|
||||||
}//flagReadOnly()//
|
}//flagReadOnly()//
|
||||||
}//AbstractSocketContext//
|
}//AbstractSocketContext//
|
||||||
@@ -1275,8 +1275,9 @@ public class WebServer {
|
|||||||
if(result && pendingOutboundMessage != null) {
|
if(result && pendingOutboundMessage != null) {
|
||||||
//Check to see if the outbound message is prepared to send more content. For chunked transfers the outbound message may be waiting for additional content from another stream and we should return later.//
|
//Check to see if the outbound message is prepared to send more content. For chunked transfers the outbound message may be waiting for additional content from another stream and we should return later.//
|
||||||
if(result && !pendingOutboundMessage.getBuffer().hasRemaining()) {
|
if(result && !pendingOutboundMessage.getBuffer().hasRemaining()) {
|
||||||
|
|
||||||
if(!pendingOutboundMessage.loadBuffer()) {
|
if(!pendingOutboundMessage.loadBuffer()) {
|
||||||
if(pendingOutboundMessage.getNext() != null) {
|
if(pendingOutboundMessage.getBuffer() == null && pendingOutboundMessage.getNext() != null) {
|
||||||
pendingOutboundMessage = pendingOutboundMessage.getNext();
|
pendingOutboundMessage = pendingOutboundMessage.getNext();
|
||||||
}//if//
|
}//if//
|
||||||
else {
|
else {
|
||||||
@@ -1410,7 +1411,7 @@ public class WebServer {
|
|||||||
|
|
||||||
if(!pendingOutboundMessage.loadBuffer()) {
|
if(!pendingOutboundMessage.loadBuffer()) {
|
||||||
//Load the next pending outbound message in the chain. This is currently only used for content being passed through to another process via a second socket.//
|
//Load the next pending outbound message in the chain. This is currently only used for content being passed through to another process via a second socket.//
|
||||||
if(pendingOutboundMessage.getNext() != null) {
|
if(pendingOutboundMessage.getBuffer() == null && pendingOutboundMessage.getNext() != null) {
|
||||||
pendingOutboundMessage = pendingOutboundMessage.getNext();
|
pendingOutboundMessage = pendingOutboundMessage.getNext();
|
||||||
}//if//
|
}//if//
|
||||||
else {
|
else {
|
||||||
@@ -1445,7 +1446,7 @@ public class WebServer {
|
|||||||
else {
|
else {
|
||||||
if(!pendingOutboundMessage.loadBuffer()) {
|
if(!pendingOutboundMessage.loadBuffer()) {
|
||||||
//Load the next pending outbound message in the chain. This is currently only used for content being passed through to another process via a second socket.//
|
//Load the next pending outbound message in the chain. This is currently only used for content being passed through to another process via a second socket.//
|
||||||
if(pendingOutboundMessage.getNext() != null) {
|
if(pendingOutboundMessage.getBuffer() == null && pendingOutboundMessage.getNext() != null) {
|
||||||
pendingOutboundMessage = pendingOutboundMessage.getNext();
|
pendingOutboundMessage = pendingOutboundMessage.getNext();
|
||||||
}//if//
|
}//if//
|
||||||
else {
|
else {
|
||||||
@@ -1513,7 +1514,7 @@ public class WebServer {
|
|||||||
* @see com.foundation.web.server.WebServer.AbstractSocketContext#processRequest()
|
* @see com.foundation.web.server.WebServer.AbstractSocketContext#processRequest()
|
||||||
*/
|
*/
|
||||||
protected void processRequest() throws IOException {
|
protected void processRequest() throws IOException {
|
||||||
boolean result = true;
|
boolean requiresRead = true;
|
||||||
SocketChannel channel = (SocketChannel) key.channel();
|
SocketChannel channel = (SocketChannel) key.channel();
|
||||||
|
|
||||||
if(isSsl()) {
|
if(isSsl()) {
|
||||||
@@ -1602,7 +1603,7 @@ public class WebServer {
|
|||||||
if(sslEngine != null) {
|
if(sslEngine != null) {
|
||||||
//While we have a count greater than zero, indicating that some data is comming through, keep reading and processing the data.//
|
//While we have a count greater than zero, indicating that some data is comming through, keep reading and processing the data.//
|
||||||
//Note: We are throddling this for active connections to prevent a single connection from hogging all the resources.//
|
//Note: We are throddling this for active connections to prevent a single connection from hogging all the resources.//
|
||||||
while(channel.isOpen() && loopCount < 10 && result && keepReading) {
|
while(channel.isOpen() && loopCount < 10 && requiresRead && keepReading) {
|
||||||
int readCount = -1;
|
int readCount = -1;
|
||||||
|
|
||||||
//Track how many loops we run so that we don't hog all the server's resources with one connection.//
|
//Track how many loops we run so that we don't hog all the server's resources with one connection.//
|
||||||
@@ -1654,7 +1655,7 @@ public class WebServer {
|
|||||||
sslResult = sslEngine.unwrap(encryptedReadBuffer, unencryptedReadBuffer);
|
sslResult = sslEngine.unwrap(encryptedReadBuffer, unencryptedReadBuffer);
|
||||||
unencryptedReadBuffer.flip();
|
unencryptedReadBuffer.flip();
|
||||||
|
|
||||||
//Check the result of the SSL processing.//
|
//Check the requiresRead of the SSL processing.//
|
||||||
if(sslResult.getStatus() == Status.BUFFER_UNDERFLOW) {
|
if(sslResult.getStatus() == Status.BUFFER_UNDERFLOW) {
|
||||||
//Buffer underflow indicates we haven't enough bytes to finish processing the next frame of data.//
|
//Buffer underflow indicates we haven't enough bytes to finish processing the next frame of data.//
|
||||||
break;
|
break;
|
||||||
@@ -1684,11 +1685,11 @@ public class WebServer {
|
|||||||
|
|
||||||
//Need to synchronize if this is a pass through socket so that multiple threads don't access pendingOutboundMessage or lastAddedMessageBuffer (via a call to passThrough(ByteBuffer) on another thread).//
|
//Need to synchronize if this is a pass through socket so that multiple threads don't access pendingOutboundMessage or lastAddedMessageBuffer (via a call to passThrough(ByteBuffer) on another thread).//
|
||||||
if(getPassThroughSocketContext() == null) {
|
if(getPassThroughSocketContext() == null) {
|
||||||
result = writeClientResponse();
|
requiresRead = writeClientResponse();
|
||||||
}//if//
|
}//if//
|
||||||
else {
|
else {
|
||||||
synchronized(this) {
|
synchronized(this) {
|
||||||
result = writeClientResponse();
|
requiresRead = writeClientResponse();
|
||||||
}//synchronized//
|
}//synchronized//
|
||||||
}//else//
|
}//else//
|
||||||
}//if//
|
}//if//
|
||||||
@@ -1697,14 +1698,14 @@ public class WebServer {
|
|||||||
if(sslResult.bytesProduced() > 0) {
|
if(sslResult.bytesProduced() > 0) {
|
||||||
//If we are not passing all content to another process then handle it by calling processClientRequest, otherwise pass it through.//
|
//If we are not passing all content to another process then handle it by calling processClientRequest, otherwise pass it through.//
|
||||||
if(getPassThroughSocketContext() == null) {
|
if(getPassThroughSocketContext() == null) {
|
||||||
result = WebServer.this.processClientRequest((SocketContext) this, unencryptedReadBuffer, key);
|
requiresRead = WebServer.this.processClientRequest((SocketContext) this, unencryptedReadBuffer, key);
|
||||||
}//if//
|
}//if//
|
||||||
else {
|
else {
|
||||||
//TODO: Comment me.
|
//TODO: Comment me.
|
||||||
//Debug.log("Receiving message (" + unencryptedReadBuffer.remaining() + " bytes) from client for git.");
|
//Debug.log("Receiving message (" + unencryptedReadBuffer.remaining() + " bytes) from client for git.");
|
||||||
//Queue the data for sending to the remote process via the pass through socket context.//
|
//Queue the data for sending to the remote process via the pass through socket context.//
|
||||||
getPassThroughSocketContext().passThrough(unencryptedReadBuffer);
|
getPassThroughSocketContext().passThrough(unencryptedReadBuffer);
|
||||||
result = true;
|
requiresRead = true;
|
||||||
}//else//
|
}//else//
|
||||||
}//if//
|
}//if//
|
||||||
}//else if//
|
}//else if//
|
||||||
@@ -1729,7 +1730,7 @@ public class WebServer {
|
|||||||
|
|
||||||
//While we have a count greater than zero, indicating that some data is comming through, keep reading and processing the data.//
|
//While we have a count greater than zero, indicating that some data is comming through, keep reading and processing the data.//
|
||||||
//Note: We are throddling this for active connections to prevent a single connection from hogging all the resources.//
|
//Note: We are throddling this for active connections to prevent a single connection from hogging all the resources.//
|
||||||
while(loopCount < 10 && result && count > 0) {
|
while(loopCount < 10 && requiresRead && count > 0) {
|
||||||
loopCount++;
|
loopCount++;
|
||||||
//Allow data to be left on the socket read buffer.//
|
//Allow data to be left on the socket read buffer.//
|
||||||
if(socketReadBuffer.position() != 0) socketReadBuffer.compact();
|
if(socketReadBuffer.position() != 0) socketReadBuffer.compact();
|
||||||
@@ -1767,7 +1768,7 @@ public class WebServer {
|
|||||||
relatedSocketContext.passThrough(socketReadBuffer);
|
relatedSocketContext.passThrough(socketReadBuffer);
|
||||||
}//else if//
|
}//else if//
|
||||||
else if(socketReadBuffer.hasRemaining()) {
|
else if(socketReadBuffer.hasRemaining()) {
|
||||||
result = WebServer.this.processClientRequest((SocketContext) this, socketReadBuffer, key);
|
requiresRead = WebServer.this.processClientRequest((SocketContext) this, socketReadBuffer, key);
|
||||||
}//else//
|
}//else//
|
||||||
else {
|
else {
|
||||||
break;
|
break;
|
||||||
@@ -1775,7 +1776,7 @@ public class WebServer {
|
|||||||
}//while//
|
}//while//
|
||||||
}//else//
|
}//else//
|
||||||
|
|
||||||
if(result) {
|
if(requiresRead) {
|
||||||
flagReadOnly();
|
flagReadOnly();
|
||||||
}//if//
|
}//if//
|
||||||
else {
|
else {
|
||||||
|
|||||||
Reference in New Issue
Block a user