\r
import java.io.BufferedOutputStream;\r
import java.io.BufferedReader;\r
-import java.io.ByteArrayOutputStream;\r
import java.io.File;\r
import java.io.FileOutputStream;\r
import java.io.IOException;\r
import java.io.InputStream;\r
import java.io.InputStreamReader;\r
import java.io.OutputStream;\r
-import java.net.URLEncoder;\r
+import java.io.UnsupportedEncodingException;\r
+import java.net.URLDecoder;\r
import java.util.ArrayList;\r
import java.util.Date;\r
import java.util.Enumeration;\r
*\r
* @author Martin T Dengler [root@martindengler.com]\r
* @author Amy Roh\r
- * @version $Revision: 383693 $, $Date: 2006-03-06 23:16:24 +0100 (lun., 06 mars 2006) $\r
+ * @version $Revision: 421476 $, $Date: 2006-07-12 22:08:28 -0400 (Wed, 12 Jul 2006) $\r
* @since Tomcat 4.0\r
*\r
*/\r
* <p>\r
* </p>\r
*\r
- * @version $Revision: 383693 $, $Date: 2006-03-06 23:16:24 +0100 (lun., 06 mars 2006) $\r
+ * @version $Revision: 421476 $, $Date: 2006-07-12 22:08:28 -0400 (Wed, 12 Jul 2006) $\r
* @since Tomcat 4.0\r
*\r
*/\r
/** cgi command's desired working directory */\r
private File workingDirectory = null;\r
\r
- /** cgi command's query parameters */\r
- private ArrayList queryParameters = new ArrayList();\r
+ /** cgi command's command line parameters */\r
+ private ArrayList cmdLineParameters = new ArrayList();\r
\r
/** whether or not this object is valid or not */\r
private boolean valid = false;\r
setupFromContext(context);\r
setupFromRequest(req);\r
\r
- Enumeration paramNames = req.getParameterNames();\r
- while (paramNames != null && paramNames.hasMoreElements()) {\r
- String param = paramNames.nextElement().toString();\r
- if (param != null) {\r
- String values[] = req.getParameterValues(param);\r
- for (int i=0; i < values.length; i++) {\r
- String value = URLEncoder.encode(values[i],\r
- parameterEncoding);\r
- NameValuePair nvp = new NameValuePair(param, value);\r
- queryParameters.add(nvp);\r
- }\r
- }\r
- }\r
-\r
this.valid = setCGIEnvironment(req);\r
\r
if (this.valid) {\r
*\r
* @param req HttpServletRequest for information provided by\r
* the Servlet API\r
+ * @throws UnsupportedEncodingException \r
*/\r
- protected void setupFromRequest(HttpServletRequest req) {\r
+ protected void setupFromRequest(HttpServletRequest req)\r
+ throws UnsupportedEncodingException {\r
+ \r
this.contextPath = req.getContextPath();\r
this.servletPath = req.getServletPath();\r
this.pathInfo = req.getPathInfo();\r
if (this.pathInfo == null) {\r
this.pathInfo = this.servletPath;\r
}\r
+ \r
+ // If request is HEAD or GET and Query String does not contain\r
+ // an unencoded "=" this is an indexed query. Parsed Query String\r
+ // forms command line parameters for cgi command.\r
+ if (!"GET".equals(req.getMethod()) &&\r
+ !"HEAD".equals(req.getMethod()))\r
+ return;\r
+ \r
+ String qs = req.getQueryString();\r
+ \r
+ if (qs == null || qs.indexOf("=")>0)\r
+ return;\r
+ \r
+ int delimIndex = 0;\r
+ int lastDelimIndex = 0;\r
+ delimIndex = qs.indexOf("+");\r
+ \r
+ while (delimIndex >0) {\r
+ cmdLineParameters.add(URLDecoder.decode(qs.substring(\r
+ lastDelimIndex,delimIndex),parameterEncoding));\r
+ lastDelimIndex = delimIndex + 1;\r
+ delimIndex = qs.indexOf("+",lastDelimIndex);\r
+ }\r
+ cmdLineParameters.add(URLDecoder.decode(qs.substring(\r
+ lastDelimIndex),parameterEncoding));\r
}\r
\r
\r
-\r
/**\r
* Resolves core information about the cgi script.\r
*\r
}\r
sb.append("</td></tr>");\r
\r
- sb.append("<tr><td colspan=2>Query Params</td></tr>");\r
- for (int i=0; i < queryParameters.size(); i++) {\r
- NameValuePair nvp = (NameValuePair) queryParameters.get(i);\r
- sb.append("<tr><td>");\r
- sb.append(nvp.getName());\r
- sb.append("</td><td>");\r
- sb.append(nvp.getValue());\r
- sb.append("</td></tr>");\r
+ sb.append("<tr><td>Command Line Params</td><td>");\r
+ for (int i=0; i < cmdLineParameters.size(); i++) {\r
+ String param = (String) cmdLineParameters.get(i);\r
+ sb.append("<p>");\r
+ sb.append(param);\r
+ sb.append("</p>");\r
}\r
+ sb.append("</td></tr>");\r
\r
sb.append("</TABLE><p>end.");\r
\r
*\r
*/\r
protected ArrayList getParameters() {\r
- return queryParameters;\r
+ return cmdLineParameters;\r
}\r
\r
\r
* and <code>setResponse</code> methods, respectively.\r
* </p>\r
*\r
- * @version $Revision: 383693 $, $Date: 2006-03-06 23:16:24 +0100 (lun., 06 mars 2006) $\r
+ * @version $Revision: 421476 $, $Date: 2006-07-12 22:08:28 -0400 (Wed, 12 Jul 2006) $\r
*/\r
\r
protected class CGIRunner {\r
/** working directory used when invoking the cgi script */\r
private File wd = null;\r
\r
- /** query parameters to be passed to the invoked script */\r
+ /** command line parameters to be passed to the invoked script */\r
private ArrayList params = null;\r
\r
/** stdin to be passed to cgi script */\r
* @param command string full path to command to be executed\r
* @param env Hashtable with the desired script environment\r
* @param wd File with the script's desired working directory\r
- * @param params ArrayList with the script's query parameters as\r
- * NameValuePairs\r
+ * @param params ArrayList with the script's query command line\r
+ * paramters as strings\r
*/\r
protected CGIRunner(String command, Hashtable env, File wd,\r
ArrayList params) {\r
\r
for (int i=0; i < params.size(); i++) {\r
cmdAndArgs.append(" ");\r
- NameValuePair nvp = (NameValuePair) params.get(i); \r
- String k = nvp.getName();\r
- String v = nvp.getValue();\r
- if ((k.indexOf("=") < 0) && (v.indexOf("=") < 0)) {\r
- StringBuffer arg = new StringBuffer(k);\r
- arg.append("=");\r
- arg.append(v);\r
- if (arg.toString().indexOf(" ") < 0) {\r
- cmdAndArgs.append(arg);\r
- } else {\r
- // Spaces used as delimiter, so need to use quotes\r
- cmdAndArgs.append("\"");\r
- cmdAndArgs.append(arg);\r
- cmdAndArgs.append("\"");\r
- }\r
+ String param = (String) params.get(i);\r
+ if (param.indexOf(" ") < 0) {\r
+ cmdAndArgs.append(param);\r
+ } else {\r
+ // Spaces used as delimiter, so need to use quotes\r
+ cmdAndArgs.append("\"");\r
+ cmdAndArgs.append(param);\r
+ cmdAndArgs.append("\"");\r
}\r
}\r
\r
command.append(cmdAndArgs.toString());\r
cmdAndArgs = command;\r
\r
- String sContentLength = (String) env.get("CONTENT_LENGTH");\r
- ByteArrayOutputStream contentStream = null;\r
- if(!"".equals(sContentLength)) {\r
- byte[] content = new byte[Integer.parseInt(sContentLength)];\r
-\r
- // Bugzilla 32023\r
- int lenRead = 0;\r
- do {\r
- int partRead = stdin.read(content,lenRead,content.length-lenRead);\r
- lenRead += partRead;\r
- } while (lenRead > 0 && lenRead < content.length);\r
-\r
- contentStream = new ByteArrayOutputStream(\r
- Integer.parseInt(sContentLength));\r
- if ("POST".equals(env.get("REQUEST_METHOD"))) {\r
- String paramStr = getPostInput(params);\r
- if (paramStr != null) {\r
- byte[] paramBytes = paramStr.getBytes();\r
- contentStream.write(paramBytes);\r
-\r
- int contentLength = paramBytes.length;\r
- if (lenRead > 0) {\r
- String lineSep = System.getProperty("line.separator");\r
- contentStream.write(lineSep.getBytes());\r
- contentLength = lineSep.length() + lenRead;\r
- }\r
- env.put("CONTENT_LENGTH", Integer.toString(contentLength));\r
- }\r
- }\r
-\r
- if (lenRead > 0) {\r
- contentStream.write(content, 0, lenRead);\r
- }\r
- contentStream.close();\r
- }\r
-\r
rt = Runtime.getRuntime();\r
proc = rt.exec(cmdAndArgs.toString(), hashToStringArray(env), wd);\r
\r
- if(contentStream != null) {\r
+ String sContentLength = (String) env.get("CONTENT_LENGTH");\r
+\r
+ if(!"".equals(sContentLength)) {\r
commandsStdIn = new BufferedOutputStream(proc.getOutputStream());\r
- commandsStdIn.write(contentStream.toByteArray());\r
+ IOTools.flow(stdin, commandsStdIn);\r
commandsStdIn.flush();\r
commandsStdIn.close();\r
}\r
log("runCGI: " + lineCount + " lines received on stderr") ;\r
} ;\r
}\r
-\r
-\r
- /**\r
- * Gets a string for input to a POST cgi script\r
- *\r
- * @param params ArrayList of query parameters to be passed to\r
- * the CGI script\r
- * @return for use as input to the CGI script\r
- */\r
-\r
- protected String getPostInput(ArrayList params) {\r
- StringBuffer qs = new StringBuffer("");\r
- for (int i=0; i < params.size(); i++) {\r
- NameValuePair nvp = (NameValuePair) this.params.get(i); \r
- String k = nvp.getName();\r
- String v = nvp.getValue();\r
- if ((k.indexOf("=") < 0) && (v.indexOf("=") < 0)) {\r
- qs.append(k);\r
- qs.append("=");\r
- qs.append(v);\r
- qs.append("&");\r
- }\r
- }\r
- if (qs.length() > 0) {\r
- // Remove last "&"\r
- qs.setLength(qs.length() - 1);\r
- return qs.toString();\r
- } else {\r
- return null;\r
- }\r
- }\r
} //class CGIRunner\r
\r
/**\r
- * This is a simple class for storing name-value pairs.\r
- * \r
- * TODO: It might be worth moving this to the utils package there is a\r
- * wider requirement for this functionality.\r
- */\r
- protected class NameValuePair {\r
- private String name;\r
- private String value;\r
- \r
- NameValuePair(String name, String value) {\r
- this.name = name;\r
- this.value = value;\r
- }\r
- \r
- protected String getName() {\r
- return name;\r
- }\r
- \r
- protected String getValue() {\r
- return value;\r
- }\r
- }\r
-\r
- /**\r
* This is an input stream specifically for reading HTTP headers. It reads\r
* upto and including the two blank lines terminating the headers. It\r
* allows the content to be read using bytes or characters as appropriate.\r