/*****************************************************************************
 *
 * 8. Uebungsblatt Verteilte Systeme II
 * University of Ulm, Distributed Systems, 1999
 *
 *****************************************************************************
 *
 * W3Thread.java
 *
 * this class handles individual client connections
 *
 * @author Frank Kargl
 * @version 0.1
 * 
 *****************************************************************************
 * 
 * Changes:
 * 99-02-09 14:06 Frank Kargl
 *          initial coding
 *
 *****************************************************************************/

import java.io.*;
import java.net.*;

class W3Thread extends Thread {

	public static String DOC_ROOT = "/users/depart1/fkargl/public_html";
											// Document Root
	
	private Socket incoming;		// socket connected to client
	private DataOutputStream out;	// output stream connected to above socket

	//=public=================================================================

  	/**
     * constructor method
	 *
	 * @param     sock - client socket
	 * @return    -
	 */
	public W3Thread(Socket sock) {
		incoming = sock;
	}

	/**
     * sendError method
	 *
	 * @param     message - the error message with Content Type
	 * @return    -
	 */
	public void sendErrorCT(String message) {

		try {
			out.writeBytes("Content-Type: text/html\r\n\r\n");
			sendError(message);
		} catch (IOException ioe) {
		   	System.err.println("IOException while " +
					"reading/sending to/from socket");
			ioe.printStackTrace();
	   	}
			
	}
			
/**
     * sendError method
	 *
	 * @param     message - the error message without Content Type
	 * @return    -
	 */
	public void sendError(String message) {

		try {
			out.writeBytes("<H1>"+message+"</H1>\r\n");
			out.flush();
			incoming.close();
		} catch (IOException ioe) {
		   	System.err.println("IOException while " +
					"reading/sending to/from socket");
			ioe.printStackTrace();
	   	}
			
	}

	/**
     * run method
	 *
	 * @param     -
	 * @return    -
	 */
  
	public void run() {

		try {

			InputStream inStream = incoming.getInputStream();
			BufferedReader br = new BufferedReader(
									new InputStreamReader(inStream));

			OutputStream outStream = incoming.getOutputStream();
			out = new DataOutputStream(outStream);

			// read request
			String request = br.readLine();
			
			System.out.println("Request: "+request);
			
			String method;
			if (request.startsWith("GET")) {
					method = "GET";
			} else {
				sendErrorCT("Method unknown");
				return;
			}

			System.out.println("Method: " + method);

			// extract filename
			int beginFilename = request.indexOf(" ") + 1;
			int endFilename = request.indexOf(" ", beginFilename);
			String filename = request.substring(beginFilename, endFilename);
			request.replace('/',
				   	System.getProperty("file.separator").charAt(0));

			System.out.println("Filename: " + filename);

			// check http version
			String httpMajorS = request.substring(endFilename+6, endFilename+7);
			System.out.println("http Major: " + httpMajorS);
			String httpMinorS = request.substring(endFilename+8, endFilename+9);
			System.out.println("http Minor: " + httpMinorS);
			
			int httpMajor = Integer.parseInt(httpMajorS);
			int httpMinor = Integer.parseInt(httpMinorS);
			
			System.out.println("Protocol: HTTP/"+httpMajor+"."+httpMinor);

			if (httpMajor != 1) {
				sendErrorCT("Wrong Protocol Version");
				return;
			}

			// try to figure out mime-type
			String suffix;
			String mimeType;
			int beginSuffix =
				filename.lastIndexOf(".", filename.length()) + 1;
			int endSuffix = filename.length();
			int lastSlash = filename.lastIndexOf(
					System.getProperty("file.separator"), filename.length());
			
			suffix = filename.substring(beginSuffix, endSuffix);
			
			System.out.println("Suffix: " + suffix);
			
			if (suffix.equalsIgnoreCase("gif")) {
				mimeType = "image/gif";
			} else if (suffix.equalsIgnoreCase("html") ||
					   suffix.equalsIgnoreCase("htm")) {
				mimeType = "text/html";
			} else {
				sendErrorCT("Unknown Mime Type");
				return;
			}
			
			System.out.println("Mimetype: " + mimeType);

			try{
				
				// send header
				out.writeBytes("HTTP/"+httpMajor+
					"."+httpMinor+" 200 OK\r\n");
				out.writeBytes("Content-Type: "+mimeType+"\r\n\r\n");

				// read and send file
				filename = DOC_ROOT + filename;
				FileInputStream file = new FileInputStream(filename);
				byte[] buffer = new byte[1024];
				int bytesRead;
				while ((bytesRead = file.read(buffer)) != -1) {
					out.write(buffer, 0, bytesRead);
				}   

			} catch(IOException ioe) { 
				sendError("Error sending data");
				ioe.printStackTrace();
				return;
				
			}

			// close socket
			out.flush();
			incoming.close();

		} catch(IOException ioe) {
		   	System.err.println("IOException while " +
					"reading/sending to/from socket");
			ioe.printStackTrace();
			return;
	   	}

	}

	//=package================================================================
	
	//=protected==============================================================
	
	//=private================================================================

}