Switched to using HttpMessageBuffer in the code and moved the code from prepareResponse into initialize.

This commit is contained in:
wcrisman
2014-12-10 14:37:55 -08:00
parent d00638873b
commit c36467d172

View File

@@ -207,11 +207,6 @@ public class WebServer {
/** The ability to chain message buffers into a linked list. */
private MessageBuffer next = null;
/** The optional response the message is based upon. */
private Response response = null;
/** The content if there is any. */
private IContent content = null;
/**
* MessageBuffer constructor.
*/
@@ -233,25 +228,6 @@ public class WebServer {
if(buffer != null && buffer.position() != 0) buffer.flip();
}//setBuffer()//
/**
* MessageBuffer constructor.
* @param buffer The buffer to use for assembling the message bytes.
* @param response The optional response that generates this message.
* @param content The content if the response is not just a header.
*/
public MessageBuffer(ByteBuffer buffer, Response response, IContent content) {
this.buffer = buffer;
this.content = content;
//Fill the remaining buffer space with the content.//
if(content != null) {
content.get(buffer);
}//if//
//Flip the buffer (if not already flipped) so we can write out the bytes.//
if(buffer.position() != 0) buffer.flip();
this.response = response;
}//MessageBuffer()//
/**
* Initializes the message buffer for use.
* @return Whether initialization succeded. Intialization should be considered a success even if none is required or has already been performed. If it fails the caller should close the socket.
@@ -283,42 +259,54 @@ public class WebServer {
* @return Whether the buffer could be loaded with the next part of the message. If false, then the caller should try again in the future when additional message content may be available. Will always be false if there is no content to load from.
*/
public boolean loadBuffer() {
boolean result = true;
if(buffer != null) {
if(content != null) {
int getResult;
buffer.compact();
getResult = content.get(buffer);
if(getResult == IContent.CONTENT_PENDING) {
result = false; //Should never occur currently: See StreamedContent's javadocs.//
}//if//
else if(getResult == IContent.CONTENT_END) {
buffer = null;
}//else if//
if(buffer != null && buffer.position() != 0) buffer.flip();
}//if//
else if(!buffer.hasRemaining()) {
if(!buffer.hasRemaining()) {
//Clear the buffer pointer indicating the message buffer is done.//
buffer = null;
result = false;
}//else if//
close();
}//if//
else {
result = false;
buffer.compact();
}//else//
}//if//
return result;
return false;
//OLD CODE
// boolean result = true;
//
// if(buffer != null) {
// if(content != null) {
// int getResult;
//
// buffer.compact();
// getResult = content.get(buffer);
//
// if(getResult == IContent.CONTENT_PENDING) {
// result = false; //Should never occur currently: See StreamedContent's javadocs.//
// }//if//
// else if(getResult == IContent.CONTENT_END) {
// buffer = null;
// }//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;
// result = false;
// }//else if//
// }//if//
// else {
// result = false;
// }//else//
//
// return result;
}//loadBuffer()//
/** Gets the next message buffer (only used for pass through sockets). */
public MessageBuffer getNext() {return next;}
/** Sets the next message buffer (only used for pass through sockets). */
public void setNext(MessageBuffer next) {this.next = next;}
/** Gets the response object that created the message. This will be null for pass through sockets. */
public Response getResponse() {return response;}
// /** Gets the response object that created the message. This will be null for pass through sockets. */
// public Response getResponse() {return response;}
}//MessageBuffer//
private class WebsocketMessageBuffer extends MessageBuffer {
/** The streaming message handler which will be set only if the currently sending message is streaming. */
@@ -474,6 +462,275 @@ public class WebServer {
}//HttpMessageBuffer()//
/** Gets the response object that created the message. This will be null for pass through sockets. */
public Response getResponse() {return response;}
/**
* Processes the next response in the sequence.
* <p>Note: The caller must synchronize on this context to prevent multiple threads from accessing the context at the same time.</p>
* @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() {
Request request = (Request) response.getRequest();
byte[] headerBytes = null;
IContent content = null;
ByteBuffer buffer = null;
try {
//Wrap the response in http cloths. The HeaderFieldNames will be set if the response was provided with a completely custom HTTP header to be used.//
if(response.getHeaderFieldNames() != null) {
ByteArrayOutputStream bout = new ByteArrayOutputStream(1000);
PrintStream pout = new PrintStream(bout, true, "ASCII");
LiteList headerFieldNames = response.getHeaderFieldNames();
LiteHashMap headerFieldMap = response.getHeaderFieldMap();
//Write the response line which is mapped to the null field name.//
pout.print(headerFieldMap.get(null));
pout.print("\r\n");
//Write the rest of the response header lines in order.//
for(int index = 0; index < headerFieldNames.getSize(); index++) {
String headerFieldName = (String) headerFieldNames.get(index);
String headerFieldValue = (String) headerFieldMap.get(headerFieldName);
if(headerFieldName.equals("Server")) {
pout.print("Server: DE/1.0");
}//if//
else {
pout.print(headerFieldName);
pout.print(": ");
pout.print(headerFieldValue);
}//else//
pout.print("\r\n");
}//for//
//Write out any cookies necessary to retain our session.//
writeSessionCookies(pout);
//End the header.//
pout.print("\r\n");
pout.close();
headerBytes = bout.toByteArray();
//Prepare the content for delivery.//
content = response.getContent();
}//if//
else if(response.getForwardUri() != null) {
ByteArrayOutputStream bout = new ByteArrayOutputStream(1000);
PrintStream pout = new PrintStream(bout, true, "ASCII");
//String today = format.format(new Date());
//The 303 code may not be fully supported by browsers.//
//if(request.getHttpVersion().equalsIgnoreCase("HTTP/1.1") || request.getHttpVersion().equalsIgnoreCase("HTTP/1.2")) {
// pout.print("HTTP/1.1 303 Forwarded\r\n");
//}//if//
//else {
pout.print("HTTP/1.1 302 Moved Temporarily\r\n");
//}//else//
writeSessionCookies(pout);
pout.print("Location: " + response.getForwardUri() + "\r\n");
//Note: Encoded URL's will have their parameters in the content, not in the URL.//
if(response.getContent() == null) {
pout.print("Content-Length: 0\r\n");
}//if//
else {
pout.print("Content-Length: " + response.getContent().getSize() + "\r\n");
pout.print("Content-Type: application/x-www-form-urlencoded\r\n");
}//else//
pout.print("\r\n");
pout.close();
headerBytes = bout.toByteArray();
}//else if//
else if((content = response.getContent()) != null) { //Convert the result into a stream of bytes.//
ByteArrayOutputStream bout = new ByteArrayOutputStream(1000);
PrintStream pout = new PrintStream(bout, true, "ASCII");
Date lastModifiedDate = content.getLastModifiedDate();
String cacheDirective = null;
IMimeType mimeType = content.getMimeType(response.getApplication() != null ? response.getApplication().getMimeTypeProvider() : null);
boolean isDownloaded = content != null && (content.getIsDownloaded() == null ? mimeType != null && mimeType.isDownloaded() : content.getIsDownloaded().booleanValue());
boolean compress = response.getCompress().booleanValue() && (mimeType == null || mimeType.isCompressable());
int compressionType = 0; //0: none, 1: gzip, ..//
if(compress) {
//Check for an encoding allowed by the client that we know how to use.//
if(request.getAllowedEncodings() == null || request.getAllowedEncodings().length < 1) {
compress = false;
}//if//
else {
compress = false;
//Ensure we have an allowed encoding we know how to use.//
for(int index = 0; !compress && index < request.getAllowedEncodings().length; index++) {
String encoding = request.getAllowedEncodings()[index];
if(encoding.equalsIgnoreCase("gzip")) {
compress = true;
compressionType = 1;
}//if//
}//for//
}//else//
}//if//
if(response.isError()) {
if(response.getHeader() != null) {
pout.print(response.getHeader());
}//if//
else {
pout.print("HTTP/1.1 404 Resource Not Found\r\n");
}//else//
}//if//
else if(response.getCustomHeader() != null) {
pout.print(response.getCustomHeader());
}//else if//
else if(isDownloaded && request.getRange() != null) {
pout.print("HTTP/1.1 206 Partial Content\r\n");
}//else if//
else {
pout.print("HTTP/1.1 200 OK\r\n");
}//else//
pout.print("Content-Length: " + (content != null ? content.getSize() : 0) + "\r\n");
if(compress) {
//TODO: Add others?
if(compressionType == 1) {
content = new GzipContent(content);
pout.print("Content-Encoding: gzip\r\n");
}//if//
}//if//
if(content != null) {
//Note: The character set gives IE indigestion for some reason.//
pout.print("Content-Type: " + (mimeType != null ? mimeType.getMimeName() : "text/html") + "; charset=" + (response.getCharacterSet() == null ? "UTF-8" : response.getCharacterSet()) + "\r\n");
cacheDirective = content.getCacheDirective();
if(isDownloaded) {
pout.print("Content-Disposition: attachment; filename=\"" + content.getDownloadName() + "\";\r\n");
pout.print("Accept-Ranges: bytes\r\n");
if(request.getRange() != null) {
// Debug.log("Sending a ranged response: " + request.getRange() + " content range: (" + content.getStart() + " - " + content.getEnd() + "/" + content.getSize() + ").");
pout.print("Range: " + request.getRange() + "\r\n");
pout.print("Content-Range: bytes " + content.getStart() + "-" + content.getEnd() + "/" + content.getSize() + "\r\n");
}//if//
}//if//
}//if//
writeSessionCookies(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.//
//private / no-cache
if(content.getExpiresDirective() != null) {
pout.print("Expires: " + getHttpDateFormat().format(content.getExpiresDirective()));
}//if//
if(cacheDirective != null) {
pout.print("Cache-Control: " + cacheDirective + "\r\n");
}//if//
else {
int cacheLength = content.getCacheLength() != null ? content.getCacheLength().intValue() : mimeType != null ? mimeType.getDefaultCacheLength() : IMimeType.CACHE_LENGTH_NEVER_CACHE;
if(cacheLength > 0) {
pout.print("Cache-Control: public, max-age=" + cacheLength + "\r\n");
}//if//
else if(cacheLength == IMimeType.CACHE_LENGTH_ALWAYS_TEST) {
pout.print("Cache-Control: public, pre-check=0, post-check=120\r\n");
}//else if//
else if(cacheLength == IMimeType.CACHE_LENGTH_NEVER_CACHE) {
pout.print("Cache-Control: no-cache\r\n");
}//else if//
else {
pout.print("Cache-Control: no-store\r\n");
}//else//
}//else//
//TODO: Determine if we need to use age.
//pout.print("Age: 0\r\n");
//TODO: Determine if we need to use ETags
if(lastModifiedDate != null) {
SimpleDateFormat format = getHttpDateFormat();
pout.print("Last-Modified: " + format.format(lastModifiedDate) + "\r\n");
pout.print("Date: " + format.format(new Date()) + "\r\n");
}//if//
pout.print("\r\n");
headerBytes = bout.toByteArray();
}//else if//
else {
ByteArrayOutputStream bout = new ByteArrayOutputStream(1000);
PrintStream pout = new PrintStream(bout, true, "ASCII");
if(response.isError()) {
if(response.getHeader() != null) {
pout.print(response.getHeader());
}//if//
else {
pout.print("HTTP/1.1 404 Resource Not Found\r\n");
}//else//
}//if//
else if(response.getCustomHeader() != null) {
pout.print(response.getCustomHeader());
}//else if//
else {
Debug.log(new RuntimeException("The response to: " + response.getRequest().getHeaderText() + " had no response content!"));
pout.print("HTTP/1.1 200 OK\r\n");
}//else//
writeSessionCookies(pout);
pout.print("Content-Length: 0\r\n");
pout.print("Server: DE/1.0\r\n");
pout.print("\r\n");
pout.close();
headerBytes = bout.toByteArray();
}//else//
buffer = ByteBuffer.allocate(headerBytes.length > 2000 ? headerBytes.length : 2000);
buffer.put(headerBytes);
if(debug) {
//Test code...
ByteBuffer buffer2 = ByteBuffer.allocate(headerBytes.length);
buffer2.put(headerBytes);
buffer2.flip();
CharBuffer ch = decoder.decode(buffer2);
// debugBuffer.append("Sending message:\n");
// debugBuffer.append(ch.toString());
// debugBuffer.append("\nResponse Size: " + (headerBytes.length + (content != null ? content.getSize() : 0)) + "\n");
Debug.log(ch.toString());
}//if//
//Ignore the content if we are only accessing the header.//
// if(content != null && request.getRequestType() != Request.TYPE_HEAD) {
// content.get(buffer);
// }//if//
//Save the buffer as the current pending outbound message for this socket context.//
//currentOutboundMessage = new MessageBuffer(buffer, response, );
setBuffer(buffer);
this.content = content != null && request.getRequestType() != Request.TYPE_HEAD ? content : null;
//Fill the remaining buffer space with the content.//
if(content != null) {
content.get(buffer);
}//if//
//Flip the buffer (if not already flipped) so we can write out the bytes.//
if(buffer.position() != 0) buffer.flip();
}//try//
catch(Throwable e) {
Debug.log("Fatal Error: Failed to build and send the response message due to an exception.", e);
//Force the channel to close.//
// try {key.channel().close();} catch(Throwable e2) {}
//Clean up after the request and response.//
try {response.close();} catch(Throwable e2) {}
}//catch//
}//prepareResponse()//
/* (non-Javadoc)
* @see com.foundation.web.server.WebServer.MessageBuffer#initialize()
*/
@@ -776,8 +1033,48 @@ public class WebServer {
response = null;
content = null;
}//close()//
/* (non-Javadoc)
* @see com.foundation.web.server.WebServer.MessageBuffer#loadBuffer()
//New Code
// /* (non-Javadoc)
// * @see com.foundation.web.server.WebServer.MessageBuffer#loadBuffer()
// */
// public boolean loadBuffer() {
// boolean result = true;
// ByteBuffer buffer = getBuffer();
//
// if(buffer != null) {
// if(content != null) {
// int getResult;
//
// buffer.compact();
// getResult = content.get(buffer);
//
// if(getResult == IContent.CONTENT_PENDING) {
// result = false; //Should never occur currently: See StreamedContent's javadocs.//
// }//if//
// else if(getResult == IContent.CONTENT_END) {
// content = null;
// }//else if//
//
// if(buffer.position() != 0) buffer.flip();
// }//if//
// else {
// if(!buffer.hasRemaining()) {
// //Clear the buffer pointer indicating the message buffer is done.//
// close();
// }//if//
//
// result = false;
// }//else//
// }//if//
// else {
// result = false;
// }//else//
//
// return result;
// }//loadBuffer()//
/**
* Loads the next part of the message into the buffer (any remaining bytes in the buffer will be compacted).
* @return Whether the buffer could be loaded with the next part of the message. If false, then the caller should try again in the future when additional message content may be available. Will always be false if there is no content to load from.
*/
public boolean loadBuffer() {
boolean result = true;
@@ -794,19 +1091,24 @@ public class WebServer {
result = false; //Should never occur currently: See StreamedContent's javadocs.//
}//if//
else if(getResult == IContent.CONTENT_END) {
buffer = null;
content = null;
}//else if//
if(buffer.position() != 0) buffer.flip();
if(buffer != null && buffer.position() != 0) buffer.flip();
}//if//
else {
if(!buffer.hasRemaining()) {
else if(!buffer.hasRemaining()) {
//Clear the buffer pointer indicating the message buffer is done.//
close();
}//if//
//Does this cause the bug?
// close();
//Comment out buffer = null;
buffer = null;
result = false;
}//else//
}//else if//
//Does this cause the bug?
// else {
// result = false;
// }//else//
}//if//
else {
result = false;
@@ -1295,259 +1597,8 @@ public class WebServer {
* @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;
Request request = (Request) response.getRequest();
byte[] headerBytes = null;
IContent content = null;
ByteBuffer buffer = null;
try {
//Wrap the response in http cloths. The HeaderFieldNames will be set if the response was provided with a completely custom HTTP header to be used.//
if(response.getHeaderFieldNames() != null) {
ByteArrayOutputStream bout = new ByteArrayOutputStream(1000);
PrintStream pout = new PrintStream(bout, true, "ASCII");
LiteList headerFieldNames = response.getHeaderFieldNames();
LiteHashMap headerFieldMap = response.getHeaderFieldMap();
//Write the response line which is mapped to the null field name.//
pout.print(headerFieldMap.get(null));
pout.print("\r\n");
//Write the rest of the response header lines in order.//
for(int index = 0; index < headerFieldNames.getSize(); index++) {
String headerFieldName = (String) headerFieldNames.get(index);
String headerFieldValue = (String) headerFieldMap.get(headerFieldName);
if(headerFieldName.equals("Server")) {
pout.print("Server: DE/1.0");
}//if//
else {
pout.print(headerFieldName);
pout.print(": ");
pout.print(headerFieldValue);
}//else//
pout.print("\r\n");
}//for//
//Write out any cookies necessary to retain our session.//
writeSessionCookies(pout);
//End the header.//
pout.print("\r\n");
pout.close();
headerBytes = bout.toByteArray();
//Prepare the content for delivery.//
content = response.getContent();
}//if//
else if(response.getForwardUri() != null) {
ByteArrayOutputStream bout = new ByteArrayOutputStream(1000);
PrintStream pout = new PrintStream(bout, true, "ASCII");
//String today = format.format(new Date());
//The 303 code may not be fully supported by browsers.//
//if(request.getHttpVersion().equalsIgnoreCase("HTTP/1.1") || request.getHttpVersion().equalsIgnoreCase("HTTP/1.2")) {
// pout.print("HTTP/1.1 303 Forwarded\r\n");
//}//if//
//else {
pout.print("HTTP/1.1 302 Moved Temporarily\r\n");
//}//else//
writeSessionCookies(pout);
pout.print("Location: " + response.getForwardUri() + "\r\n");
//Note: Encoded URL's will have their parameters in the content, not in the URL.//
if(response.getContent() == null) {
pout.print("Content-Length: 0\r\n");
}//if//
else {
pout.print("Content-Length: " + response.getContent().getSize() + "\r\n");
pout.print("Content-Type: application/x-www-form-urlencoded\r\n");
}//else//
pout.print("\r\n");
pout.close();
headerBytes = bout.toByteArray();
}//else if//
else if((content = response.getContent()) != null) { //Convert the result into a stream of bytes.//
ByteArrayOutputStream bout = new ByteArrayOutputStream(1000);
PrintStream pout = new PrintStream(bout, true, "ASCII");
Date lastModifiedDate = content.getLastModifiedDate();
String cacheDirective = null;
IMimeType mimeType = content.getMimeType(response.getApplication() != null ? response.getApplication().getMimeTypeProvider() : null);
boolean isDownloaded = content != null && (content.getIsDownloaded() == null ? mimeType != null && mimeType.isDownloaded() : content.getIsDownloaded().booleanValue());
boolean compress = response.getCompress().booleanValue() && (mimeType == null || mimeType.isCompressable());
int compressionType = 0; //0: none, 1: gzip, ..//
if(compress) {
//Check for an encoding allowed by the client that we know how to use.//
if(request.getAllowedEncodings() == null || request.getAllowedEncodings().length < 1) {
compress = false;
}//if//
else {
compress = false;
//Ensure we have an allowed encoding we know how to use.//
for(int index = 0; !compress && index < request.getAllowedEncodings().length; index++) {
String encoding = request.getAllowedEncodings()[index];
if(encoding.equalsIgnoreCase("gzip")) {
compress = true;
compressionType = 1;
}//if//
}//for//
}//else//
}//if//
if(response.isError()) {
if(response.getHeader() != null) {
pout.print(response.getHeader());
}//if//
else {
pout.print("HTTP/1.1 404 Resource Not Found\r\n");
}//else//
}//if//
else if(response.getCustomHeader() != null) {
pout.print(response.getCustomHeader());
}//else if//
else if(isDownloaded && request.getRange() != null) {
pout.print("HTTP/1.1 206 Partial Content\r\n");
}//else if//
else {
pout.print("HTTP/1.1 200 OK\r\n");
}//else//
pout.print("Content-Length: " + (content != null ? content.getSize() : 0) + "\r\n");
if(compress) {
//TODO: Add others?
if(compressionType == 1) {
content = new GzipContent(content);
pout.print("Content-Encoding: gzip\r\n");
}//if//
}//if//
if(content != null) {
//Note: The character set gives IE indigestion for some reason.//
pout.print("Content-Type: " + (mimeType != null ? mimeType.getMimeName() : "text/html") + "; charset=" + (response.getCharacterSet() == null ? "UTF-8" : response.getCharacterSet()) + "\r\n");
cacheDirective = content.getCacheDirective();
if(isDownloaded) {
pout.print("Content-Disposition: attachment; filename=\"" + content.getDownloadName() + "\";\r\n");
pout.print("Accept-Ranges: bytes\r\n");
if(request.getRange() != null) {
// Debug.log("Sending a ranged response: " + request.getRange() + " content range: (" + content.getStart() + " - " + content.getEnd() + "/" + content.getSize() + ").");
pout.print("Range: " + request.getRange() + "\r\n");
pout.print("Content-Range: bytes " + content.getStart() + "-" + content.getEnd() + "/" + content.getSize() + "\r\n");
}//if//
}//if//
}//if//
writeSessionCookies(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.//
//private / no-cache
if(content.getExpiresDirective() != null) {
pout.print("Expires: " + getHttpDateFormat().format(content.getExpiresDirective()));
}//if//
if(cacheDirective != null) {
pout.print("Cache-Control: " + cacheDirective + "\r\n");
}//if//
else {
int cacheLength = content.getCacheLength() != null ? content.getCacheLength().intValue() : mimeType != null ? mimeType.getDefaultCacheLength() : IMimeType.CACHE_LENGTH_NEVER_CACHE;
if(cacheLength > 0) {
pout.print("Cache-Control: public, max-age=" + cacheLength + "\r\n");
}//if//
else if(cacheLength == IMimeType.CACHE_LENGTH_ALWAYS_TEST) {
pout.print("Cache-Control: public, pre-check=0, post-check=120\r\n");
}//else if//
else if(cacheLength == IMimeType.CACHE_LENGTH_NEVER_CACHE) {
pout.print("Cache-Control: no-cache\r\n");
}//else if//
else {
pout.print("Cache-Control: no-store\r\n");
}//else//
}//else//
//TODO: Determine if we need to use age.
//pout.print("Age: 0\r\n");
//TODO: Determine if we need to use ETags
if(lastModifiedDate != null) {
SimpleDateFormat format = getHttpDateFormat();
pout.print("Last-Modified: " + format.format(lastModifiedDate) + "\r\n");
pout.print("Date: " + format.format(new Date()) + "\r\n");
}//if//
pout.print("\r\n");
headerBytes = bout.toByteArray();
}//else if//
else {
ByteArrayOutputStream bout = new ByteArrayOutputStream(1000);
PrintStream pout = new PrintStream(bout, true, "ASCII");
if(response.isError()) {
if(response.getHeader() != null) {
pout.print(response.getHeader());
}//if//
else {
pout.print("HTTP/1.1 404 Resource Not Found\r\n");
}//else//
}//if//
else if(response.getCustomHeader() != null) {
pout.print(response.getCustomHeader());
}//else if//
else {
Debug.log(new RuntimeException("The response to: " + response.getRequest().getHeaderText() + " had no response content!"));
pout.print("HTTP/1.1 200 OK\r\n");
}//else//
writeSessionCookies(pout);
pout.print("Content-Length: 0\r\n");
pout.print("Server: DE/1.0\r\n");
pout.print("\r\n");
pout.close();
headerBytes = bout.toByteArray();
}//else//
buffer = ByteBuffer.allocate(headerBytes.length > 2000 ? headerBytes.length : 2000);
buffer.put(headerBytes);
if(debug) {
//Test code...
ByteBuffer buffer2 = ByteBuffer.allocate(headerBytes.length);
buffer2.put(headerBytes);
buffer2.flip();
CharBuffer ch = decoder.decode(buffer2);
// debugBuffer.append("Sending message:\n");
// debugBuffer.append(ch.toString());
// debugBuffer.append("\nResponse Size: " + (headerBytes.length + (content != null ? content.getSize() : 0)) + "\n");
Debug.log(ch.toString());
}//if//
//Ignore the content if we are only accessing the header.//
// if(content != null && request.getRequestType() != Request.TYPE_HEAD) {
// content.get(buffer);
// }//if//
//Save the buffer as the current pending outbound message for this socket context.//
currentOutboundMessage = new MessageBuffer(buffer, response, content != null && request.getRequestType() != Request.TYPE_HEAD ? content : null);
}//try//
catch(Throwable e) {
Debug.log("Fatal Error: Failed to build and send the response message due to an exception.", e);
//Force the channel to close.//
try {key.channel().close();} catch(Throwable e2) {}
//Clean up after the request and response.//
try {response.close();} catch(Throwable e2) {}
}//catch//
currentOutboundMessage = new HttpMessageBuffer(currentResponse);
currentOutboundMessage.initialize();
}//prepareResponse()//
/**
* Adds a HTTP response to the socket context.