Class CGIRequest

Object
  extended by CGIRequest

public class CGIRequest
extends Object

This class is designed to handle a CGI request on a web server. It can deal with GET and POST requests, and can deal with multipart/form-data encoding type, as might be generated with POST, particularly if Input fields of type "file" are to cause the file content to be sent. Because the action attribute of a form requires the name of a program without command-line arguments, and because a Java program is specified to a virtual machine on the command-line, it is necessary to also provide a shell script or BAT file to set the Java program running.

Unix Shell script

On a Unix system, this would be done with:


 #!/bin/sh
 java CGIRequest

 
If this file is named "java.cgi", the action field of the form would then be action="java.cgi".

Microsoft Shell script

Under Microsoft, the equivalent '.bat' file might be:


 Dim WSHShell
 Set WSHShell = WScript.CreateObject("WScript.Shell")
 cmdStr="java CGIRequest "
 Return=WshShell.Run (cmdStr,0,TRUE) 

 
If this file is named "javacgi.bat", the action field of the form would then be action="javacgi".

Older versions of Java

CGI relies on environment variables to transfer information from the request into the CGI program. Versions of Java earlier than 1.5 did not provide a reliable support for access to environment variables.

If the data in environment variables is placed in System properties by the shell script, then this class is able to use that data rather than attempting to access the environment variables directly.

Unix Shell script for old versions of Java


 #!/bin/sh

 java \
  -Dcgi.content_type="$CONTENT_TYPE" \
  -Dcgi.content_length="$CONTENT_LENGTH" \
  -Dcgi.request_method="$REQUEST_METHOD" \
  -Dcgi.query_string="$QUERY_STRING" \
  -Dcgi.server_name="$SERVER_NAME" \
  -Dcgi.server_port="$SERVER_PORT" \
  -Dcgi.script_name="$SCRIPT_NAME" \
  -Dcgi.path_info="$PATH_INFO" \
  -Dcgi.http_cookie="$HTTP_COOKIE" \
 CGIRequest

 
In this example, '\' must be the very last character on the lines. It must not be followed by a space or other non-printing character. Problems can arise if this is copied on a Microsoft system where a CR character is inserted before LF to indicate line end. CR characters in a shell script will cause this to fail.

As above, this could be named "java.cgi", and would then be referred to in a web page with action="java.cgi".

Microsoft Shell script for old versions of Java


 Dim WSHShell
 Set WSHShell = WScript.CreateObject("WScript.Shell")
 cmdStr="java "
 cmdStr=cmdStr&"-Dcgi.content_type=%CONTENT_TYPE% "
 cmdStr=cmdStr&"-Dcgi.content_length=%CONTENT_LENGTH% "
 cmdStr=cmdStr&"-Dcgi.request_method=%REQUEST_METHOD% "
 cmdStr=cmdStr&"-Dcgi.query_string=%QUERY_STRING% "
 cmdStr=cmdStr&"-Dcgi.server_name=%SERVER_NAME% "
 cmdStr=cmdStr&"-Dcgi.server_port=%SERVER_PORT% "
 cmdStr=cmdStr&"-Dcgi.script_name=%SCRIPT_NAME% "
 cmdStr=cmdStr&"-Dcgi.path_info=%PATH_INFO% " 
 cmdStr=cmdStr&"-Dcgi.http_cookie="$HTTP_COOKIE" 
 cmdStr=cmdStr&"CGIRequest "
 Return=WshShell.Run (cmdStr,0,TRUE) 

 
As above, this could be named "javacgi.bat", and would then be referred to in a web page with action="javacgi".

See http://www.microsoft.com/msdownload/vbscript/scripting.asp to download the Microsoft WSH shell.

Identifying the CGI program in the form

Within a web-page, the form must identify the program that will receive the information from the form. This must be the name of the shell script and not the name of this class file. Eg.

 <FORM method="post" action="http://www.mysite.com/cgi-bin/java.cgi">
 

Constructor

Calling the constructor will cause the environment variables to be acted upon, with the field data interpreted and placed in two Hashtables (params and files). The keys in these table are the names of the fields.

The params table contains values which are arrays of strings, the values received for each field name. These arrays will usually contain a single item, but can contain several elements for multi-valued checkboxes or for select fields. If cookies are received by the CGI program, they will be held in params under the name "http_cookies".

The files table contains values which are FileContent objects. These contain byte arrays of the raw files received from the web page, and descriptive data such as original file name.

Main program

This class contains a small main program suitable for demonstrating how the class can be used. This main program is generic, simply returning a web-page containing a table with all the information received from the form.

You will normally need to create a class containing a main program to replace the one provided here, in which you would create an instance of CGIRequest. You would then extract from params and files the data that you expect to be there, specific to the form you are working with.

See Also:

Parts of this program are based on cgi_lib.java, written by Pat L. Durante

Field Summary
 Hashtable<String,FileContent> files
          The field values from the form representing names of files are held in "files".
 Hashtable<String,String[]> params
          The simple field values from the form are held in "params".
 
Constructor Summary
CGIRequest()
          Take the input from the HTML form and convert the stream of field values into HashTables.
 
Method Summary
 FileContent getFile(String par)
          Get the file content associated with a named field received from the web form.
 String[] getParam(String par)
          Get the text associated with a named field received from the web form.
static void main(String[] arg)
          Dummy main program to show how a CGIRequest object can be used, and to provide a simple default processing of a CGI request.
static void printSafely(byte[] str)
          Print the byte array, converting any '<', '>', and '&' to entities so that they will display properly in HTML.
static StringBuffer urlDecode(byte[] in, int start, int end)
          Decode the string.
 
Methods inherited from class Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

files

public Hashtable<String,FileContent> files
The field values from the form representing names of files are held in "files".


params

public Hashtable<String,String[]> params
The simple field values from the form are held in "params". Note that the value part is an array of strings rather than a string. This enables multiple checkboxes to share the same name and for all values to be stored associated with the one name. The disadvantage is that most ordinary valuess in the Hashtable will be in arrays of size 1.

Constructor Detail

CGIRequest

public CGIRequest()
           throws Exception
Take the input from the HTML form and convert the stream of field values into HashTables. Some information will come from environment variables. Early versions of Java which do not robustly handle environment variables can still work if the data has been placed in system properties.

This will cope with GET or POST requests. The stream will be decoded assuming the data to be in the x-www-form-urlencoded form. POST data in multipart/form-data format can also be handled.

Data from the request will be placed in params and files. Cookies will be placed in params under the name http_cookies.

Throws:
Exception - if a request other than GET or POST is received, or multipart/form-data is received which lacks an associated boundary= to indicate how the parts are separated.
Method Detail

getFile

public FileContent getFile(String par)
Get the file content associated with a named field received from the web form. This will contain the raw bytes and descriptive items such as original name.

Returns:
the text string(s) associated with the field name.

getParam

public String[] getParam(String par)
Get the text associated with a named field received from the web form. Note that some field names may have more than one value, so an array of strings is returned instead of a single string.

Returns:
the text string(s) associated with the field name.

main

public static void main(String[] arg)
Dummy main program to show how a CGIRequest object can be used, and to provide a simple default processing of a CGI request.


printSafely

public static void printSafely(byte[] str)
Print the byte array, converting any '<', '>', and '&' to entities so that they will display properly in HTML.


urlDecode

public static StringBuffer urlDecode(byte[] in,
                                     int start,
                                     int end)
Decode the string.

First, '+' characters are replaced by a space.

Then, '%' and the following two hexadecimal digits are replaced by the character they represent.

Returns:
the decoded string, which will be no longer than the original.