Wednesday, March 10, 2010

TannHandler (This is the meat of the program)

/**
Daniel Tanner
CMPT 352 - Computer Networking
January 26th, 2010
Handler class for threaded DNS Server
 */

import java.net.*;
import java.lang.Object.*;
import java.util.*;
import java.text.*;
import javax.activation.*;
import java.io.*;

public class TannHandler
{       
    //Create variables
    public static Configuration configurator = TannerWebServer.configurator;
    public static WeakHashMap cache = TannerWebServer.cache;
    public static File logFile = TannerWebServer.logFile;
    public static InputStream fromClient = null;
    public static BufferedOutputStream toClient = null;
    public static File requestedFile = null;
    public static HTTPRequestHeader requestHeader = null;
    public static HTTPResponseHeader responseHeader = null;
   
    public static long startTime = System.currentTimeMillis();
   
    //This method invoked as a separate thread
    public void process(Socket client) throws IOException
    {   
        //try block for opening streams and getting hostname
        try
        {
            //open Streams
            fromClient = (client.getInputStream());
            toClient = new BufferedOutputStream(client.getOutputStream());
       
       
            while(System.currentTimeMillis() - startTime < 60000)
            {
                //Get Request
                System.out.println("Now handing InputStream from client to request header");
                requestHeader = new HTTPRequestHeader(fromClient);
                responseHeader = new HTTPResponseHeader();
       
                //process Request
                processRequest(client);
            }
        }
       
        catch(IOException ioe)
        {
            System.err.println(ioe);
            System.exit(0);
        }
       
                finally
                {
                    // close streams and socket
                    if (fromClient != null)
                        fromClient.close();
                    if (toClient != null)
                        toClient.close();
                    if (client != null)
                        client.close();
                }
    }
   
    /** This function will process the HTTP request
    If GET, will try to find the file in the cache.
    If the file isn't in the hashmap it will add it to the cache.
    If the file doesn't exist, will send the 404 error
    the default response is to send the 400 error
    */
    public void processRequest(Socket client) throws IOException
    {
        //GET command
        if(requestHeader.getMethod() == "GET" || requestHeader.getMethod() == "get")
        {
            //check if the path is asking for the default
            if(requestHeader.getPath() == "/")
            {
                //check cache
                String defaultDoc = TannerWebServer.configurator.getDefaultDocument();
                if(cache.containsKey(defaultDoc))
                {
                    requestedFile = cache.get(defaultDoc);
                }
               
                //not in cache, load it in
                else
                {
                    requestedFile = new File(defaultDoc);
                    cache.put(defaultDoc, requestedFile);
                }
            }
           
            //check if it's in cache, if it's not, add it to cache
            else if(cache.containsKey(requestHeader.getPath()))
            {               
                requestedFile = cache.get(requestHeader.getPath());
            }
            else
            {
                //open new File
                try
                {
                    requestedFile = new File(requestHeader.getPath());
                    if(!requestedFile.exists())
                        throw new FileNotFoundException();
                    cache.put(requestHeader.getPath(), requestedFile);
                }
               
                //404 error
                catch (FileNotFoundException fnfe)
                {
                    responseHeader.setCode("404");
                    responseHeader.setMessage("File Not Found");
               
                    //Write 404 page to client
                    if(cache.containsKey("/404.html"))               
                        requestedFile = cache.get("/404.html");
                    else
                    {
                        requestedFile = new File(configurator.get404());
                        cache.put("/404.html", requestedFile);
                    }
                }
            }
        }
       
        //Bad request
        else
        {
            responseHeader.setCode("400");
            responseHeader.setMessage("Bad Request");
           
            //write 400 page to client
            if(cache.containsKey("/400.html"))
                requestedFile = cache.get("/400.html");
            else
            {
                requestedFile = new File(configurator.get404());
                cache.put("/404.html", requestedFile);
            }
        }
       
        //Fill out responseHeader headers
        DateFormat df = DateFormat.getDateInstance(DateFormat.LONG);
        Calendar cal = Calendar.getInstance(new SimpleTimeZone(0, "GMT"));
        df.setCalendar(cal);
        Date now = new Date();
        javax.activation.MimetypesFileTypeMap someMimes = new javax.activation.MimetypesFileTypeMap();
        responseHeader.setDate(df.format(now));
        responseHeader.setServerName(TannerWebServer.configurator.getServerName());
        responseHeader.setContentType(someMimes.getContentType(requestedFile));
        responseHeader.setContentLength(requestedFile.length());
       
        //write the header and the file to the client
        toClient.write(responseHeader.getBytes());
        InputStream requestedFileStream = null;
        try
        {
            requestedFileStream = new BufferedInputStream(new FileInputStream(requestedFile));
        }
        catch(IOException ioe)
        {
            System.err.println(ioe);
            System.exit(0);
        }
       
        while(requestedFileStream.available() > 0)
        {
            toClient.write(requestedFileStream.read());
        }
        toClient.write("\r\n\r\n".getBytes("US-ASCII"));
        toClient.flush();
       
        //print to log file
        String logEntry = client.getInetAddress().getHostAddress() + ":" + client.getPort() + " " + df.format(now) + "\"" + requestHeader.getMethod() + " " + requestHeader.getPath() + " " + responseHeader.getHTTPVersion() + responseHeader.getCode() + " " + requestedFile.length() + "\n";
        OutputStream logOut = null;
        try
        {
            if(logFile.exists())
                logOut = new BufferedOutputStream(new FileOutputStream(logFile, true));
            else
                logOut = new BufferedOutputStream(new FileOutputStream(logFile, false));
            logOut.write(logEntry.getBytes("US-ASCII"));
        }
        catch (IOException ioe)
        {
            System.err.println(ioe);
            System.exit(0);
        }
       
        //restart the timer
        startTime = System.currentTimeMillis();
    }
}

No comments:

Post a Comment