next up previous contents
Next: Apache Up: Web Servers Previous: Universal Resource   Contents

A Trivial Web Server

This is a trivial web server. It is composed of two classes. The first class, called WebServer, has only a main method. The main method will create a new copy of the getRequest method to handle HTTP GET requests.

A web server is only required to implement GET requests. All of the other HTTP commands are optional.

You can run this code by typing:

  javac WebServer.java
  java WebServer

From another terminal on the same machine you can ask for files thus:

  telnet 127.0.0.1 80
  GET /WebServer.java

The telnet command establishes a TCP/IP connection to the local machine (127.0.0.1 is the default IP address of ``this machine'') and connects to port 80, the HTTP server port.

The ``GET /WebServer.java'' command says that we want to get the file called ``WebServer.java'' in the current directory.

The main method creates a new getRequest class as a new thread to handle this request. The getRequest routine changes the filename to read ``./WebServer.java'' so we look in the current directory. The console trace on the WebServer machine will look like (lines with ``$==>$'' are from you, lines with ``$<==$'' are what WebServer typed):

New connection accepted /127.0.0.1:49250
==>GET /WebServer.java 
<==HTTP/1.0 200 OK
<==WebServer
<==Content-type: text/plain
<==Content-Length: 4045
<==
<== 200: file sent: ./WebServer.java

We can also use a web browser to connect by typing:

  http://127.0.0.1/WebServer.java
in the location input box of your browser. Note that the browser sends all kinds of additional information besides the GET command.
New connection accepted /127.0.0.1:49250
==>GET /WebServer.java HTTP/1.1
<==HTTP/1.0 200 OK
<==WebServer
<==Content-type: text/plain
<==Content-Length: 4045
<==
<== 200: file sent: ./WebServer.java
==>Host: 127.0.0.1
==>User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.2.1) Gecko/20030225
==>Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,video/x-mng,image/png,image/jpeg,image/gif;q=0.2,text/css,*/*;q=0.1
==>Accept-Language: en-us, en;q=0.50
==>Accept-Encoding: gzip, deflate, compress;q=0.9
==>Accept-Charset: ISO-8859-1, utf-8;q=0.66, *;q=0.66
==>Keep-Alive: 300
==>Connection: keep-alive
==>

Note the glaring security hole. We could ask for something like

   GET /../filename
The WebServer will let you fetch any file you can reach. Don't use this code as a real web server. In fact, this is a standard attack on Microsoft web servers. You simply ask for files anywhere on the machine. A lot of the servers are badly configured and will download any file on your Microsoft machine.
import java.io.*;
import java.lang.*;
import java.net.*;
import java.util.*;

public class WebServer 
{
 
 public static void main(String args[]) 
 { ServerSocket sock;
   try 
   { sock = new ServerSocket(80);
     System.out.println("WebServer started");
     while(true) 
     { Socket socket = sock.accept();
       System.out.println("New connection accepted " +
           socket.getInetAddress() + ":" + socket.getPort());
       try 
       { getRequest request =  new getRequest(socket);
         Thread thread = new Thread(request);
         thread.start();
       }
       catch(Exception e) 
       { e.printStackTrace();
       }
     }
   }
   catch (Exception e) 
   { e.printStackTrace();
   }
 }
}
        
class getRequest implements Runnable
{ String CRLF = "\r\n";
  Socket sock;
  InputStream input;
  OutputStream output;
  BufferedReader bin;

  public getRequest(Socket s) throws Exception 
  { this.sock = s;
    this.input = s.getInputStream();
    this.output = s.getOutputStream();
    this.bin= new BufferedReader(new InputStreamReader(s.getInputStream()));
  }
    
  public void run()
  { while(true) 
    { try
      { String GETline = bin.readLine();
        System.out.println("==>"+GETline);
        if(GETline.equals(CRLF) || GETline.equals("")) break;
        StringTokenizer s = new StringTokenizer(GETline);
        String temp = s.nextToken();
        if(temp.equals("GET")) 
        { String filename = s.nextToken();
          filename = "." + filename ;
          FileInputStream inFile = null ;
          boolean fileExists = true ;
          try 
          { inFile = new FileInputStream( filename ) ;
          } 
          catch ( FileNotFoundException e ) 
          { fileExists = false ;
          }
          String serverln = "WebServer"+CRLF;
          String statusln = null;
          String contentTypeln = null;
          String FourOFour = null;
          String contentLengthln = "error";
          String mime="text/html";
          if (!(filename.endsWith(".html")))
            mime="text/plain";
          if (fileExists)
          { statusln = "HTTP/1.0 200 OK" + CRLF ;
            contentTypeln = "Content-type: "+mime+CRLF;
            contentLengthln = "Content-Length: " +
               (new Integer(inFile.available())).toString() + CRLF;
          }
          else
          { statusln = "HTTP/1.0 404 Not Found" + CRLF ;
            contentTypeln = "Content-type: " + "text/html" + CRLF;
            FourOFour = 
             "<HTML>" + 
             " <HEAD>" +
             "  <TITLE>" +
             "   404 Not Found" +
             "  </TITLE>" +
             " </HEAD>" +
             " <BODY>"+
             "  404 Not Found "+filename+
             " </BODY>"+
             "</HTML>";
            contentLengthln = "Content-Length: " +
               (new Integer(FourOFour.length())).toString() + CRLF;
          }
          output.write(statusln.getBytes());
          System.out.print("<=="+statusln);
          output.write(serverln.getBytes());
          System.out.print("<=="+serverln);
          output.write(contentTypeln.getBytes());
          System.out.print("<=="+contentTypeln);
          output.write(contentLengthln.getBytes());
          System.out.print("<=="+contentLengthln);
          output.write(CRLF.getBytes());
          System.out.print("<=="+CRLF);
          System.out.flush();
          if (fileExists)
          { byte[] buffer = new byte[1024] ;
            int bytes = 0 ;
            while ((bytes = inFile.read(buffer)) != -1 ) 
            { output.write(buffer, 0, bytes);
            }
            inFile.close();
            System.out.println("<== 200: file sent: "+filename);
          }
          else
          { output.write(FourOFour.getBytes());
            System.out.println("<== 404: not found: "+filename);
          }
        }
      }
      catch(Exception e)
      { e.printStackTrace();
      }
    }
    try 
    { output.close();
      bin.close();
      sock.close();
    }
    catch(Exception e) {}
  }

}

next up previous contents
Next: Apache Up: Web Servers Previous: Universal Resource   Contents
root 2004-02-18