Split sending message code into SSL and plain.
This commit is contained in:
@@ -235,8 +235,8 @@ private void queueOutboundClientMessage(MessageBuffer messageBuffer) {
|
||||
if(currentOutboundMessage == null) {
|
||||
lastOutboundMessage = currentOutboundMessage = messageBuffer;
|
||||
notify = true;
|
||||
}//if//
|
||||
else {
|
||||
}//if//
|
||||
else {
|
||||
lastOutboundMessage.setNext(messageBuffer);
|
||||
lastOutboundMessage = messageBuffer;
|
||||
}//else//
|
||||
@@ -244,7 +244,7 @@ private void queueOutboundClientMessage(MessageBuffer messageBuffer) {
|
||||
|
||||
if(notify) {
|
||||
notifyListenerOfPendingWrite();
|
||||
}//if//
|
||||
}//if//
|
||||
}//queueOutboundClientMessage()//
|
||||
private void writeSessionCookies(PrintStream pout) {
|
||||
Response response = currentResponse;
|
||||
@@ -554,22 +554,22 @@ public synchronized boolean sendHttpResponse(Response response) {
|
||||
* @see com.foundation.web.server.WebServer.AbstractSocketContext#passThrough(java.nio.ByteBuffer)
|
||||
*/
|
||||
protected synchronized boolean passThrough(ByteBuffer buffer) {
|
||||
ByteBuffer messageBytes = ByteBuffer.allocate(buffer.remaining());
|
||||
MessageBuffer message;
|
||||
|
||||
//Create a new buffer to hold the data so we don't modify the passed buffer (other than to update its position).//
|
||||
messageBytes = ByteBuffer.allocate(buffer.remaining());
|
||||
messageBytes.put(buffer);
|
||||
message = new MessageBuffer(messageBytes);
|
||||
|
||||
//Chain the message into the linked list.
|
||||
if(lastOutboundMessage == null || currentOutboundMessage == null) {
|
||||
currentOutboundMessage = lastOutboundMessage = message;
|
||||
}//if//
|
||||
else {
|
||||
lastOutboundMessage.setNext(message);
|
||||
lastOutboundMessage = message;
|
||||
}//else//
|
||||
// ByteBuffer messageBytes = ByteBuffer.allocate(buffer.remaining());
|
||||
// MessageBuffer message;
|
||||
//
|
||||
// //Create a new buffer to hold the data so we don't modify the passed buffer (other than to update its position).//
|
||||
// messageBytes = ByteBuffer.allocate(buffer.remaining());
|
||||
// messageBytes.put(buffer);
|
||||
// message = new MessageBuffer(messageBytes);
|
||||
//
|
||||
// //Chain the message into the linked list.
|
||||
// if(lastOutboundMessage == null || currentOutboundMessage == null) {
|
||||
// currentOutboundMessage = lastOutboundMessage = message;
|
||||
// }//if//
|
||||
// else {
|
||||
// lastOutboundMessage.setNext(message);
|
||||
// lastOutboundMessage = message;
|
||||
// }//else//
|
||||
|
||||
return true;
|
||||
}//passThrough()//
|
||||
@@ -578,18 +578,18 @@ protected synchronized boolean passThrough(ByteBuffer buffer) {
|
||||
*/
|
||||
protected void writeOutgoingMessages() throws IOException {
|
||||
if(getPassThroughSocketContext() != null) {
|
||||
//Synchronized to avoid multiple threads accessing the pendingOutboundMessage chain at one time and updating the write flag out of order (could happen if we enabled request chaining over a single socket).//
|
||||
synchronized(this) {
|
||||
writeClientBoundMessage();
|
||||
}//synchronized//
|
||||
// //Synchronized to avoid multiple threads accessing the pendingOutboundMessage chain at one time and updating the write flag out of order (could happen if we enabled request chaining over a single socket).//
|
||||
// synchronized(this) {
|
||||
// writeClientBoundMessage();
|
||||
// }//synchronized//
|
||||
}//if//
|
||||
else if(isWebsocket) {
|
||||
//Right after upgrading the socket we have one last HTTP response to process.//
|
||||
if(currentResponse != null) {
|
||||
internalProcessResponses();
|
||||
}//if//
|
||||
|
||||
internalProcessWebsocketMessages();
|
||||
// if(currentResponse != null) {
|
||||
// internalProcessResponses();
|
||||
// }//if//
|
||||
//
|
||||
// internalProcessWebsocketMessages();
|
||||
}//else if//
|
||||
else {
|
||||
//Go directly to writing the client response if we are just passing everything through to another process.//
|
||||
@@ -770,99 +770,92 @@ private synchronized void internalProcessResponses() {
|
||||
private boolean writeClientBoundMessage() {
|
||||
boolean sendMore = true;
|
||||
|
||||
// if(getWebServer().debug) {
|
||||
// debugBuffer.append("Starting a write cycle.\n");
|
||||
// }//if//
|
||||
|
||||
if(sslEngine != null) {
|
||||
sendMore = writeClientBoundSslMessage();
|
||||
}//if//
|
||||
else {
|
||||
sendMore = writeClientBoundPlainMessage();
|
||||
}//else//
|
||||
|
||||
return sendMore;
|
||||
}//writeClientBoundMessage()//
|
||||
/**
|
||||
* Sends a response to the client.
|
||||
* @return Whether the response could be fully sent. This will be false if there is still more data to be written when the call returns.
|
||||
*/
|
||||
private boolean writeClientBoundSslMessage() {
|
||||
boolean sendMore = true;
|
||||
|
||||
try {
|
||||
//Process SSL output first.//
|
||||
if(sslEngine != null) {
|
||||
//If we have part of an SSL frame then try to send it first.//
|
||||
if(encryptedWriteBuffer.hasRemaining()) {
|
||||
int remaining = encryptedWriteBuffer.remaining();
|
||||
//If we have part of an SSL frame then try to send it first.//
|
||||
if(encryptedWriteBuffer.hasRemaining()) {
|
||||
int remaining = encryptedWriteBuffer.remaining();
|
||||
|
||||
//Write the bytes to the stream.//
|
||||
((SocketChannel) key.channel()).write(encryptedWriteBuffer);
|
||||
|
||||
// if(getWebServer().debug) {
|
||||
// debugBuffer.append("Wrote " + (remaining - encryptedWriteBuffer.remaining()) + " encrypted bytes to the stream. " + encryptedWriteBuffer.remaining() + " remain.\n");
|
||||
// }//if//
|
||||
|
||||
//Check to see if we failed to send the whole frame.//
|
||||
if(encryptedWriteBuffer.hasRemaining()) {
|
||||
sendMore = false;
|
||||
}//if//
|
||||
}//if//
|
||||
//Write the bytes to the stream.//
|
||||
((SocketChannel) key.channel()).write(encryptedWriteBuffer);
|
||||
|
||||
while(sendMore && sslNeedsWrap) {
|
||||
SSLEngineResult handshakeResult;
|
||||
|
||||
//Reset the encrypted write buffer - note that since we will never read while waiting to write data, this should always be empty.//
|
||||
encryptedWriteBuffer.position(0);
|
||||
encryptedWriteBuffer.limit(encryptedWriteBuffer.capacity());
|
||||
//Generate the handshake message.//
|
||||
handshakeResult = sslEngine.wrap(ByteBuffer.allocate(0), encryptedWriteBuffer);
|
||||
encryptedWriteBuffer.flip();
|
||||
|
||||
if(handshakeResult.getStatus() == Status.BUFFER_OVERFLOW) {
|
||||
//Check to see if we failed to send the whole frame.//
|
||||
if(encryptedWriteBuffer.hasRemaining()) {
|
||||
sendMore = false;
|
||||
}//if//
|
||||
}//if//
|
||||
|
||||
while(sendMore && sslNeedsWrap) {
|
||||
SSLEngineResult handshakeResult;
|
||||
|
||||
//Reset the encrypted write buffer - note that since we will never read while waiting to write data, this should always be empty.//
|
||||
encryptedWriteBuffer.position(0);
|
||||
encryptedWriteBuffer.limit(encryptedWriteBuffer.capacity());
|
||||
//Generate the handshake message.//
|
||||
handshakeResult = sslEngine.wrap(ByteBuffer.allocate(0), encryptedWriteBuffer);
|
||||
encryptedWriteBuffer.flip();
|
||||
|
||||
if(handshakeResult.getStatus() == Status.BUFFER_OVERFLOW) {
|
||||
//Should never happen.//
|
||||
Debug.log(new RuntimeException("Unexpected ssl engine buffer overflow."));
|
||||
}//if//
|
||||
else if(handshakeResult.getStatus() == Status.BUFFER_UNDERFLOW) {
|
||||
//Should never happen.//
|
||||
Debug.log(new RuntimeException("Unexpected ssl engine buffer underflow."));
|
||||
}//else if//
|
||||
else if(handshakeResult.getStatus() == Status.CLOSED) {
|
||||
//Should never happen.//
|
||||
Debug.log(new RuntimeException("Unexpected ssl engine closed."));
|
||||
//TODO: Handle this closure without an infinate loop...
|
||||
//Close the socket.//
|
||||
try {key.channel().close();}catch(Throwable e2) {}
|
||||
}//else if//
|
||||
else if(handshakeResult.getStatus() == Status.OK) {
|
||||
if(handshakeResult.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
|
||||
//Should never happen.//
|
||||
Debug.log(new RuntimeException("Unexpected ssl engine buffer overflow."));
|
||||
Debug.log(new RuntimeException("Unexpected ssl engine task."));
|
||||
}//if//
|
||||
else if(handshakeResult.getStatus() == Status.BUFFER_UNDERFLOW) {
|
||||
//Should never happen.//
|
||||
Debug.log(new RuntimeException("Unexpected ssl engine buffer underflow."));
|
||||
}//else if//
|
||||
else if(handshakeResult.getStatus() == Status.CLOSED) {
|
||||
//Should never happen.//
|
||||
Debug.log(new RuntimeException("Unexpected ssl engine closed."));
|
||||
//TODO: Handle this closure without an infinate loop...
|
||||
//Close the socket.//
|
||||
try {key.channel().close();}catch(Throwable e2) {}
|
||||
}//else if//
|
||||
else if(handshakeResult.getStatus() == Status.OK) {
|
||||
if(handshakeResult.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
|
||||
//Should never happen.//
|
||||
Debug.log(new RuntimeException("Unexpected ssl engine task."));
|
||||
else if(encryptedWriteBuffer.hasRemaining()) {
|
||||
int remaining = encryptedWriteBuffer.remaining();
|
||||
|
||||
//Write the bytes to the stream.//
|
||||
((SocketChannel) key.channel()).write(encryptedWriteBuffer);
|
||||
|
||||
//If not all the bytes could be written then we will need to wait until we can write more.//
|
||||
if(encryptedWriteBuffer.hasRemaining()) {
|
||||
//Leave the data in the encrypted write buffer for the writing operation to send it.//
|
||||
sendMore = false;
|
||||
}//if//
|
||||
else if(encryptedWriteBuffer.hasRemaining()) {
|
||||
int remaining = encryptedWriteBuffer.remaining();
|
||||
|
||||
//Write the bytes to the stream.//
|
||||
((SocketChannel) key.channel()).write(encryptedWriteBuffer);
|
||||
|
||||
// if(getWebServer().debug) {
|
||||
// debugBuffer.append("Sent " + (remaining - encryptedWriteBuffer.remaining()) + " encrypted bytes.\n");
|
||||
// }//if//
|
||||
|
||||
//If not all the bytes could be written then we will need to wait until we can write more.//
|
||||
if(encryptedWriteBuffer.hasRemaining()) {
|
||||
// if(getWebServer().debug) {
|
||||
// debugBuffer.append("Pausing due to a partially sent packet (while ssl handshaking). Bytes actually sent: " + encryptedWriteBuffer.position() + ". Bytes remaining: " + encryptedWriteBuffer.remaining() + ".\n");
|
||||
// }//if//
|
||||
|
||||
//Leave the data in the encrypted write buffer for the writing operation to send it.//
|
||||
sendMore = false;
|
||||
}//if//
|
||||
|
||||
//Update the SSL needs wrap flag.//
|
||||
if(handshakeResult.getHandshakeStatus() != HandshakeStatus.NEED_WRAP) {
|
||||
sslNeedsWrap = false;
|
||||
}//if//
|
||||
}//else if//
|
||||
else {
|
||||
|
||||
//Update the SSL needs wrap flag.//
|
||||
if(handshakeResult.getHandshakeStatus() != HandshakeStatus.NEED_WRAP) {
|
||||
sslNeedsWrap = false;
|
||||
}//else//
|
||||
}//if//
|
||||
}//else if//
|
||||
else {
|
||||
//Should never happen.//
|
||||
Debug.log(new RuntimeException("Unexpected ssl engine status code."));
|
||||
sslNeedsWrap = false;
|
||||
}//else//
|
||||
}//while//
|
||||
|
||||
// if(getWebServer().debug) {
|
||||
// debugBuffer.append("End Handshaking SSL\n");
|
||||
// }//if//
|
||||
}//if//
|
||||
}//else if//
|
||||
else {
|
||||
//Should never happen.//
|
||||
Debug.log(new RuntimeException("Unexpected ssl engine status code."));
|
||||
}//else//
|
||||
}//while//
|
||||
|
||||
if(sendMore && currentOutboundMessage != 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.//
|
||||
@@ -884,128 +877,82 @@ private boolean writeClientBoundMessage() {
|
||||
|
||||
//If we have an application response pending then send it now.//
|
||||
if(sendMore && currentOutboundMessage.getBuffer().hasRemaining()) {
|
||||
if(sslEngine != null) {
|
||||
//Keep sending encrypted frames until the output buffer is full, or we run out of message to send.//
|
||||
while(key.channel().isOpen() && sendMore && (currentOutboundMessage != null) && currentOutboundMessage.getBuffer().hasRemaining()) {
|
||||
SSLEngineResult encryptResult;
|
||||
// int offset = pendingOutboundMessage.getBuffer().position();
|
||||
//TODO: Comment me.
|
||||
//int rem = pendingOutboundMessage.getBuffer().remaining();
|
||||
//Reset the encrypted write buffer.//
|
||||
encryptedWriteBuffer.compact();
|
||||
//Encrypt the next message frame.//
|
||||
encryptResult = sslEngine.wrap(currentOutboundMessage.getBuffer(), encryptedWriteBuffer);
|
||||
encryptedWriteBuffer.flip();
|
||||
//TODO: Comment me.
|
||||
//Debug.log("Encrypting/Sending to client from Git " + (rem - pendingOutboundMessage.getBuffer().remaining()) + " bytes.");
|
||||
|
||||
// if(getWebServer().debug) {
|
||||
// sentBytes += (pendingOutboundMessage.position() - offset);
|
||||
// debugBuffer.append("Encrypted: " + (pendingOutboundMessage.position() - offset) + ". Total Encrypted: " + sentBytes + ". Encrypted size: " + encryptedWriteBuffer.limit() + ".\n");
|
||||
// }//if//
|
||||
|
||||
if(encryptResult.getStatus() == Status.BUFFER_OVERFLOW) {
|
||||
//Should never happen.//
|
||||
Debug.log(new RuntimeException("Unexpected ssl engine buffer overflow."));
|
||||
}//if//
|
||||
else if(encryptResult.getStatus() == Status.BUFFER_UNDERFLOW) {
|
||||
//Should never happen.//
|
||||
Debug.log(new RuntimeException("Unexpected ssl engine buffer underflow."));
|
||||
}//else if//
|
||||
else if(encryptResult.getStatus() == Status.CLOSED) {
|
||||
//Should never happen.//
|
||||
//Keep sending encrypted frames until the output buffer is full, or we run out of message to send.//
|
||||
while(key.channel().isOpen() && sendMore && (currentOutboundMessage != null) && currentOutboundMessage.getBuffer().hasRemaining()) {
|
||||
SSLEngineResult encryptResult;
|
||||
|
||||
//Reset the encrypted write buffer.//
|
||||
encryptedWriteBuffer.compact();
|
||||
//Encrypt the next message frame.//
|
||||
encryptResult = sslEngine.wrap(currentOutboundMessage.getBuffer(), encryptedWriteBuffer);
|
||||
encryptedWriteBuffer.flip();
|
||||
|
||||
if(encryptResult.getStatus() == Status.BUFFER_OVERFLOW) {
|
||||
//Should never happen.//
|
||||
Debug.log(new RuntimeException("Unexpected ssl engine buffer overflow."));
|
||||
}//if//
|
||||
else if(encryptResult.getStatus() == Status.BUFFER_UNDERFLOW) {
|
||||
//Should never happen.//
|
||||
Debug.log(new RuntimeException("Unexpected ssl engine buffer underflow."));
|
||||
}//else if//
|
||||
else if(encryptResult.getStatus() == Status.CLOSED) {
|
||||
//Should never happen.//
|
||||
// Debug.log(new RuntimeException("Unexpected ssl engine closed."));
|
||||
//TODO: Handle this closure without an infinate loop...
|
||||
//Close the socket.//
|
||||
try {key.channel().close();} catch(Throwable e2) {}
|
||||
}//else if//
|
||||
else if(encryptResult.getStatus() == Status.OK) {
|
||||
//Write the bytes to the stream.//
|
||||
try {
|
||||
int remaining = encryptedWriteBuffer.remaining();
|
||||
|
||||
((SocketChannel) key.channel()).write(encryptedWriteBuffer);
|
||||
|
||||
//TODO: Handle this closure without an infinate loop...
|
||||
//Close the socket.//
|
||||
try {key.channel().close();} catch(Throwable e2) {}
|
||||
}//else if//
|
||||
else if(encryptResult.getStatus() == Status.OK) {
|
||||
//Write the bytes to the stream.//
|
||||
try {
|
||||
int remaining = encryptedWriteBuffer.remaining();
|
||||
|
||||
((SocketChannel) key.channel()).write(encryptedWriteBuffer);
|
||||
|
||||
// if(getWebServer().debug) {
|
||||
// debugBuffer.append("Sent " + (remaining - encryptedWriteBuffer.remaining()) + " encrypted bytes.\n");
|
||||
// }//if//
|
||||
}//try//
|
||||
catch(IOException e) {
|
||||
//Caught if the channel is forcably closed by the client. We will ignore it.//
|
||||
}//catch//
|
||||
}//try//
|
||||
catch(IOException e) {
|
||||
//Caught if the channel is forcably closed by the client. We will ignore it.//
|
||||
}//catch//
|
||||
|
||||
//If not all the bytes could be written then we will need to wait until we can write more.//
|
||||
if(encryptedWriteBuffer.hasRemaining()) {
|
||||
//Leave the data in the encrypted write buffer for the writing operation to send it.//
|
||||
sendMore = false;
|
||||
|
||||
//If not all the bytes could be written then we will need to wait until we can write more.//
|
||||
if(encryptedWriteBuffer.hasRemaining()) {
|
||||
//Leave the data in the encrypted write buffer for the writing operation to send it.//
|
||||
sendMore = false;
|
||||
|
||||
// if(getWebServer().debug) {
|
||||
// debugBuffer.append("Pausing due to a partially sent packet. Bytes actually sent: " + encryptedWriteBuffer.position() + ". Bytes remaining: " + encryptedWriteBuffer.remaining() + ".\n");
|
||||
// }//if//
|
||||
}//if//
|
||||
}//else if//
|
||||
else {
|
||||
//Should never happen.//
|
||||
Debug.log(new RuntimeException("Unexpected ssl engine status code."));
|
||||
}//else//
|
||||
|
||||
//Add more content to the buffer.//
|
||||
//Note: Do this even if the last encrypted write buffer could not be fully sent - so that when it is sent there will be outbound message content.//
|
||||
if(key.channel().isOpen() && currentOutboundMessage != null) {
|
||||
if(!currentOutboundMessage.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.//
|
||||
if(currentOutboundMessage.getBuffer() == null && currentOutboundMessage.getNext() != null) {
|
||||
currentOutboundMessage = currentOutboundMessage.getNext();
|
||||
}//if//
|
||||
else {
|
||||
//Wait until additional message bytes are available.//
|
||||
sendMore = false;
|
||||
}//else//
|
||||
}//if//
|
||||
|
||||
//If the message end has been reached then the buffer will be null.//
|
||||
if(currentOutboundMessage.getBuffer() == null) {
|
||||
currentOutboundMessage = null;
|
||||
lastOutboundMessage = null;
|
||||
}//if//
|
||||
}//if//
|
||||
}//while//
|
||||
}//if//
|
||||
else {
|
||||
//Keep sending encrypted frames until the output buffer is full, or we run out of message to send.//
|
||||
while(sendMore && (currentOutboundMessage != null) && currentOutboundMessage.getBuffer().hasRemaining()) {
|
||||
//Write the bytes to the stream.//
|
||||
((SocketChannel) key.channel()).write(currentOutboundMessage.getBuffer());
|
||||
|
||||
// if(getWebServer().debug) {
|
||||
// sentBytes += pendingOutboundMessage.position();
|
||||
// debugBuffer.append("Wrote " + pendingOutboundMessage.position() + " bytes to the client. Total sent: " + sentBytes + "\n");
|
||||
// }//if//
|
||||
|
||||
//If not all the bytes could be written then we will need to wait until we can write more.//
|
||||
if(currentOutboundMessage.getBuffer().hasRemaining()) {
|
||||
sendMore = false;
|
||||
}//else if//
|
||||
else {
|
||||
//Should never happen.//
|
||||
Debug.log(new RuntimeException("Unexpected ssl engine status code."));
|
||||
}//else//
|
||||
|
||||
//Add more content to the buffer.//
|
||||
//Note: Do this even if the last encrypted write buffer could not be fully sent - so that when it is sent there will be outbound message content.//
|
||||
if(key.channel().isOpen() && currentOutboundMessage != null) {
|
||||
if(!currentOutboundMessage.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.//
|
||||
if(currentOutboundMessage.getBuffer() == null && currentOutboundMessage.getNext() != null) {
|
||||
currentOutboundMessage = currentOutboundMessage.getNext();
|
||||
}//if//
|
||||
else {
|
||||
//Wait until additional message bytes are available.//
|
||||
sendMore = false;
|
||||
}//else//
|
||||
}//if//
|
||||
else {
|
||||
if(!currentOutboundMessage.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.//
|
||||
if(currentOutboundMessage.getBuffer() == null && currentOutboundMessage.getNext() != null) {
|
||||
currentOutboundMessage = currentOutboundMessage.getNext();
|
||||
}//if//
|
||||
else {
|
||||
//Wait until additional message bytes are available.//
|
||||
sendMore = false;
|
||||
}//else//
|
||||
}//if//
|
||||
|
||||
//If the message end has been reached then the buffer will be null.//
|
||||
if(currentOutboundMessage.getBuffer() == null) {
|
||||
currentOutboundMessage = null;
|
||||
lastOutboundMessage = null;
|
||||
}//if//
|
||||
}//else//
|
||||
}//while//
|
||||
}//else//
|
||||
|
||||
//If the message end has been reached then the buffer will be null.//
|
||||
if(currentOutboundMessage.getBuffer() == null) {
|
||||
currentOutboundMessage = null;
|
||||
lastOutboundMessage = null;
|
||||
}//if//
|
||||
}//if//
|
||||
}//while//
|
||||
}//if//
|
||||
}//if//
|
||||
}//try//
|
||||
@@ -1028,7 +975,86 @@ private boolean writeClientBoundMessage() {
|
||||
}//catch//
|
||||
|
||||
return sendMore;
|
||||
}//writeClientBoundMessage()//
|
||||
}//writeClientBoundSslMessage()//
|
||||
/**
|
||||
* Sends a response to the client.
|
||||
* @return Whether the response could be fully sent. This will be false if there is still more data to be written when the call returns.
|
||||
*/
|
||||
private boolean writeClientBoundPlainMessage() {
|
||||
boolean sendMore = true;
|
||||
|
||||
try {
|
||||
if(sendMore && currentOutboundMessage != 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.//
|
||||
if(!currentOutboundMessage.getBuffer().hasRemaining()) {
|
||||
if(!currentOutboundMessage.loadBuffer()) {
|
||||
if(currentOutboundMessage.getBuffer() == null && currentOutboundMessage.getNext() != null) {
|
||||
currentOutboundMessage = currentOutboundMessage.getNext();
|
||||
}//if//
|
||||
else {
|
||||
sendMore = false;
|
||||
}//else//
|
||||
}//if//
|
||||
|
||||
if(currentOutboundMessage.getBuffer() == null) {
|
||||
currentOutboundMessage = null;
|
||||
lastOutboundMessage = null;
|
||||
}//if//
|
||||
}//if//
|
||||
|
||||
//If we have an application response pending then send it now.//
|
||||
if(sendMore && currentOutboundMessage.getBuffer().hasRemaining()) {
|
||||
//Keep sending encrypted frames until the output buffer is full, or we run out of message to send.//
|
||||
while(sendMore && (currentOutboundMessage != null) && currentOutboundMessage.getBuffer().hasRemaining()) {
|
||||
//Write the bytes to the stream.//
|
||||
((SocketChannel) key.channel()).write(currentOutboundMessage.getBuffer());
|
||||
|
||||
//If not all the bytes could be written then we will need to wait until we can write more.//
|
||||
if(currentOutboundMessage.getBuffer().hasRemaining()) {
|
||||
sendMore = false;
|
||||
}//if//
|
||||
else {
|
||||
if(!currentOutboundMessage.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.//
|
||||
if(currentOutboundMessage.getBuffer() == null && currentOutboundMessage.getNext() != null) {
|
||||
currentOutboundMessage = currentOutboundMessage.getNext();
|
||||
}//if//
|
||||
else {
|
||||
//Wait until additional message bytes are available.//
|
||||
sendMore = false;
|
||||
}//else//
|
||||
}//if//
|
||||
|
||||
//If the message end has been reached then the buffer will be null.//
|
||||
if(currentOutboundMessage.getBuffer() == null) {
|
||||
currentOutboundMessage = null;
|
||||
lastOutboundMessage = null;
|
||||
}//if//
|
||||
}//else//
|
||||
}//while//
|
||||
}//if//
|
||||
}//if//
|
||||
}//try//
|
||||
catch(ClosedChannelException e) {
|
||||
close();
|
||||
}//catch//
|
||||
catch(SSLException e) {
|
||||
if(getWebServer().debug) {
|
||||
Debug.log(e);
|
||||
}//if//
|
||||
|
||||
close();
|
||||
}//catch//
|
||||
catch(IOException e) {
|
||||
if(getWebServer().debug) {
|
||||
Debug.log(e);
|
||||
}//if//
|
||||
|
||||
close();
|
||||
}//catch//
|
||||
|
||||
return sendMore;
|
||||
}//writeClientBoundPlainMessage()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.web.server.WebServer.AbstractSocketContext#processRequest()
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user