Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Java

Implementing a Web Server in Java

4.00/5 (2 votes)
8 Jun 2010CPOL4 min read 78.6K   4.3K  
An article on how to implement a functional web server in Java

What's A Web Server?

The Web server is the software responsible for accepting browser requests, retrieving the specified file (or executing the specified CGI, PHP, ASP script), and returning its contents (or the script's results). Most Web servers on the Internet today run on UNIX machines, although the percentage of servers on other platforms (such as Windows 95, Windows NT, and the Macintosh) is steadily increasing.

Web servers first retrieve the request using sockets, a mechanism for communicating over a network. The Web server listens for requests on a particular port on the server machine, generally port 80. By default, Web browsers use port 80 for their requests.

Once the server receives the request, it locates the document being requested. It looks for the file under the document root directory. For example, if the root is C:\AssWebSrv\htdocs, and the client requests the document /public/docs.html, then the server retrieves C:\AssWebSrv\htdocs\public\docs.html.

If the URL doesn't specify a file but just a directory, the server returns the directory index.

The server sends the contents of the file back to the client, along with some HTTP response headers. Among the data in the response headers is the media type (also known as a content type or MIME type), i.e., the format that the file is in. The way it determines the format depends on the server, but usually it comes from the suffix of the document .html is taken to be an HTML document, .pdf is assumed to be an Adobe Acrobat document, etc.

There are four major flavors of Web server:

  • The NCSA server, maintained by the National Center for Supercomputing Applications at the University of Illinois at Urbana-Champaign.
  • Apache, a variation of NCSA that has grown into the most popular Web server today.
  • The CERN server, maintained by the World Wide Web Consortium.
  • The Netscape family of servers, although the Netscape servers are commercial products.

AssoudiWebServer1.5 Mechanism's Like This

Now that we have a good description on what's a web server, let's start discovering AssoudiWebServer1.5 and its mechanisms.

AssoudiWebServer1.5 is a Web Server developed entirely in Java, as opposed to almost web servers which are developed in C language, like Apache web server.

Image 1

Figure 1: AssoudiWebSrv1.5 starting...

The client, generally a browser when it launches an HTTP request to the server, opens many sockets by each opened file, for example an HTML file that contains 10 pictures, the server must create 10 sockets to process each file. So you can ask me how the server can process many files simultaneously at the same time. The answer will naturally be, the use of threads. For each accepted request, the server must create a new thread, which processes the request and then sends the result.

Java
//
try{
	//creating a new ServerSocket Listing on SERVER_PORT 
	ServerSocket S=new ServerSocket(SERVER_PORT);
		
	try{
	while(true){
	//returning an established socket via the ServerSocket accept method 
	Socket sock=S.accept();
	try {
        System.out.println("[REMOTE HOST]: "+sock.getInetAddress().toString());
		System.out.println("[LISTNING ON PORT]: "+sock.getPort());              
            
		//calling the ServeurWeb constructor
		new ServeurWeb(sock,SERVER_ROOT,SERVER_HOMEPAGE,
				SERVER_ICONS,SERVER_LOG);
			 
		}catch ( IOException e ) {
        sock.close();//always close the socket
        }
        }
        }finally {
        S.close();//always close the ServerSocket
		}
		}catch(BindException B){
	//handling exception generated if they are already running server 
		System.out.println("SERVER Already Running");
		System.exit(0);
}
//	

ServeurWeb() is an instance of the class ServeurWeb which implements the interface Runnable. The objects of type ServeurWeb all have a run() method, the code of processing a socket comes in the body of this method. The code is located in AssoWebSrv.java file.

Java
//
//constructor ServeurWeb
class ServeurWeb implements Runnable {
public ServeurWeb(Socket s,String Sroot,String Shome,
	String Sicons,String Slog)throws UnknownHostException,IOException{
	...
	run();//invoking method run() to execute the thread code
	...
	}
}
//

Image 2

Figure 2: Server processing many requested files.

As mentioned earlier, once the server receives the request, it can either send the content of the file, if the browser request contains a requested file, or if the URL specifies just a directory, the server returns the directory index.

Image 3

Figure 3: Index of directory /public under host Zenith.
Java
//
public void Listdir(String directory,OutputStream pr,
	String HOST_NAME_LINK,String Icons_Path)throws IOException  {

 File DIR_FILE=new File(directory);

 String File_Separ_String=System.getProperty("file.separator");
 String ActualDir=this.DirectoryToList(this.getDirectory_Name());

  if(DIR_FILE.isDirectory()){
  pr.write(new String
	(""+HOST_NAME_LINK+"- /"+this.getDirectory_Name()+"").getBytes());
  String[] File_List=new String[DIR_FILE.list().length];
		
  /** File_List contain the List of files and sub directories 
contained in the current folder **/
  File_List=DIR_FILE.list();		
		...		
	}
}
//

The rest of code can be found in the FileRead.java file in package WebServer.

At this moment, our Server is not dynamic. It can just process some text, HTML, images files. A web server is said to be dynamic when it can offer to the user an interactive content. For this purpose, AssoudiWebServer1.5 supports a powerful scripting language PHP, in addition to cgi programs.

Image 4

Figure 4: AssoudiWebServer1.5 executing a PHP script.
Java
//
public void ProcessCgi(String CGI_PHPFile,OutputStream ToBrowser,int CGI_PHP )
	throws IOException{

/**
  * Method ProcessCgi according to the CGI_PHP variable ,either directly execute
  * the file if it is a cgi program or call the PHP program which 
  *executes the PHP script 
  * then send the result to the server
  */	

 Runtime r=Runtime.getRuntime();	//creating an object Runtime by calling 
				//the getRuntime Method
 String cgiContent="";		//cgiContent contain the program STDOUT
 Process p=null;			//win32 process initialised to null

 switch(CGI_PHP){
	
 case CGI_PROG:
               p=r.exec(CGI_PHPFile);
               break;
 case PHP_PROG:
			   //the php program must be under the path c:\php
               p=r.exec("C:\\php\\php.exe "+CGI_PHPFile);
               break;
	}
/*we redirect the program STDOUT  to a bufferedReader */
	
	BufferedReader brcgi=
	
	
	newBufferedReader(newInputStreamReader(p.getInputStream()));
	while((cgiContent=brcgi.readLine())!=null){
		
/**Eliminate useless data generated by the program STDOUT */	
		
		if(cgiContent.startsWith("Status")||
		   cgiContent.startsWith("Content")||
		   cgiContent.startsWith("X-Powered-By"))
		{
		
		ToBrowser.write("".getBytes());
		ToBrowser.flush();
		
		}else
		{
		//we send the data redirected from the program STDOUT to the client
		ToBrowser.write((cgiContent+"\r\n").getBytes());
		ToBrowser.flush();
		}
}
//

This code comes from the FileRead.java file in package WebServer.

As you can observe, the port number here is different from the usual port number 80. One reason to do so is to prevent having two or many servers listening on the same port number.

The port number is one from other directives that AssoudiWebServer1.5 configuration file defines, in order to be configured by the Server administrator.

  • # Directive ServerRoot holds the path of directory publication
  • # Directive Port contains the listening server number port
  • # Directive Welcome used to contain the welcome page
  • # Directive Icons contains the virtual directory name, in which Server icons are located
  • # Directive LogFile indicates the path of server log File

Conclusion

Even if AssoudiWebServer1.5 seems to be able to do almost all things needed by an efficient web Server, it still incomplete. I'm looking for adding a support for native servlets, and some security features in the next version.

A Linux version of AssoudiWebServer1.5 is (coming soon...).

For more information or suggestions, please contact me at a_othmane@hotmail.com.

By Assoudi Othmane

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)