Listing 1: CGI.java
// CGI framework class
import java.io.PrintStream;
import java.io.InputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Vector;
import java.util.Hashtable;
import java.util.Properties;
import java.util.StringTokenizer;
public class CGI {
public static void main(String[] argv) {
CGI cgi = new CGI();
cgi.handle(argv);
}
protected PrintStream outputStream = System.out;
// basic logic for handling a request
protected void handle(String[] argv) {
printHeader(); // make sure that the header gets out
// at least, so that any error messages
// will be displayedin the browser
try {
if (argv.length > 0) { // are there variables on the command line?
setupVariables(argv);
}
else {
setupVariables();
}
printBody();
}
catch (Exception e) { // output error message in case of Exception
outputStream.println("Error: " + e);
}
outputStream.println("</HTML>");
}
protected void printHeader() {
outputStream.println("Content-type: text/html\n");
outputStream.println("<HTML>");
}
// default printBody, prints out all of the CGI variables
protected void printBody() throws Exception {
outputStream.println("<HEAD><TITLE>Variables</TITLE></HEAD>");
outputStream.println("<H2>Variables</H2><P>");
outputStream.println("<PRE>");
Enumeration e = getVariables();
while(e.hasMoreElements()) {
String key = (String) e.nextElement();
Enumeration valuesEnum = getValues(key);
while (valuesEnum.hasMoreElements()) {
outputStream.println(key + " = " + valuesEnum.nextElement());
}
}
outputStream.println("</PRE>");
outputStream.println("</BODY>");
}
// gets a header (environment) variable
public String getHeader(String name) {
String result = System.getProperty(name);
if (result == null) {
result = "";
}
return result;
}
// get request method, either GET or POST
public String getMethod() {
return getHeader("REQUEST_METHOD");
}
// return the value associate with a variable name
// if there are multiple values, return the first value
// if there is no value, return the empty string
public String getValue(String name) {
if (variables != null) {
Enumeration enum = getValues(name);
if (enum.hasMoreElements()) {
return (String) enum.nextElement();
}
}
return "";
}
// get all of the values associated with a variable name
// returning an Enumeration so that they can be iterated over
public Enumeration getValues(String name) {
Object o = variables.get(name);
if ((o != null) && (o instanceof Vector)) {
return ((Vector)o).elements();
}
Vector v = new Vector();
if (o != null) {
v.addElement(o);
}
return v.elements();
}
// has the variable been assigned any value?
public boolean hasValue(String name) {
Object o = variables.get(name);
return (o != null);
}
public boolean hasMultipleValues(String name) {
Object o = variables.get(name);
return ((o != null) && (o instanceof Vector));
}
// return an Enumeration of all of the variables that
// have been defined
public Enumeration getVariables() {
return variables.keys();
}
// save a variable/value pair,or if the variable already
// has a value, add another value to the variable. Primarily used
// by setupVariables() (see above), this can also be used
// by subclass code for temporary variable storage
public void setValue(String name, String value) {
Object o = variables.get(name);
if (o != null) {
if (o instanceof Vector) {
((Vector)o).addElement(value);
}
else {
Vector v = new Vector();
v.addElement(o);
v.addElement(value);
variables.put(name,v);
}
}
else {
variables.put(name,value);
}
}
//----------------------------------------------------------------
// private variables and methods
//----------------------------------------------------------------
private String queryString = "";
private Hashtable variables = new Hashtable(); // internal storage
// of variables
private InputStream inputStream = System.in;
// gets the QUERY_STRING from the environment variable or from
// standard input (if POST), and set up the variables
private void setupVariables() {
if (System.getProperty("QUERY_STRING") != null) {
queryString = System.getProperty("QUERY_STRING");
}
int requestContentLength = 0;
if (System.getProperty("CONTENT_LENGTH") != null) {
try {
requestContentLength = \
Integer.parseInt(System.getProperty("CONTENT_LENGTH"));
}
catch (NumberFormatException nfe) {
}
}
try {
if ((getHeader("REQUEST_METHOD").equals("POST")) && \
(requestContentLength > 0)) {
byte[] b = new byte[requestContentLength];
int count = inputStream.read(b); // read variables from
// standard input
queryString = new String(b,0,0,count);
}
}
catch (IOException e) {
queryString = "";
}
createVariables();
}
// sets variables up by getting the arguments from the command line
// useful for invoking the CGI from command line for testing
private void setupVariables(String[] argv) {
int firstArg = 0;
Properties properties = new Properties(System.getProperties());
StringBuffer b = new StringBuffer();
for (int i = firstArg; i < argv.length; i++) {
if (argv[i].startsWith("-H")) { // handle "fake"
// environment variables
int equalIndex = argv[i].indexOf("=");
if (equalIndex >= 0) {
properties.put(argv[i].substring(2,equalIndex),
argv[i].substring(equalIndex+1));
}
}
else { // add argument to the query string
if (b.length() > 0) { b.append("&"); }
b.append(argv[i]);
}
}
queryString = b.toString();
createVariables();
System.setProperties(properties); // add "fake" environment
// to System properties
}
// takes a query string and creates variables and values from them
private void createVariables() {
if (queryString == null) { return; }
// split up the string along "&" characters
StringTokenizer tokenizer = new StringTokenizer(queryString, "&");
while (tokenizer.hasMoreTokens()) {
String pair = decodeString(tokenizer.nextToken());
int equalIndex = pair.indexOf('='); // split into key and
// value components
if ((equalIndex >= 0) && (pair.length() != (equalIndex + 1))) {
setValue(pair.substring(0,equalIndex),pair.substring(equalIndex + 1));
}
}
}
// query strings encode special characters as "%XX", where XX is
// the hexidecimal character number of the character. In addition,
// an "+" character is mapped to a space
private String decodeString(String s) {
// decode arguments
StringBuffer b = new StringBuffer(s.length());
int i = 0;
while (i < s.length()) {
char c = s.charAt(i++);
if (c == '+') {
c = ' ';
}
else if (c == '%') {
try {
char c1 = s.charAt(i++);
char c2 = s.charAt(i++);
c = (char) Integer.parseInt(""+c1+c2,16);
}
catch (NumberFormatException e) {
}
}
b.append(c);
}
return b.toString();
}
}
// End of File
|