/** * This file contains example code from the book * JAVA NETWORKING AND COMMUNICATIONS * by Todd Courtois * ISBN 0-13-850454-7 * * Purchasers of the book may reuse this sample code * for any purpose whatsoever as long as this header * is included. Use of this example code is subject * to the license agreement printed in the book. * * For updates see the web site * http://www.rawthought.com/JNC/ */ /** * Modified by Michael Hicks for CMSC 433, * University of Maryland, 2002. */ import java.io.*; import java.net.*; import java.util.*; /** * An object encapsulating an HTTP response. Provides methods for creating * responses and sending them to remote clients on given streams. */ public class HttpResponse { //response status constants public final static int REPLY_ERROR_NO_ERROR = 200, REPLY_ERROR_NO_SUCH_FILE = 404; public final static String REPLY_EXPLANATION_OK = " OK ",//no problem REPLY_EXPLANATION_ERROR = " ERROR ";//error of some sort public static boolean fDebugOn = true; int fReplyErrorCode = REPLY_ERROR_NO_ERROR; //no error by default String fReplyErrorExplanation = REPLY_EXPLANATION_OK; String fContent; long fContentLastModified = 0; String fContentTypeStr = "text/html"; /** * Used by static routines below for constructing responses */ private HttpResponse(int code, String expl, String content, long lastModified, String contentType) { fReplyErrorCode = code; fReplyErrorExplanation = expl; fContent = content; fContentLastModified = lastModified; fContentTypeStr = contentType; } /** * Build the HTTP reply header * This includes things like the MIME content type, * length, mod date, and so on. */ private String getReplyHeader() { String date = (new Date()).toGMTString(); if (fDebugOn) System.out.println("building header str..."); String headerStr = "HTTP/1.0 " + fReplyErrorCode + fReplyErrorExplanation + "\n" + "Date: " + date + "\n" + "Expires: " + date + "\n" + "Server: Todd's_Skanky_Web_Server/1.0\n" + "MIME-version: 1.0\n" + "Content-type: " + fContentTypeStr + "\n" + "Last-modified: " + (new Date(fContentLastModified)).toGMTString() + "\n" + "Content-length: " + fContent.length() + "\n\n"; //this last seq terminates the header if (fDebugOn) System.out.println("reply header: " + headerStr); return headerStr; }//getReplyHeader /** * Sends this HTTPresponse object to the client at the other end of * the given output stream. * * @param out the output stream that connects to the web browser. */ public void sendResponse(OutputStream out) { /* * We build a StringBufferInputStream here because * the more obvious implementation: * fClientOutputStream.writeBytes(getReplyHeader()); * * ...is EXTREMELY slow. Basically, it sends a series of TCP * packets out containing single-byte data. The * DataOutputStream.writeChars method is so slow because it * writes out data on the output stream a single byte at a time * instead of sending the data in the big blocks that TCP loves. * * Using our "block move" copySrcToSink method, in combination * with the StringBufferInputStream, improves the efficiency * tremendously. */ StringBufferInputStream headerStream = new StringBufferInputStream(getReplyHeader()); copySrcToSink((InputStream)headerStream, out); headerStream = null; if (fDebugOn) System.out.println("done with reply header..."); //save the content file.... StringBufferInputStream contentStream = new StringBufferInputStream(fContent); copySrcToSink((InputStream)contentStream, out); if (fDebugOn) System.out.println("done copying content data..."); } /** * Take a source data input stream and a sink data ouput stream * copy input to output */ private static void copySrcToSink(InputStream src, OutputStream sink) { byte[] tempBuf = new byte[1024]; int bytesRead = 1; try { do { bytesRead = src.read(tempBuf,0,1024); if (bytesRead > 0) { if (fDebugOn) System.out.println("bytesRead: " + bytesRead); sink.write(tempBuf,0,bytesRead); sink.flush(); } } while (bytesRead >= 0); } catch (IOException ioEx) { System.err.println("copySrcToSink failed with: " + ioEx); } } /* copySrcToSink */ /** * Sends an error back to the client indicating that something went wrong. */ public static HttpResponse errorResponse(String msg) { return new HttpResponse(REPLY_ERROR_NO_SUCH_FILE, REPLY_EXPLANATION_ERROR, "Failed!"+msg+"\n", (new Date()).getTime(), "text/html"); } /** * Sends a successful response back to the client. The response * must be formatted HTML. * * @param msg is the main content of the response, to be viewed * in the web browser. */ public static HttpResponse successResponse(String msg) { return new HttpResponse(REPLY_ERROR_NO_ERROR, REPLY_EXPLANATION_OK, msg, (new Date()).getTime(), "text/html"); } }