diff --git a/Foundation Web Core/src/com/foundation/web/application/WebServerApplication.java b/Foundation Web Core/src/com/foundation/web/application/WebServerApplication.java index ef474ac..b694d47 100644 --- a/Foundation Web Core/src/com/foundation/web/application/WebServerApplication.java +++ b/Foundation Web Core/src/com/foundation/web/application/WebServerApplication.java @@ -104,7 +104,7 @@ public class WebServerApplication extends Application implements IWebServer { public void log(int type, String note, Throwable exception) { log(note, exception, type, true); }//log()// - /* + /* TODO: Fix this code - it should be changed from using Framework Models to using a queue of plain objects that can be listened on for changes. private boolean suspend = false; public void log(int type, String note, Throwable exception) { diff --git a/Foundation Web Core/src/com/foundation/web/server/WebServer.java b/Foundation Web Core/src/com/foundation/web/server/WebServer.java index 7c07f3e..3f54a6a 100644 --- a/Foundation Web Core/src/com/foundation/web/server/WebServer.java +++ b/Foundation Web Core/src/com/foundation/web/server/WebServer.java @@ -815,93 +815,104 @@ public class WebServer { }//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(!response.isError() && response.getHeader() != null) { + //Include all but the last end of line.// + pout.print(response.getHeader().substring(0, response.getHeader().length() - 2)); + writeSessionCookies(pout); + //Add a final terminating end of line.// + pout.print("\r\n"); }//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(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// - }//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(); + 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// - 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"); + 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// - - 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(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 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"); + 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"); }//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 { diff --git a/Foundation Web Interfaces/src/com/foundation/web/interfaces/IResponse.java b/Foundation Web Interfaces/src/com/foundation/web/interfaces/IResponse.java index f451113..f196876 100644 --- a/Foundation Web Interfaces/src/com/foundation/web/interfaces/IResponse.java +++ b/Foundation Web Interfaces/src/com/foundation/web/interfaces/IResponse.java @@ -80,20 +80,24 @@ public String getRedirectUri(); */ public void setRedirectUri(String redirectUri); /** - * Gets a user defined header for the response. + * Gets a user defined header for the response (IMPORTANT: First line of the header ONLY). * This is useful for specifying non-standard error codes useable by either the browser or javascript in their processing. * The content will be written out as usual if any content is set. * The error code prempts this. *
Example: "HTTP/1.1 404 Resource Not Found\r\n". Ensure that there is a \r\n at the end of each line you add to the header.
+ * + *TODO: Rename this method. Call it getHeaderFirstLine or something, anything to distinguish it from setting a full blown header (see #getHeader()).
* @param header The header to be used in place of the standard header. This must at the very least include the HTTP tag similar to the one in the above example. */ public String getCustomHeader(); /** - * Sets a user defined header for the response. + * Sets a user defined header for the response (IMPORTANT: First line of the header ONLY). * This is useful for specifying non-standard error codes useable by either the browser or javascript in their processing. * The content will be written out as usual if any content is set. * The error code prempts this. *Example: "HTTP/1.1 404 Resource Not Found\r\n". Ensure that there is a \r\n at the end of each line you add to the header.
+ * + *TODO: Rename this method. Call it setHeaderFirstLine or something, anything to distinguish it from setting a full blown header (see #setHeader()).
* @param customHeader The header to be used in place of the standard header. This must at the very least include the HTTP tag similar to the one in the above example. */ public void setCustomHeader(String customHeader); @@ -109,8 +113,8 @@ public IWebApplication getApplication(); */ public String getHeaderFieldValue(String name); /** - * Sets the content provider which is used to provide all the headers and content for the message. - * @param header Sets a custom header (the entire header, properly formatted for HTTP and ending with \r\n\r\n). + * Sets the exact header that will be sent before sending the content to the client. + * @param header Sets a completely custom header (the entire header, properly formatted for HTTP and ending with \r\n\r\n). */ public void setHeader(String header); }//IResponse// \ No newline at end of file