From 0c3b7d026be3f5b78de5505e8dfcefa6c7d7d5b0 Mon Sep 17 00:00:00 2001 From: wcrisman Date: Sun, 28 Dec 2014 16:03:49 -0800 Subject: [PATCH] Fixed bug in MessageBuffer to close the buffer instead of just setting buffer = null. Modified MessageBuffer to close the response if closed its self. Modified SocketContext to get rid of the response linked list, and close the outbound message instead of the response (no more references to Response). Modified SocketContext to immediately create a MessageBuffer from a Response that is ready to be sent, and set it as the currentOutboundMessage (no list or linked list used currently). Modified writeSessionCookies() and prepareResponse() in SocketContext to take the Response as a parameter. --- .../foundation/web/server/MessageBuffer.java | 9 +- .../foundation/web/server/SocketContext.java | 89 +++++++++++-------- 2 files changed, 61 insertions(+), 37 deletions(-) diff --git a/Foundation Web Core/src/com/foundation/web/server/MessageBuffer.java b/Foundation Web Core/src/com/foundation/web/server/MessageBuffer.java index 941fc22..f8d333c 100644 --- a/Foundation Web Core/src/com/foundation/web/server/MessageBuffer.java +++ b/Foundation Web Core/src/com/foundation/web/server/MessageBuffer.java @@ -78,6 +78,11 @@ class MessageBuffer { */ public void close() { this.buffer = null; + + if(response != null) { + response.close(); + response = null; + }//if// }//close()// /** * Gets the byte buffer containing the current portion of the message to be sent. @@ -102,14 +107,14 @@ class MessageBuffer { result = false; //Should never occur currently: See StreamedContent's javadocs.// }//if// else if(getResult == IContent.CONTENT_END) { - buffer = null; + close(); }//else if// if(buffer != null && buffer.position() != 0) buffer.flip(); }//if// else if(!buffer.hasRemaining()) { //Clear the buffer pointer indicating the message buffer is done.// - buffer = null; + close(); result = false; }//else if// }//if// diff --git a/Foundation Web Core/src/com/foundation/web/server/SocketContext.java b/Foundation Web Core/src/com/foundation/web/server/SocketContext.java index 9fc762b..4fd6a3e 100644 --- a/Foundation Web Core/src/com/foundation/web/server/SocketContext.java +++ b/Foundation Web Core/src/com/foundation/web/server/SocketContext.java @@ -95,9 +95,9 @@ public class SocketContext extends AbstractSocketContext implements IWebApplicat /** The last used request number which identifies the sequence for the requests. */ private int lastRequestNumber = 0; /** The response we are currently processing. */ - private Response currentResponse = null; - /** The response we are will process last. */ - private Response lastResponse = null; +// private Response currentResponse = null; +// /** The response we are will process last. */ +// private Response lastResponse = null; /** Tracks the number of bytes sent from the current response. This is only used when debugging. */ private int sentBytes = 0; /** Tracks the getWebServer().debug output for the current request/response cycle. This is only used when debugging. */ @@ -189,7 +189,8 @@ protected synchronized void close() { try {if(key != null) key.cancel();} catch(Throwable e) {} //Clean up after the response and request.// //try {while(currentOutboundMessage != null) {currentOutboundMessage.close(); currentOutboundMessage = currentOutboundMessage.getNext();}} catch(Throwable e2) {} - try {if(currentResponse != null) currentResponse.close();} catch(Throwable e2) {} +// try {if(currentResponse != null) currentResponse.close();} catch(Throwable e2) {} + try {if(currentOutboundMessage != null) currentOutboundMessage.close();} catch(Throwable e2) {} if(getPassThroughSocketContext() != null) { getPassThroughSocketContext().close(); @@ -246,8 +247,7 @@ private void queueOutboundClientMessage(MessageBuffer messageBuffer) { notifyListenerOfPendingWrite(); }//if// }//queueOutboundClientMessage()// -private void writeSessionCookies(PrintStream pout) { - Response response = currentResponse; +private void writeSessionCookies(Response response, PrintStream pout) { ISession session = response.getSession(); if(session != null) { @@ -271,8 +271,7 @@ private void writeSessionCookies(PrintStream pout) { *

Note: The caller must synchronize on this context to prevent multiple threads from accessing the context at the same time.

* @result Whether request is in a receive state. Will be false if the request generated a response that could not be completely transmitted. */ -private void prepareResponse() { - Response response = currentResponse; +private void prepareResponse(Response response) { Request request = (Request) response.getRequest(); byte[] headerBytes = null; IContent content = null; @@ -308,7 +307,7 @@ private void prepareResponse() { }//for// //Write out any cookies necessary to retain our session.// - writeSessionCookies(pout); + writeSessionCookies(response, pout); //End the header.// pout.print("\r\n"); @@ -331,7 +330,7 @@ private void prepareResponse() { pout.print("HTTP/1.1 302 Moved Temporarily\r\n"); //}//else// - writeSessionCookies(pout); + writeSessionCookies(response, pout); pout.print("Location: " + response.getForwardUri() + "\r\n"); @@ -423,7 +422,7 @@ private void prepareResponse() { }//if// }//if// - writeSessionCookies(pout); + writeSessionCookies(response, pout); pout.print("Server: DE/1.0\r\n"); //TODO: IE has a problem with caching and forwarding/redirecting. A page that redirects to another page that was previously cached does not result in IE sending a request for the forwarded content.// @@ -487,7 +486,7 @@ private void prepareResponse() { pout.print("HTTP/1.1 200 OK\r\n"); }//else// - writeSessionCookies(pout); + writeSessionCookies(response, pout); pout.print("Content-Length: 0\r\n"); pout.print("Server: DE/1.0\r\n"); pout.print("\r\n"); @@ -534,8 +533,8 @@ private void prepareResponse() { */ public synchronized boolean sendHttpResponse(Response response) { //Short circuit the response linked list since it shouldn't be being used.// - lastResponse = currentResponse = response; - prepareResponse(); +// lastResponse = currentResponse = response; + prepareResponse(response); // if(currentResponse != null) { // lastResponse.setNextResponse(response); // lastResponse = response; @@ -730,7 +729,7 @@ private synchronized void internalProcessResponses() { boolean finishedSending = true; //Keep sending responses while the buffers are not full and there is another response to send.// - while(finishedSending && currentResponse != null) { + while(finishedSending) { //If the socket is open then send the next buffer of data.// if(key.channel().isOpen()) { //Send the pending response object's prepared buffer of data.// @@ -739,32 +738,52 @@ private synchronized void internalProcessResponses() { //Close the response if successfully sent, or if the socket is closed.// if(finishedSending || !key.channel().isOpen()) { - try {currentResponse.close();} catch(Throwable e) {} + try {currentOutboundMessage.close();} catch(Throwable e) {} }//if// //If we finished sending the current response then load the next one.// if(finishedSending) { - currentResponse = currentResponse.getNextResponse(); - - if(currentResponse == null) { - lastResponse = null; - }//if// - else if(key.channel().isOpen()) { - //Prep the next response object for sending.// - prepareResponse(); - }//else// - else { - //Clean up after all the left over responses.// - while(currentResponse != null) { - currentResponse.close(); - currentResponse = currentResponse.getNextResponse(); - }//while// - - currentResponse = null; - lastResponse = null; - }//else// + //TODO: Queue up the next outbound message. + currentOutboundMessage = null; }//if// }//while// + +// //Keep sending responses while the buffers are not full and there is another response to send.// +// while(finishedSending && currentResponse != null) { +// //If the socket is open then send the next buffer of data.// +// if(key.channel().isOpen()) { +// //Send the pending response object's prepared buffer of data.// +// finishedSending = writeClientBoundMessage(); +// }//if// +// +// //Close the response if successfully sent, or if the socket is closed.// +// if(finishedSending || !key.channel().isOpen()) { +// try {currentResponse.close();} catch(Throwable e) {} +// }//if// +// +// //If we finished sending the current response then load the next one.// +// if(finishedSending) { +// currentResponse = currentResponse.getNextResponse(); +// +// if(currentResponse == null) { +// lastResponse = null; +// }//if// +// else if(key.channel().isOpen()) { +// //Prep the next response object for sending.// +// prepareResponse(); +// }//else// +// else { +// //Clean up after all the left over responses.// +// while(currentResponse != null) { +// currentResponse.close(); +// currentResponse = currentResponse.getNextResponse(); +// }//while// +// +// currentResponse = null; +// lastResponse = null; +// }//else// +// }//if// +// }//while// }//processCurrentResponse()// /** * Sends a response to the client.