import java.util.*; import java.net.URLDecoder; /** * This small class "unpacks" the environment variables that are input to * CGI scripts. *

* Please note that since environment variables aren't accessible from Java, the * environment variables PATH_INFO, QUERY_STRING, and CONTENT_LENGTH always must be * passed as parameters to the contructors of this class. This can be done by e.g. * using a Unix Shell Script as wrapper. *

* Example, Unix Shell Script wrapper file: *

*
* #!/bin/sh *
cd /YourDomain/cgi-bin *
/usr/local/jdk/bin/java CgiParser "$PATH_INFO" "$QUERY_STRING" "$CONTENT_LENGTH" *
*

* Some Class features: *

*/ public class CgiParser { private Vector path = new Vector(); private Properties params = new Properties(); private static String noTags(String s) { for (int i = s.indexOf('<'); i >= 0; i = s.indexOf('<')) s = s.substring(0,i)+"<"+s.substring(i+1); for (int i = s.indexOf('>'); i >= 0; i = s.indexOf('>')) s = s.substring(0,i)+">"+s.substring(i+1); return s; } private void tokenizePath(String pathInfo) { StringTokenizer st = new StringTokenizer(pathInfo,"/"); while (st.hasMoreTokens()) try { path.add(URLDecoder.decode(st.nextToken())); } catch (Exception e) {} } private void tokenizeQuery(String query) { StringTokenizer st = new StringTokenizer(query,"&/"); while (st.hasMoreTokens()) { String s = st.nextToken(); int i = s.indexOf("="); if (i > 0) try { params.setProperty(s.substring(0,i),URLDecoder.decode(s.substring(i+1))); } catch (Exception e) {} } } /** * Construct a CGI Parser and parse the environment variables. *

* @param pathInfo environment variable PATH_INFO * @param queryString environment variable QUERY_STRING * @param contentLength environment variable CONTENT_LENGTH */ public CgiParser(String pathInfo, String queryString, String contentLength) { this(pathInfo, queryString, contentLength, false); } /** * Construct a CGI Parser and parse the environment variables. *

* @param pathInfo environment variable PATH_INFO * @param queryString environment variable QUERY_STRING * @param contentLength environment variable CONTENT_LENGTH * @param pathParams when true, if the PATH_INFO elements contain * parameter/value pairs (e.g. http://a.com/cgi-bin/b.sh/x=1/y=2/ * i.e. x = 1 and y = 2) those elements will be handled * exactly as the parameter/value pairs in QUERY_STRING and content. */ public CgiParser(String pathInfo, String queryString, String contentLength, boolean pathParams) { try { int l = new Integer(contentLength).intValue(); byte[] b = new byte[l]; System.in.read(b,0,l); tokenizeQuery(new String(b)); } catch (Exception e) {} if (queryString != null) tokenizeQuery(queryString); if (pathInfo != null) { if (pathParams) tokenizeQuery(pathInfo); tokenizePath(pathInfo); } } /** * Returns Enumeration containing the QUERY_STRING or content (or PATH_INFO) parameter names. *

* Example: The URL being http://a.com/cgi-bin/b.sh?x=1&y=2 or the content * being "x=1&y=2", the resulting Enumeration will contain the strings "x" and "y". *
           * Provided that the CgiParser was constructed with pathParams * set to true, the URL http://a.com/cgi-bin/b.sh/x=1/y=2 will yield the * same result. Also, in that case any PATH_INFO/QUERY_STRING/content * parameter/value pair combination works perfectly Ok, e.g. for the URL * http://a.com/cgi-bin/b.sh/x=1/y=2?z=3&t=4 with the content being "v=5&w=6", * the resulting Enumeration will contain "x", "y", "z", "t", "v", and "w"; where * "x" and "y" come from PATH_INFO, "z" and "t" come from QUERY_STRING, * and "v" and "w" come from content. *

* The basic idea of usage is: *

     *     for (Enumeration e = cgiParser.getParams(); e.hasMoreElements();) {
     *         String param = (String)e.nextElement();
     *         String value = cgiParser.getParamValue(param);
     *         // Do something with param and/or value
     *     }
     * 
*

* @return Enumeration containing the parameter names * */ public Enumeration getParams() { return params.propertyNames(); } /** * Returns value of named parameter as posted in QUERY_STRING or content (or PATH_INFO). *

* Example: The URL being http://a.com/cgi-bin/b.sh?x=1&y=2 or the * content being "x=1&y=2", getParamValue("x") will return "1" and * getParamValue("y") will return "2" (always as a String, n.b.) *
           * If the CgiParser was constructed with pathParams set to true, the URL * http://a.com/cgi-bin/b.sh/x=1/y=2 will also yield * getParamValue("x") returning "1" and getParamValue("y") returning "2". *

* @param param parameter name *

* @return value of named parameter (null if not found) */ public String getParamValue(String param) { return params.getProperty(param); } /** * Returns number of PATH_INFO elements. *

* Example: The URL being http://a.com/cgi-bin/b.sh/x/y/z/t, pathSize returns 4. *

* @return number of PATH_INFO elements */ public int pathSize() { return path.size(); } /** * Returns the PATH_INFO element of the specified index. *

* Example: The URL being http://a.com/cgi-bin/b.sh/x/y/z/t, * pathAt(2) returns "z". *

* @param index index, from 0 to pathSize()-1 *

* @return PATH_INFO element of the specified index */ public String pathAt(int index) { return (String)path.get(index); } /** * Returns the index of the PATH_INFO element, or -1 if element not in PATH_INFO. *

* Example: The URL being http://a.com/cgi-bin/b.sh/x/y/z/t, * pathIndex("z") returns 2, and pathIndex("q") returns -1. *

* @param s element id *

* @return index of the PATH_INFO element, or -1 if element not found in PATH_INFO */ public int pathIndex(String s) { for (int i = 0; i < pathSize(); i++) if (s.equals(pathAt(i))) return i; return -1; } /** * Returns true if PATH_INFO contains such an element. *

* Example: The URL being http://a.com/cgi-bin/b.sh/x/y/z/t, * inPath("z") returns true, and inPath("q") returns false. *

* @param s element id *

* @return true if PATH_INFO contains such an element, false otherwise */ public boolean inPath(String s) { return pathIndex(s) >= 0; } /** * Test program, printing a HTML page to java.lang.System.out (as "CGI output"). *

* This program needs to be wrapped in e.g. a Unix Shell Script. *

* @param args[0] environment variable PATH_INFO * @param args[1] environment variable QUERY_STRING * @param args[2] environment variable CONTENT_LENGTH */ public static void main(String[] args) { System.out.println("Content-type: text/html"); System.out.println(""); System.out.println(""); System.out.println("PATH_INFO: "+(args.length > 0? args[0]: "")); System.out.println("
"); System.out.println("QUERY_STRING: "+(args.length > 1? args[1]: "")); System.out.println("
"); System.out.println("CONTENT_LENGTH: "+(args.length > 2? args[2]: "")); CgiParser cgiParser = new CgiParser( args.length > 0? args[0]: null, args.length > 1? args[1]: null, args.length > 2? args[2]: null, true ); System.out.println("

Path:"); System.out.println("

"); System.out.println("

Parameter Values:"); System.out.println("

"); System.out.println(""); } }