Das HTTP-Protokoll: Beispiel: Einfacher HTTP-Server

Dieser Server schickt nur die gefragte Datei zurück. Die Konfiguration erfolgt über die Kommandozeilen-Parameter in der Reihenfolge: Verzeichnis, Default-Datei, Port.
 
import java.net.Socket;
import java.net.ServerSocket;
import java.io.*;
import java.util.StringTokenizer;
import sun.servlet.http.HttpDate;

public class BasicHttp extends Thread

 Socket Connect;   // Die Socket der Verbindung
 static String Docroot;  // Root des Server-Dateisystems
 static String Indexfile;
 
 public static void main(String args[])
 { // Die Parameter sind Docroot (ohne letzten '/'), 
   // Indexfile, Port

  int port;   // Der Port, an dem der Server warten soll
  ServerSocket socket;// Die Socket des Servers
  Socket connection; // Die Socket der Verbindung
 
  System.out.println( "Starte ..." );
    // Versuch, Root und Name des Indexfiles aus
    //den Parametern zu lesen:
  try
  { Docroot = args[0]; }
  catch (Exception e)
  { Docroot = "."; }
  try
  { Indexfile = args[1]; }
  catch (Exception e)
  { Indexfile = "index.html"; }
    // Versuch, den Port aus den Parametern zu lesen:
  try
  {
   port = Integer.parseInt(args[2]);
   if (port < 0 || port > 65535) port = 0;
  }
  catch (Exception e)
  { port = 0; }
  try
  {
   socket = new ServerSocket(port);
    // Erzeugen einer Socket
   System.out.println("Warte auf Verbindung an Port "
    + socket.getLocalPort());
   System.out.println("Docroot: " + Docroot);
   System.out.println("Indexfile: " + Indexfile);
   while (true)
   { // Endlos auf Verbindungen warten ...
    while (activeCount() > 100);
     // max. 100 Threads starten, geg. warten
    new BasicHttp(socket.accept()).start();
     // fuer jede Verbindung ein neuer Thread
   }
  }
  catch (Exception e)
  { // Ganz gleich welcher Fehler ...
    System.err.println("Ouch!!!");
  }
 }
 
// Konstruktor
 public BasicHttp(Socket s)
 {
  Connect = s;
 }

// Verarbeiten der Requests
 public void run()
 {
  try
  {
   PrintStream os = new PrintStream(
        Connect.getOutputStream());

   BufferedReader br = new BufferedReader(
       new InputStreamReader(Connect.getInputStream()));
// erste Zeile lesen; z.B. "GET /hallo.html HTTP/1.0"
   String get = br.readLine();
   StringTokenizer st = new StringTokenizer(get);
   String method = st.nextToken();  // Methode
   String filename = st.nextToken(); // Request-URI
   if (filename.endsWith("/")) 
        // evt. Indexfile anhaengen

    filename += Indexfile;
   String ct = guessContentType(filename); 
        // Content-Type

   String version = "";
   if (st.hasMoreTokens())
    version = st.nextToken(); 
                // restliche Sendung ignorieren
 
   Connect.getInputStream().skip(
        Connect.getInputStream().available());

   try
   {
// die gefragte Datei lesen
    filename = Docroot + filename;
    File file = new File(filename);
    FileInputStream fis = new FileInputStream(filename);
    byte[] data = new byte[(int)file.length()];
    fis.read(data);
    fis.close();
// geg. Status-Zeile und Header senden
    if (version.startsWith("HTTP/1"))
    {
     os.print("HTTP/1.0 200 OK\r\n");
     os.print("Date: " +
      new HttpDate(HttpDate.getCurrentTime()) + "\r\n");
     os.print("Server: BasicHttp/1.2\r\n");
     os.print("Content-length: " + file.length() + "\r\n");
     os.print("Content-type: " + ct + "\r\n\r\n");
    }
// geg. Datei senden
    if (! method.equals("HEAD"))
     os.write(data);
    Connect.close();
   }
   catch (IOException e)
   {
// geg. File Not Found-Meldung senden
// geg. Status-Zeile und Header senden
    if (version.startsWith("HTTP/1"))
    {
     os.print("HTTP/1.0 404 File Not Found\r\n");
     os.print("Date: " +
      new HttpDate(HttpDate.getCurrentTime()) + "\r\n");
     os.print("Server: BasicHttp/1.2\r\n");
     os.print("Content-type: text/html\r\n\r\n");
    }
    os.print("<HTML><HEAD><TITLE>File Not Found</TITLE>"
     + "</HEAD><BODY><H1>HTTP Error 404: File Not Found"
        + "</H1></BODY></HTML>");

    Connect.close();
    System.err.println("Datei nicht gefunden: " + filename);
   }
  }
  catch (IOException e)
  {
   System.err.println("Unbekannter Fehler: " + e);
  }
  System.out.println("Anfrage um " + new HttpDate(
    HttpDate.getCurrentTime()));
 }
 
 public String guessContentType(String name)
 { // erraet den MIME-Type anhand der Extension
  if (name.endsWith(".html") || name.endsWith(".htm"))
    return "text/html";
  else if (name.endsWith(".txt") || name.endsWith(".java"))
    return "text/plain";
  else if (name.endsWith(".gif")) return "image/gif";
  else if (name.endsWith(".class"))
    return "application/octet-stream";
  else if (name.endsWith(".jpg") || name.endsWith(".jpeg"))
    return "image/jpeg";
  else return "text/plain";
 }
}