Roger L. Kraft

CS 40400 / CS 59000-01 - Programming Assignment 3

This assignment is due Thursday, December 5.

In this homework assignment you will add two features to the HTTP web server discussed in class.

Download this zip file.

In the zip file there is a copy of the Java web sever discussed in class. But in the zip file the code has been somewhat artificially broken up into three files. This is to make it easier to grade your work. Your assignment is to add two features to the web server, dynamic directory listings, and the CGI GET method. The code for the dynamic directory listing should go in the file DoDynDirListing.java and the code for the CGI GET method should go in the file DoCGIGet.java (right now, those two files in the zip file contain stub functions that just return error responses). Below are detailed descriptions of each of these two new features.

The DoDynDirListing.java file contains a single method, doDynDirListing(). This method should have a structure similar to the method sendErrorResponse(). Both methods build a string that is the response entity body, then they build the response line and headers, and then they send the response to the client.

In the case of doDynDirListing(), the response body is a HTML table where each row of the table is a HTML hyperlink to one file from the directory listing. To get the files in the directory, use the listFiles() method from the File class. This method returns an array of File objects, and you can use the getName() method from the File class to get each file's name. In the zip file there is a screen shot, DirectoryListing.png, of what a directory listing should look like. The HTML for a line of the directory listing should look like this.

     <tr><td><a href="/dynamic.html">dynamic.html</a></td></tr>

Notice that the first "file" listed in the directory listing should be a link to the folder's parent folder. If you want to get a feel for how directory listings are supposed to work, run the Mongoose webserver and use it to look at some directory listings. When you use a browser to view a directory listing produced by Mongoose, be sure to use the browser's "View Source" feature to see what the HTML code produced by Mongoose looks like.

The DoCGIGet.java file contains a single method, doCGIGet(). Writing this method is another exercise in inter-process communication (as in the two previous homework assignments). The doCGIGet() method is supposed to start a CGI process as a child process of the web server, communicate information to this child process (using environment variables), and redirect the child's stdout so that the child process can communicate with the HTTP client process (the web browser).

Since the web server communicates with its child CGI process using environment variables, we need a way for a Java program to set environment variables. In the Java System class, there is a method getenv() that will get the value of an environment variable, but there is not "setenv()" method for setting environment variables. The reason is that, in the Java philosophy of processes, no Java process should be allowed to change its own environment variables. But a Java process is allowed to modify the environment of a child process that it is about to create. So Java has a way of setting environment variables only in the class for creating child processes, the ProcessBuilder class. The environment() method lets you get a Map<String,String> of the child's environment, and then you can use the Map class's put() method to insert a new environment variable into the child's environment.

There are two environment variables that doCGIGet() must set before it starts the child process. The two are REQUEST_METHOD and QUERY_STRING. For the case of doCGIGet(), the request method is GET and the query string is passed to doCGIGet() as a parameter. (There are many other CGI environment variables, but these are the only two that doCGIGet() must set.)

After you start the child process (using the start() method), you need to redirect the child's standard output to the stream outToClient, which is one of the parameters for doCGIGet(). You need to do this with one of the "pumps" that was used in the previous two homework assignments. This situation is almost exactly the same as the examples from the folder 5. Redirect Child's Standard Streams from the zip file Inter-Process Communication.zip (look at the file Java6_RedirectChildStdinStdoutToFiles_ver3.java).

Inter-process communication is always tricky to debug. Notice that in the file DoCGIGet.java there is a main() method. This lets you run, and test, your doCGIGet() method without having to run the method from within the web server. Also, within the hw3/html/cgi-bin directory there is a program adder_win32.exe that makes the CGI process sleep for three minutes. This gives you enough time to use a program like ProcessHacker to examine the environment variables of the running child process, to make sure that the two needed CGI environment variables are set correctly.

Turn in a zip file called CS404Hw3Surname.zip containing the three files CS404Hw3HTTPServer.java, DoDynDirListing.java, and DoCGIGet.java. Please remember to put your name inside of each of your source files.

This assignment is due Thursday, December 5.