//: TraiteConnexion.java
import java.net.*;
import java.io.*;
import java.util.*;

public class TraiteConnexion extends Thread {
    private Socket connexion; // socket de connexion
    private BufferedReader in;// le flux d'entree
    private PrintWriter out;  // le flux de sortie

	private String req_method; // Requete HTTP
	private String req_url;
	private String req_version;
	
	private String dirsep = System.getProperty("file.separator");
	private String curdir = System.getProperty("user.dir");

    TraiteConnexion( Socket connexion ) {
		  // connexion est le socket retourne par accept()
		  this.connexion=connexion;
		  try {
				// Creation des deux flux
				in = new BufferedReader(new InputStreamReader(
					 connexion.getInputStream()));
				out = new PrintWriter(connexion.getOutputStream());
		  }
		  catch(IOException e){
				System.err.println("Erreur: TraiteConnexion "
										 + e.getMessage());
		  }
    }

	 // Envoi des en-tetes HTTP en cas de succes:
	 public void sendHTTPHeaders( String type ){
		  out.println( "HTTP/1.0 200 OK" );
		  out.println( "Server: TP GTR" );
		  out.println( "Content-Type: " + type );
		  out.println("");
	 }

	 // Envoi d'un message d'erreur HTTP:
	 public void sendErrorMessage(int errCode ){
		  System.err.println("Envoi de l'erreur " + errCode );
		  out.println( "HTTP/1.0 " + errCode + " ERROR" );
		  out.println("");
		  out.println("<HTML><H1>Erreur " + errCode + "</H1><p>");
		  out.println("Impossible de traiter cette requete<p>");
		  out.println("method=" + req_method + "<br>");
		  out.println("URL   =" + req_url + "<br>");
		  out.println("</HTML>");
	 }

	 // Lecture et envoi d'un fichier text/html:
	 public void sendFile(String filename) {		
		  try {
				// ouvre le fichier
				BufferedReader fIn = null;
				try {
					 File file = new File(curdir,filename);
					 fIn = 
						  new BufferedReader( 
								new InputStreamReader(
									 new FileInputStream(file)));
				} catch  (FileNotFoundException e) {
					 sendErrorMessage( 404 ); // NOT FOUND !
				}
				if (fIn != null) {
					 // envoie header HTTP
					 sendHTTPHeaders( "text/HTML" );
					 // recopie le fichier ligne a ligne
					 String line = fIn.readLine();
					 while (line!=null) {
						  out.println(line);
						  line=fIn.readLine();
					 }
					 fIn.close();
				}
		  } catch (IOException e) {
				System.err.println("Erreur: TraiteConnexion "
										 + e.getMessage());
		  }
    }

	 // Execute le script CGI nomScript
	 public void execCGI(String nomScript){
		  String command = curdir + dirsep + nomScript;
		  System.err.println("execution du CGI " + command );
		  try {
				// Lance la commande 
				Process p = Runtime.getRuntime().exec( command );
				// Recupere sa sortie
				BufferedReader pin = new BufferedReader(
					 new InputStreamReader(p.getInputStream()));
				String line;
				while ((line = pin.readLine()) != null) {
					 out.println(line); // envoi au client
					 // System.out.println(line); 
				}
				pin.close();
				p.destroy();
		  } catch (IOException e) {
				sendErrorMessage( 400 ); // BAD REQUEST
				System.err.println("Erreur: executeCGI " 
										 + e.getMessage());
		  }				
	 }

	 // Lecture des en-tetes HTTP
	 // renseigne req_method, req_url, req_version
	 protected void readHTTPHeaders() throws IOException {
		  String line = in.readLine();
		  System.err.println(line);
		  StringTokenizer st = new StringTokenizer(line);
		  req_method  = st.nextToken();
		  req_url     = st.nextToken();
		  req_version = st.nextToken();
		  // Lit la suite de l'en-tete et affiche
		  int content_length = 0;
		  while (line.length() > 0) {
				line = in.readLine();
				System.err.println(line);
				if (line.length() > 16 &&
					(line.substring(0,15).compareToIgnoreCase("Content-Length:") == 0)) {
					String s = line.substring(16,line.length());
					content_length = Integer.parseInt(s);
				}
		  }
		  // affiche corps de la requete (utile pour POST)
		  if (content_length > 0) {
			  char buf[] = new char[content_length];
			  in.read( buf, 0, content_length );
			  System.err.print( buf );
		  } else {
			  System.err.println( "content_length == " + content_length );
		  }
	 }

	 public void run(){  
		  try {	
				readHTTPHeaders();
				if (req_method.equals("GET")) {
					 if (req_url.equals("/")) {
						  req_url = "index.html";
					 }
					 System.err.println( "demande du fichier: " 
												+ req_url);				
					 if (req_url.endsWith(".cgi")) {
						  execCGI(req_url);
					 } else
						  sendFile( req_url );
				} else {
					 // commande inconnue
					 System.err.println("Erreur: commande inconnue: "
											  + req_method);
					 sendErrorMessage( 400 ); // BAD REQUEST
				}		
				out.flush(); // force envoi
				// fermeture du socket:
				in.close();
				out.close();
				connexion.close();
		  } catch (IOException e) {
				sendErrorMessage(500); // INTERNAL ERROR
				System.err.println("Erreur: TraiteConnexion " 
										 + e.getMessage());
		  }
    }//fin
}//fin classe
