Changed key.channel().close() into just calling close on the SocketContext throughout the code. Comment changes and debugging additions and changes.
This commit is contained in:
@@ -205,6 +205,9 @@ private boolean writeClientBoundMessage(SocketChannel channel, MessageBuffer cur
|
|||||||
* @see com.foundation.web.server.WebServer.AbstractSocketContext#passThrough(java.nio.ByteBuffer)
|
* @see com.foundation.web.server.WebServer.AbstractSocketContext#passThrough(java.nio.ByteBuffer)
|
||||||
*/
|
*/
|
||||||
protected void passThrough(ByteBuffer buffer) {
|
protected void passThrough(ByteBuffer buffer) {
|
||||||
|
if(buffer != null) {
|
||||||
|
boolean notify = false;
|
||||||
|
|
||||||
synchronized(getLock()) {
|
synchronized(getLock()) {
|
||||||
ByteBuffer messageBytes = ByteBuffer.allocate(buffer.remaining());
|
ByteBuffer messageBytes = ByteBuffer.allocate(buffer.remaining());
|
||||||
MessageBuffer message;
|
MessageBuffer message;
|
||||||
@@ -217,12 +220,18 @@ protected void passThrough(ByteBuffer buffer) {
|
|||||||
//Chain the message into the linked list.
|
//Chain the message into the linked list.
|
||||||
if(lastOutboundMessage == null) {
|
if(lastOutboundMessage == null) {
|
||||||
currentOutboundMessage = lastOutboundMessage = message;
|
currentOutboundMessage = lastOutboundMessage = message;
|
||||||
|
notify = true;
|
||||||
}//if//
|
}//if//
|
||||||
else {
|
else {
|
||||||
lastOutboundMessage.setNext(message);
|
lastOutboundMessage.setNext(message);
|
||||||
lastOutboundMessage = message;
|
lastOutboundMessage = message;
|
||||||
}//else//
|
}//else//
|
||||||
}//synchronized//
|
}//synchronized//
|
||||||
|
|
||||||
|
if(notify) {
|
||||||
|
notifyListenerOfPendingWrite();
|
||||||
|
}//if//
|
||||||
|
}//if//
|
||||||
}//passThrough()//
|
}//passThrough()//
|
||||||
protected synchronized void close() {
|
protected synchronized void close() {
|
||||||
synchronized(getLock()) {
|
synchronized(getLock()) {
|
||||||
|
|||||||
@@ -274,12 +274,10 @@ private void queueOutboundClientMessage(MessageBuffer messageBuffer) {
|
|||||||
}//queueOutboundClientMessage()//
|
}//queueOutboundClientMessage()//
|
||||||
/**
|
/**
|
||||||
* Adds a HTTP response to the socket context.
|
* Adds a HTTP response to the socket context.
|
||||||
* <p>Note: We must synchronize since a socket could be used to access multiple applications and thus mutliple sessions.</p>
|
* <p>Note that this just queues a response. The actual sending is initiated by the web server's NetworkListener when the socket is flagged as being ready to write.</p>
|
||||||
* @param response The response to be added.
|
* @param response The response to be added.
|
||||||
* @result Whether request is in a receive state. Will be false if the request generated a response that could not be completely transmitted.
|
|
||||||
*/
|
*/
|
||||||
public void sendHttpResponse(Response response) {
|
public void sendHttpResponse(Response response) {
|
||||||
//prepareResponse(response);
|
|
||||||
queueOutboundClientMessage(new HttpMessageBuffer(this, response));
|
queueOutboundClientMessage(new HttpMessageBuffer(this, response));
|
||||||
request = null;
|
request = null;
|
||||||
}//sendHttpResponse()//
|
}//sendHttpResponse()//
|
||||||
@@ -298,7 +296,7 @@ protected void passThrough(ByteBuffer buffer) {
|
|||||||
queueOutboundClientMessage(message);
|
queueOutboundClientMessage(message);
|
||||||
}//passThrough()//
|
}//passThrough()//
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see com.foundation.web.server.WebServer.AbstractSocketContext#processResponses()
|
* @see com.foundation.web.server.WebServer.AbstractSocketContext#writeOutgoingMessages()
|
||||||
*/
|
*/
|
||||||
protected void writeOutgoingMessages() throws IOException {
|
protected void writeOutgoingMessages() throws IOException {
|
||||||
boolean keepSending;
|
boolean keepSending;
|
||||||
@@ -364,8 +362,10 @@ protected void writeOutgoingMessages() throws IOException {
|
|||||||
}//if//
|
}//if//
|
||||||
}//writeOutgoingMessages()//
|
}//writeOutgoingMessages()//
|
||||||
/**
|
/**
|
||||||
* Sends a response to the client.
|
* Sends a message/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.
|
* @param channel The channel to use for the sending.
|
||||||
|
* @param currentOutboundMessage The message to be sending. This may be null if using SSL and sending handshake data (in which case the encryptedWriteBuffer should have data on it).
|
||||||
|
* @return Whether the response could be fully sent. This will be false if there is still more data to be written for the current message OR in the encrypted SSL write buffer (for SSL handshake messages) when the call returns.
|
||||||
*/
|
*/
|
||||||
private boolean writeClientBoundMessage(SocketChannel channel, MessageBuffer currentOutboundMessage) {
|
private boolean writeClientBoundMessage(SocketChannel channel, MessageBuffer currentOutboundMessage) {
|
||||||
boolean sendMore = true;
|
boolean sendMore = true;
|
||||||
@@ -380,8 +380,10 @@ private boolean writeClientBoundMessage(SocketChannel channel, MessageBuffer cur
|
|||||||
return sendMore;
|
return sendMore;
|
||||||
}//writeClientBoundMessage()//
|
}//writeClientBoundMessage()//
|
||||||
/**
|
/**
|
||||||
* Sends a response to the client.
|
* Sends a SSL message/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.
|
* @param channel The channel to use for the sending.
|
||||||
|
* @param currentOutboundMessage The message to be sending. This may be null if using SSL and sending handshake data (in which case the encryptedWriteBuffer should have data on it).
|
||||||
|
* @return Whether the response could be fully sent. This will be false if there is still more data to be written for the current message OR in the encrypted SSL write buffer (for SSL handshake messages) when the call returns.
|
||||||
*/
|
*/
|
||||||
private boolean writeClientBoundSslMessage(SocketChannel channel, MessageBuffer currentOutboundMessage) {
|
private boolean writeClientBoundSslMessage(SocketChannel channel, MessageBuffer currentOutboundMessage) {
|
||||||
boolean sendMore = true;
|
boolean sendMore = true;
|
||||||
@@ -408,6 +410,7 @@ private boolean writeClientBoundSslMessage(SocketChannel channel, MessageBuffer
|
|||||||
}//if//
|
}//if//
|
||||||
}//if//
|
}//if//
|
||||||
|
|
||||||
|
//Perform handshaking.//
|
||||||
while(sendMore && sslNeedsWrap) {
|
while(sendMore && sslNeedsWrap) {
|
||||||
SSLEngineResult handshakeResult;
|
SSLEngineResult handshakeResult;
|
||||||
|
|
||||||
@@ -435,7 +438,7 @@ private boolean writeClientBoundSslMessage(SocketChannel channel, MessageBuffer
|
|||||||
Debug.log(new RuntimeException("Unexpected ssl engine closed."));
|
Debug.log(new RuntimeException("Unexpected ssl engine closed."));
|
||||||
//TODO: Handle this closure without an infinate loop...
|
//TODO: Handle this closure without an infinate loop...
|
||||||
//Close the socket.//
|
//Close the socket.//
|
||||||
try {key.channel().close();}catch(Throwable e2) {}
|
close();
|
||||||
}//else if//
|
}//else if//
|
||||||
else if(handshakeResult.getStatus() == Status.OK) {
|
else if(handshakeResult.getStatus() == Status.OK) {
|
||||||
if(handshakeResult.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
|
if(handshakeResult.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
|
||||||
@@ -467,6 +470,7 @@ private boolean writeClientBoundSslMessage(SocketChannel channel, MessageBuffer
|
|||||||
}//else//
|
}//else//
|
||||||
}//while//
|
}//while//
|
||||||
|
|
||||||
|
//If we can send more data and we have an outbound message then initialize and send it! The currentOutboundMessage might be null if performing an SSL handshake.//
|
||||||
if(sendMore && currentOutboundMessage != null && !currentOutboundMessage.isClosed()) {
|
if(sendMore && currentOutboundMessage != null && !currentOutboundMessage.isClosed()) {
|
||||||
//Initialize the outbound message.//
|
//Initialize the outbound message.//
|
||||||
if(!currentOutboundMessage.initialize()) {
|
if(!currentOutboundMessage.initialize()) {
|
||||||
@@ -517,7 +521,7 @@ private boolean writeClientBoundSslMessage(SocketChannel channel, MessageBuffer
|
|||||||
// Debug.log(new RuntimeException("Unexpected ssl engine closed."));
|
// Debug.log(new RuntimeException("Unexpected ssl engine closed."));
|
||||||
//TODO: Handle this closure without an infinate loop...
|
//TODO: Handle this closure without an infinate loop...
|
||||||
//Close the socket.//
|
//Close the socket.//
|
||||||
try {channel.close();} catch(Throwable e2) {}
|
close();
|
||||||
}//else if//
|
}//else if//
|
||||||
else if(encryptResult.getStatus() == Status.OK) {
|
else if(encryptResult.getStatus() == Status.OK) {
|
||||||
//Write the bytes to the stream.//
|
//Write the bytes to the stream.//
|
||||||
@@ -589,13 +593,16 @@ private boolean writeClientBoundSslMessage(SocketChannel channel, MessageBuffer
|
|||||||
return sendMore;
|
return sendMore;
|
||||||
}//writeClientBoundSslMessage()//
|
}//writeClientBoundSslMessage()//
|
||||||
/**
|
/**
|
||||||
* Sends a response to the client.
|
* Sends a plain (non-ssl) message/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.
|
* @param channel The channel to use for the sending.
|
||||||
|
* @param currentOutboundMessage The message to be sending. This may be null if using SSL and sending handshake data (in which case the encryptedWriteBuffer should have data on it).
|
||||||
|
* @return Whether the response could be fully sent. This will be false if there is still more data to be written for the current message OR in the encrypted SSL write buffer (for SSL handshake messages) when the call returns.
|
||||||
*/
|
*/
|
||||||
private boolean writeClientBoundPlainMessage(SocketChannel channel, MessageBuffer currentOutboundMessage) {
|
private boolean writeClientBoundPlainMessage(SocketChannel channel, MessageBuffer currentOutboundMessage) {
|
||||||
boolean sendMore = true;
|
boolean sendMore = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
//If we can send more data and we have an outbound message then initialize and send it! The currentOutboundMessage might be null if performing an SSL handshake.//
|
||||||
if(sendMore && currentOutboundMessage != null && !currentOutboundMessage.isClosed()) {
|
if(sendMore && currentOutboundMessage != null && !currentOutboundMessage.isClosed()) {
|
||||||
//Initialize the outbound message.//
|
//Initialize the outbound message.//
|
||||||
if(!currentOutboundMessage.initialize()) {
|
if(!currentOutboundMessage.initialize()) {
|
||||||
@@ -647,7 +654,7 @@ private boolean writeClientBoundPlainMessage(SocketChannel channel, MessageBuffe
|
|||||||
return sendMore;
|
return sendMore;
|
||||||
}//writeClientBoundPlainMessage()//
|
}//writeClientBoundPlainMessage()//
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see com.foundation.web.server.WebServer.AbstractSocketContext#processRequest()
|
* @see com.foundation.web.server.WebServer.AbstractSocketContext#readIncomingMessages()
|
||||||
*/
|
*/
|
||||||
protected void readIncomingMessages() throws IOException {
|
protected void readIncomingMessages() throws IOException {
|
||||||
boolean requiresRead = true;
|
boolean requiresRead = true;
|
||||||
@@ -889,7 +896,6 @@ protected void readIncomingMessages() throws IOException {
|
|||||||
IPassThroughDomain passThroughDomain = ((IPassThroughDomain) application);
|
IPassThroughDomain passThroughDomain = ((IPassThroughDomain) application);
|
||||||
|
|
||||||
//Setup the pass through socket context (and socket channel). All data will be sent to this context to be sent to the remote process.//
|
//Setup the pass through socket context (and socket channel). All data will be sent to this context to be sent to the remote process.//
|
||||||
//relatedSocketContext = new PassThroughSocketContext(getWebServer(), getNetworkListener(), this, passThroughDomain.getAddress(), passThroughDomain.getPort());
|
|
||||||
relatedSocketContext = new PassThroughSocketContext(this, passThroughDomain.getAddress(), passThroughDomain.getPort());
|
relatedSocketContext = new PassThroughSocketContext(this, passThroughDomain.getAddress(), passThroughDomain.getPort());
|
||||||
}//if//
|
}//if//
|
||||||
|
|
||||||
@@ -1244,8 +1250,7 @@ private boolean processRequestedHost(ByteBuffer fragment) throws IOException {
|
|||||||
//Keep adding ASCII characters to the message header fragment until the next line is read or we exceed the maximum length of the header.//
|
//Keep adding ASCII characters to the message header fragment until the next line is read or we exceed the maximum length of the header.//
|
||||||
while(fragment.hasRemaining() && (!(buffer.length() > 1 && (buffer.charAt(buffer.length() - 2) == '\r') && (buffer.charAt(buffer.length() - 1) == '\n')))) {
|
while(fragment.hasRemaining() && (!(buffer.length() > 1 && (buffer.charAt(buffer.length() - 2) == '\r') && (buffer.charAt(buffer.length() - 1) == '\n')))) {
|
||||||
if(totalHeaderSize == 4096) {
|
if(totalHeaderSize == 4096) {
|
||||||
//Force the connection to the client to be closed.//
|
close();
|
||||||
try {key.channel().close();}catch(Throwable e2) {}
|
|
||||||
//Throw an exception that should not be logged. This happens occationally when an attacker tries to exploit any buffer overrun weaknesses.//
|
//Throw an exception that should not be logged. This happens occationally when an attacker tries to exploit any buffer overrun weaknesses.//
|
||||||
throw new IgnoredIOException(null);
|
throw new IgnoredIOException(null);
|
||||||
}//if//
|
}//if//
|
||||||
@@ -1264,7 +1269,7 @@ private boolean processRequestedHost(ByteBuffer fragment) throws IOException {
|
|||||||
if(buffer.length() == 2) {
|
if(buffer.length() == 2) {
|
||||||
//End of the header reached. No host provided. Kill the connection?//
|
//End of the header reached. No host provided. Kill the connection?//
|
||||||
//Force the connection to the client to be closed.//
|
//Force the connection to the client to be closed.//
|
||||||
try {key.channel().close();}catch(Throwable e2) {}
|
close();
|
||||||
//Throw an exception that should not be logged. This happens occationally when an attacker tries to exploit any header reading weaknesses (all major browsers send a host header).//
|
//Throw an exception that should not be logged. This happens occationally when an attacker tries to exploit any header reading weaknesses (all major browsers send a host header).//
|
||||||
throw new IgnoredIOException(null);
|
throw new IgnoredIOException(null);
|
||||||
}//if//
|
}//if//
|
||||||
@@ -1510,7 +1515,7 @@ private boolean parseFirstTlsMessage(SocketChannel channel) throws IOException {
|
|||||||
/**
|
/**
|
||||||
* Processes the client request given the latest fragment of a message.
|
* Processes the client request given the latest fragment of a message.
|
||||||
* @param messageFragment The message fragment.
|
* @param messageFragment The message fragment.
|
||||||
* @result Whether request is in a receive state. Will be false if the request generated a response that could not be completely transmitted.
|
* @return Whether the request could NOT be built from the given fragment, and thus more data must be read from the socket before the request can be handled.
|
||||||
*/
|
*/
|
||||||
private boolean processClientRequest(ByteBuffer fragment) throws IOException {
|
private boolean processClientRequest(ByteBuffer fragment) throws IOException {
|
||||||
boolean result = true;
|
boolean result = true;
|
||||||
@@ -1537,7 +1542,7 @@ private boolean processClientRequest(ByteBuffer fragment) throws IOException {
|
|||||||
while(fragment.hasRemaining() && !isCompleteHeader(messageHeaderFragment)) {
|
while(fragment.hasRemaining() && !isCompleteHeader(messageHeaderFragment)) {
|
||||||
if(messageHeaderFragment.length() == 4096) {
|
if(messageHeaderFragment.length() == 4096) {
|
||||||
//Force the connection to the client to be closed.//
|
//Force the connection to the client to be closed.//
|
||||||
try {key.channel().close();}catch(Throwable e2) {}
|
close();
|
||||||
//Throw an exception that should not be logged. This happens occationally when an attacker tries to exploit any buffer overrun weaknesses.//
|
//Throw an exception that should not be logged. This happens occationally when an attacker tries to exploit any buffer overrun weaknesses.//
|
||||||
throw new IgnoredIOException(null);
|
throw new IgnoredIOException(null);
|
||||||
}//if//
|
}//if//
|
||||||
@@ -1555,11 +1560,11 @@ private boolean processClientRequest(ByteBuffer fragment) throws IOException {
|
|||||||
|
|
||||||
//Prepare the request.//
|
//Prepare the request.//
|
||||||
try {
|
try {
|
||||||
request = new Request(++lastRequestNumber, messageHeaderFragment.toString(), ((SocketChannel) key.channel()).socket().getInetAddress().getHostAddress(), this, this, isSsl());
|
request = new Request(getNextRequestNumber(), messageHeaderFragment.toString(), ((SocketChannel) getKey().channel()).socket().getInetAddress().getHostAddress(), this, this, isSsl());
|
||||||
|
|
||||||
//Log the request header if running in getWebServer().debug() mode.//
|
//Log the request header if running in debug mode.//
|
||||||
if(getWebServer().debug()) {
|
if(getWebServer().debug()) {
|
||||||
Debug.log(request.toString());
|
Debug.log(getId() + "|" + System.nanoTime() + "|Request created (header only loaded): " + request.getHeaderRequest());
|
||||||
}//if//
|
}//if//
|
||||||
}//try//
|
}//try//
|
||||||
catch(IOException e) {
|
catch(IOException e) {
|
||||||
@@ -1600,12 +1605,8 @@ private boolean processClientRequest(ByteBuffer fragment) throws IOException {
|
|||||||
if(application != null) {
|
if(application != null) {
|
||||||
int contentLength = 0;
|
int contentLength = 0;
|
||||||
|
|
||||||
//TODO: Remove
|
|
||||||
if(getWebServer().debug()) {
|
if(getWebServer().debug()) {
|
||||||
boolean sessionFound = application.getSession(request.getSessionId()) != null;
|
Debug.log(getId() + "|" + System.nanoTime() + "|Application identified for request: " + request.getHeaderRequest());
|
||||||
boolean canRecreate = request.getSessionId() != null;
|
|
||||||
|
|
||||||
Debug.log("SC: " + getId() + "; Req#: " + request.getRequestNumber() + "; ReqURI: " + request.getUri() + "\n\t(SessionId: " + request.getSessionId() + "; SecureSessionId: " + request.getSecureSessionId() + ")\n\tSession Found: " + sessionFound + (!sessionFound ? "; Can Recreate: " + canRecreate : ""));
|
|
||||||
}//if//
|
}//if//
|
||||||
|
|
||||||
request.setSession(application.getSession(request.getSessionId()));
|
request.setSession(application.getSession(request.getSessionId()));
|
||||||
@@ -1627,9 +1628,12 @@ private boolean processClientRequest(ByteBuffer fragment) throws IOException {
|
|||||||
//This is a security mechanism because the client is SUPPOSED to keep the secure session ID very private and not allow access to it by other sites. It ensures that a recreated session actually comes from a client that had it created in the first place.//
|
//This is a security mechanism because the client is SUPPOSED to keep the secure session ID very private and not allow access to it by other sites. It ensures that a recreated session actually comes from a client that had it created in the first place.//
|
||||||
if(request.getSecureSessionId() != null && request.getSession() != null && request.getSession().getSecureSessionId() != null) {
|
if(request.getSecureSessionId() != null && request.getSession() != null && request.getSession().getSecureSessionId() != null) {
|
||||||
if(!Comparator.equals(request.getSecureSessionId(), request.getSession().getSecureSessionId())) {
|
if(!Comparator.equals(request.getSecureSessionId(), request.getSession().getSecureSessionId())) {
|
||||||
Debug.log("SC: " + getId() + "Forcing connection closure.");
|
if(getWebServer().debug()) {
|
||||||
|
Debug.log(getId() + "|" + System.nanoTime() + "|Forcing connection closure (invalid secure session id).");
|
||||||
|
}//if//
|
||||||
|
|
||||||
//Force the connection to the client to be closed.//
|
//Force the connection to the client to be closed.//
|
||||||
try {key.channel().close();}catch(Throwable e2) {}
|
close();
|
||||||
//Throw an exception that should not be logged. This might happen when an attacker tries to reuse stored session data on a client.//
|
//Throw an exception that should not be logged. This might happen when an attacker tries to reuse stored session data on a client.//
|
||||||
throw new IgnoredIOException(null);
|
throw new IgnoredIOException(null);
|
||||||
}//if//
|
}//if//
|
||||||
@@ -1678,6 +1682,10 @@ private boolean processClientRequest(ByteBuffer fragment) throws IOException {
|
|||||||
|
|
||||||
//If this is a multipart or custom message then we should do as much verification of size validity as possible.//
|
//If this is a multipart or custom message then we should do as much verification of size validity as possible.//
|
||||||
if(request.getContentTypeCode() == IRequest.CONTENT_TYPE_MULTI_PART_FORM_DATA) {
|
if(request.getContentTypeCode() == IRequest.CONTENT_TYPE_MULTI_PART_FORM_DATA) {
|
||||||
|
if(getWebServer().debug()) {
|
||||||
|
Debug.log(getId() + "|" + System.nanoTime() + "|Incoming request is Multipart Form Data: " + request.getHeaderRequest());
|
||||||
|
}//if//
|
||||||
|
|
||||||
//Ensure that the multi-part form data message begins with the \r\n from the end of the header, allowing for the boundary recognition to proceed.//
|
//Ensure that the multi-part form data message begins with the \r\n from the end of the header, allowing for the boundary recognition to proceed.//
|
||||||
//This could be a problem if the fragment doesn't have the last two characters (it might have only the last 1).//
|
//This could be a problem if the fragment doesn't have the last two characters (it might have only the last 1).//
|
||||||
if(fragment.position() == 1) {
|
if(fragment.position() == 1) {
|
||||||
@@ -1719,7 +1727,7 @@ private boolean processClientRequest(ByteBuffer fragment) throws IOException {
|
|||||||
request.getRequestBytes().put(bytes);
|
request.getRequestBytes().put(bytes);
|
||||||
}//else//
|
}//else//
|
||||||
|
|
||||||
// Debug.log("Read " + (remaining - context.request.getRequestBytes().remaining()) + " bytes of the current client request.");
|
// Debug.log("Read " + (remaining - request.getRequestBytes().remaining()) + " bytes of the current client request.");
|
||||||
|
|
||||||
//Reset the fragment back to its previous position.//
|
//Reset the fragment back to its previous position.//
|
||||||
fragment.position(position);
|
fragment.position(position);
|
||||||
@@ -1773,7 +1781,7 @@ private boolean processClientRequest(ByteBuffer fragment) throws IOException {
|
|||||||
//TODO: What do we do if there are no parts in a multi-part message? Here we found the end part while NOT reading a message - shouldn't ever happen.
|
//TODO: What do we do if there are no parts in a multi-part message? Here we found the end part while NOT reading a message - shouldn't ever happen.
|
||||||
|
|
||||||
//Force the connection to the client to be closed.//
|
//Force the connection to the client to be closed.//
|
||||||
try {key.channel().close();}catch(Throwable e2) {}
|
close();
|
||||||
//Throw an exception that should not be logged. This is a malformed message.//
|
//Throw an exception that should not be logged. This is a malformed message.//
|
||||||
throw new IgnoredIOException(null);
|
throw new IgnoredIOException(null);
|
||||||
}//if//
|
}//if//
|
||||||
@@ -2010,20 +2018,6 @@ private boolean processClientRequest(final Request request, SelectionKey key) th
|
|||||||
try {
|
try {
|
||||||
boolean applicationNotFound = false;
|
boolean applicationNotFound = false;
|
||||||
|
|
||||||
//Moved this bit of code into the calling method near the top. Access to the application was required that far up in the sequence of events.//
|
|
||||||
// if(context.webApplicationContainer == null) {
|
|
||||||
// //Save the domain.//
|
|
||||||
// context.domain = request.getHost() != null ? request.getHost().toLowerCase() : null;
|
|
||||||
//
|
|
||||||
// if(context.domain != null) {
|
|
||||||
// //Get the web application for the given domain.//
|
|
||||||
// //Synchronize to prevent another thread from altering the service's web applications while we are accessing it.//
|
|
||||||
// synchronized(WebServer.this) {
|
|
||||||
// context.webApplicationContainer = context.serverSocketContext.serviceListener.getWebApplicationContainer(context.domain);
|
|
||||||
// }//synchronized//
|
|
||||||
// }//if//
|
|
||||||
// }//if//
|
|
||||||
|
|
||||||
//Verify an application was found for the context.//
|
//Verify an application was found for the context.//
|
||||||
if(webApplicationContainer != null) {
|
if(webApplicationContainer != null) {
|
||||||
//Increment the activity counter until we finish processing this request.//
|
//Increment the activity counter until we finish processing this request.//
|
||||||
@@ -2039,9 +2033,8 @@ private boolean processClientRequest(final Request request, SelectionKey key) th
|
|||||||
boolean hasNewSessionData = false;
|
boolean hasNewSessionData = false;
|
||||||
|
|
||||||
if(session == null) {
|
if(session == null) {
|
||||||
//TODO: Remove
|
|
||||||
if(getWebServer().debug()) {
|
if(getWebServer().debug()) {
|
||||||
Debug.log("SC: " + getId() + " Creating Session");
|
Debug.log(getId() + "|" + System.nanoTime() + "|Creating Session");
|
||||||
}//if//
|
}//if//
|
||||||
|
|
||||||
request.setSession(session = application.createSession());
|
request.setSession(session = application.createSession());
|
||||||
@@ -2062,13 +2055,12 @@ private boolean processClientRequest(final Request request, SelectionKey key) th
|
|||||||
allowSecureAccess = true;
|
allowSecureAccess = true;
|
||||||
}//if//
|
}//if//
|
||||||
else {
|
else {
|
||||||
Debug.log(new RuntimeException("Error: The client did not send the correct secure session getId() with the request!"));
|
Debug.log(new RuntimeException("Error: The client did not send the correct secure session id with the request!"));
|
||||||
}//else//
|
}//else//
|
||||||
}//if//
|
}//if//
|
||||||
else if(session != null && session.getSecureSessionId() == null) {
|
else if(session != null && session.getSecureSessionId() == null) {
|
||||||
//TODO: Remove
|
|
||||||
if(getWebServer().debug()) {
|
if(getWebServer().debug()) {
|
||||||
Debug.log("SC: " + getId() + " Creating Secure Session");
|
Debug.log(getId() + "|" + System.nanoTime() + "|Creating Secure Session");
|
||||||
}//if//
|
}//if//
|
||||||
|
|
||||||
application.createSecureSession(session);
|
application.createSecureSession(session);
|
||||||
@@ -2121,7 +2113,7 @@ private boolean processClientRequest(final Request request, SelectionKey key) th
|
|||||||
if(content == null) {
|
if(content == null) {
|
||||||
//For now we will simply close the connection to the client - this should never happen anyhow and if it does, it could be an attack.//
|
//For now we will simply close the connection to the client - this should never happen anyhow and if it does, it could be an attack.//
|
||||||
Debug.log(new RuntimeException("Application not found for the host: " + request.getHost()));
|
Debug.log(new RuntimeException("Application not found for the host: " + request.getHost()));
|
||||||
key.channel().close();
|
close();
|
||||||
}//if//
|
}//if//
|
||||||
else {
|
else {
|
||||||
response = new Response(request, null, null);
|
response = new Response(request, null, null);
|
||||||
@@ -2138,7 +2130,7 @@ private boolean processClientRequest(final Request request, SelectionKey key) th
|
|||||||
//response.setResourceNotFound(true);
|
//response.setResourceNotFound(true);
|
||||||
//For now simply close the connection. This simplifies threading.//
|
//For now simply close the connection. This simplifies threading.//
|
||||||
//Close the socket.//
|
//Close the socket.//
|
||||||
try {key.channel().close();}catch(Throwable e2) {}
|
close();
|
||||||
//Close the response (which also closes the request).//
|
//Close the response (which also closes the request).//
|
||||||
try {response.close();} catch(Throwable e2) {}
|
try {response.close();} catch(Throwable e2) {}
|
||||||
}//catch//
|
}//catch//
|
||||||
@@ -2147,6 +2139,7 @@ private boolean processClientRequest(final Request request, SelectionKey key) th
|
|||||||
}//processClientRequest()//
|
}//processClientRequest()//
|
||||||
/**
|
/**
|
||||||
* Processes a client request.
|
* Processes a client request.
|
||||||
|
* @param application The web application the request is associated with.
|
||||||
* @param request The request.
|
* @param request The request.
|
||||||
* @param response The response container.
|
* @param response The response container.
|
||||||
* @param session The session for the request. This may be null in the case of non-standard web applications such as a forwarding domain.
|
* @param session The session for the request. This may be null in the case of non-standard web applications such as a forwarding domain.
|
||||||
@@ -2163,6 +2156,10 @@ private boolean internalProcessClientRequest(SelectionKey key, final IWebApplica
|
|||||||
}//if//
|
}//if//
|
||||||
//Send the request to the application to be processed if we are not dealing with an error.//
|
//Send the request to the application to be processed if we are not dealing with an error.//
|
||||||
else if(application != null) {
|
else if(application != null) {
|
||||||
|
if(getWebServer().debug()) {
|
||||||
|
Debug.log(getId() + "|" + System.nanoTime() + "|Received request: " + request.getHeaderRequest());
|
||||||
|
}//if//
|
||||||
|
|
||||||
String upgrade = request.getHeaderFieldValue("Upgrade");
|
String upgrade = request.getHeaderFieldValue("Upgrade");
|
||||||
|
|
||||||
if(upgrade != null && "websocket".equalsIgnoreCase(upgrade)) {
|
if(upgrade != null && "websocket".equalsIgnoreCase(upgrade)) {
|
||||||
@@ -2175,18 +2172,26 @@ private boolean internalProcessClientRequest(SelectionKey key, final IWebApplica
|
|||||||
application.handleWebSocketUpgrade(request, response, session, allowSecureAccess, clientHadBadSession, this, connection, secWebSocketKey, secWebSocketProtocol, secWebSocketVersion, origin);
|
application.handleWebSocketUpgrade(request, response, session, allowSecureAccess, clientHadBadSession, this, connection, secWebSocketKey, secWebSocketProtocol, secWebSocketVersion, origin);
|
||||||
}//if//
|
}//if//
|
||||||
else {
|
else {
|
||||||
|
if(getWebServer().debug()) {
|
||||||
|
Debug.log(getId() + "|" + System.nanoTime() + "|Passing request to application: " + request.getHeaderRequest());
|
||||||
|
}//if//
|
||||||
|
|
||||||
application.processRequest(request, response, session, allowSecureAccess, clientHadBadSession, this);
|
application.processRequest(request, response, session, allowSecureAccess, clientHadBadSession, this);
|
||||||
}//else//
|
}//else//
|
||||||
}//else if//
|
}//else if//
|
||||||
|
|
||||||
//Convert the response into a byte stream and send it via the socket.//
|
if(getWebServer().debug()) {
|
||||||
|
Debug.log(getId() + "|" + System.nanoTime() + "|Beginning response: " + request.getHeaderRequest());
|
||||||
|
}//if//
|
||||||
|
|
||||||
|
//Convert the response into a byte stream and send it via the socket (the actual sending occurs later on another thread so this is non-blocking).//
|
||||||
sendHttpResponse(response);
|
sendHttpResponse(response);
|
||||||
result = true;
|
result = true;
|
||||||
}//try//
|
}//try//
|
||||||
catch(Throwable e) {
|
catch(Throwable e) {
|
||||||
Debug.log(e);
|
Debug.log(e);
|
||||||
//Close the socket.//
|
//Close the socket.//
|
||||||
try {key.channel().close();} catch(Throwable e2) {}
|
close();
|
||||||
//Close the response (which also closes the request).//
|
//Close the response (which also closes the request).//
|
||||||
try {response.close();} catch(Throwable e2) {}
|
try {response.close();} catch(Throwable e2) {}
|
||||||
}//catch//
|
}//catch//
|
||||||
|
|||||||
Reference in New Issue
Block a user