[jboss-svn-commits] JBL Code SVN: r6010 - in labs/jbossweb/trunk/src/share/classes/org/apache/catalina: servlets ssi
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Tue Aug 29 17:45:54 EDT 2006
Author: remy.maucherat at jboss.com
Date: 2006-08-29 17:45:52 -0400 (Tue, 29 Aug 2006)
New Revision: 6010
Modified:
labs/jbossweb/trunk/src/share/classes/org/apache/catalina/servlets/CGIServlet.java
labs/jbossweb/trunk/src/share/classes/org/apache/catalina/ssi/SSIProcessor.java
Log:
- Port patches for CGI and SSI.
Modified: labs/jbossweb/trunk/src/share/classes/org/apache/catalina/servlets/CGIServlet.java
===================================================================
--- labs/jbossweb/trunk/src/share/classes/org/apache/catalina/servlets/CGIServlet.java 2006-08-29 21:41:31 UTC (rev 6009)
+++ labs/jbossweb/trunk/src/share/classes/org/apache/catalina/servlets/CGIServlet.java 2006-08-29 21:45:52 UTC (rev 6010)
@@ -19,14 +19,14 @@
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
-import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
-import java.net.URLEncoder;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
@@ -741,8 +741,8 @@
/** cgi command's desired working directory */
private File workingDirectory = null;
- /** cgi command's query parameters */
- private ArrayList queryParameters = new ArrayList();
+ /** cgi command's command line parameters */
+ private ArrayList cmdLineParameters = new ArrayList();
/** whether or not this object is valid or not */
private boolean valid = false;
@@ -763,20 +763,6 @@
setupFromContext(context);
setupFromRequest(req);
- Enumeration paramNames = req.getParameterNames();
- while (paramNames != null && paramNames.hasMoreElements()) {
- String param = paramNames.nextElement().toString();
- if (param != null) {
- String values[] = req.getParameterValues(param);
- for (int i=0; i < values.length; i++) {
- String value = URLEncoder.encode(values[i],
- parameterEncoding);
- NameValuePair nvp = new NameValuePair(param, value);
- queryParameters.add(nvp);
- }
- }
- }
-
this.valid = setCGIEnvironment(req);
if (this.valid) {
@@ -807,8 +793,11 @@
*
* @param req HttpServletRequest for information provided by
* the Servlet API
+ * @throws UnsupportedEncodingException
*/
- protected void setupFromRequest(HttpServletRequest req) {
+ protected void setupFromRequest(HttpServletRequest req)
+ throws UnsupportedEncodingException {
+
this.contextPath = req.getContextPath();
this.servletPath = req.getServletPath();
this.pathInfo = req.getPathInfo();
@@ -817,10 +806,34 @@
if (this.pathInfo == null) {
this.pathInfo = this.servletPath;
}
+
+ // If request is HEAD or GET and Query String does not contain
+ // an unencoded "=" this is an indexed query. Parsed Query String
+ // forms command line parameters for cgi command.
+ if (!"GET".equals(req.getMethod()) &&
+ !"HEAD".equals(req.getMethod()))
+ return;
+
+ String qs = req.getQueryString();
+
+ if (qs == null || qs.indexOf("=")>0)
+ return;
+
+ int delimIndex = 0;
+ int lastDelimIndex = 0;
+ delimIndex = qs.indexOf("+");
+
+ while (delimIndex >0) {
+ cmdLineParameters.add(URLDecoder.decode(qs.substring(
+ lastDelimIndex,delimIndex),parameterEncoding));
+ lastDelimIndex = delimIndex + 1;
+ delimIndex = qs.indexOf("+",lastDelimIndex);
+ }
+ cmdLineParameters.add(URLDecoder.decode(qs.substring(
+ lastDelimIndex),parameterEncoding));
}
-
/**
* Resolves core information about the cgi script.
*
@@ -1270,15 +1283,14 @@
}
sb.append("</td></tr>");
- sb.append("<tr><td colspan=2>Query Params</td></tr>");
- for (int i=0; i < queryParameters.size(); i++) {
- NameValuePair nvp = (NameValuePair) queryParameters.get(i);
- sb.append("<tr><td>");
- sb.append(nvp.getName());
- sb.append("</td><td>");
- sb.append(nvp.getValue());
- sb.append("</td></tr>");
+ sb.append("<tr><td>Command Line Params</td><td>");
+ for (int i=0; i < cmdLineParameters.size(); i++) {
+ String param = (String) cmdLineParameters.get(i);
+ sb.append("<p>");
+ sb.append(param);
+ sb.append("</p>");
}
+ sb.append("</td></tr>");
sb.append("</TABLE><p>end.");
@@ -1330,7 +1342,7 @@
*
*/
protected ArrayList getParameters() {
- return queryParameters;
+ return cmdLineParameters;
}
@@ -1436,7 +1448,7 @@
/** working directory used when invoking the cgi script */
private File wd = null;
- /** query parameters to be passed to the invoked script */
+ /** command line parameters to be passed to the invoked script */
private ArrayList params = null;
/** stdin to be passed to cgi script */
@@ -1462,8 +1474,8 @@
* @param command string full path to command to be executed
* @param env Hashtable with the desired script environment
* @param wd File with the script's desired working directory
- * @param params ArrayList with the script's query parameters as
- * NameValuePairs
+ * @param params ArrayList with the script's query command line
+ * paramters as strings
*/
protected CGIRunner(String command, Hashtable env, File wd,
ArrayList params) {
@@ -1657,21 +1669,14 @@
for (int i=0; i < params.size(); i++) {
cmdAndArgs.append(" ");
- NameValuePair nvp = (NameValuePair) params.get(i);
- String k = nvp.getName();
- String v = nvp.getValue();
- if ((k.indexOf("=") < 0) && (v.indexOf("=") < 0)) {
- StringBuffer arg = new StringBuffer(k);
- arg.append("=");
- arg.append(v);
- if (arg.toString().indexOf(" ") < 0) {
- cmdAndArgs.append(arg);
- } else {
- // Spaces used as delimiter, so need to use quotes
- cmdAndArgs.append("\"");
- cmdAndArgs.append(arg);
- cmdAndArgs.append("\"");
- }
+ String param = (String) params.get(i);
+ if (param.indexOf(" ") < 0) {
+ cmdAndArgs.append(param);
+ } else {
+ // Spaces used as delimiter, so need to use quotes
+ cmdAndArgs.append("\"");
+ cmdAndArgs.append(param);
+ cmdAndArgs.append("\"");
}
}
@@ -1680,137 +1685,118 @@
command.append(cmdAndArgs.toString());
cmdAndArgs = command;
- String sContentLength = (String) env.get("CONTENT_LENGTH");
- ByteArrayOutputStream contentStream = null;
- if(!"".equals(sContentLength)) {
- byte[] content = new byte[Integer.parseInt(sContentLength)];
+ try {
+ rt = Runtime.getRuntime();
+ proc = rt.exec(cmdAndArgs.toString(), hashToStringArray(env), wd);
+
+ String sContentLength = (String) env.get("CONTENT_LENGTH");
- // Bugzilla 32023
- int lenRead = 0;
- do {
- int partRead = stdin.read(content,lenRead,content.length-lenRead);
- lenRead += partRead;
- } while (lenRead > 0 && lenRead < content.length);
-
- contentStream = new ByteArrayOutputStream(
- Integer.parseInt(sContentLength));
- if ("POST".equals(env.get("REQUEST_METHOD"))) {
- String paramStr = getPostInput(params);
- if (paramStr != null) {
- byte[] paramBytes = paramStr.getBytes();
- contentStream.write(paramBytes);
-
- int contentLength = paramBytes.length;
- if (lenRead > 0) {
- String lineSep = System.getProperty("line.separator");
- contentStream.write(lineSep.getBytes());
- contentLength = lineSep.length() + lenRead;
- }
- env.put("CONTENT_LENGTH", Integer.toString(contentLength));
- }
+ if(!"".equals(sContentLength)) {
+ commandsStdIn = new BufferedOutputStream(proc.getOutputStream());
+ IOTools.flow(stdin, commandsStdIn);
+ commandsStdIn.flush();
+ commandsStdIn.close();
}
- if (lenRead > 0) {
- contentStream.write(content, 0, lenRead);
- }
- contentStream.close();
- }
+ /* we want to wait for the process to exit, Process.waitFor()
+ * is useless in our situation; see
+ * http://developer.java.sun.com/developer/
+ * bugParade/bugs/4223650.html
+ */
- rt = Runtime.getRuntime();
- proc = rt.exec(cmdAndArgs.toString(), hashToStringArray(env), wd);
+ boolean isRunning = true;
+ commandsStdErr = new BufferedReader
+ (new InputStreamReader(proc.getErrorStream()));
+ final BufferedReader stdErrRdr = commandsStdErr ;
- if(contentStream != null) {
- commandsStdIn = new BufferedOutputStream(proc.getOutputStream());
- commandsStdIn.write(contentStream.toByteArray());
- commandsStdIn.flush();
- commandsStdIn.close();
- }
+ new Thread() {
+ public void run () {
+ sendToLog(stdErrRdr) ;
+ } ;
+ }.start() ;
- /* we want to wait for the process to exit, Process.waitFor()
- * is useless in our situation; see
- * http://developer.java.sun.com/developer/
- * bugParade/bugs/4223650.html
- */
-
- boolean isRunning = true;
- commandsStdErr = new BufferedReader
- (new InputStreamReader(proc.getErrorStream()));
- final BufferedReader stdErrRdr = commandsStdErr ;
-
- new Thread() {
- public void run () {
- sendToLog(stdErrRdr) ;
- } ;
- }.start() ;
-
- InputStream cgiHeaderStream =
- new HTTPHeaderInputStream(proc.getInputStream());
- BufferedReader cgiHeaderReader =
- new BufferedReader(new InputStreamReader(cgiHeaderStream));
+ InputStream cgiHeaderStream =
+ new HTTPHeaderInputStream(proc.getInputStream());
+ BufferedReader cgiHeaderReader =
+ new BufferedReader(new InputStreamReader(cgiHeaderStream));
- while (isRunning) {
- try {
- //set headers
- String line = null;
- while (((line = cgiHeaderReader.readLine()) != null)
- && !("".equals(line))) {
- if (debug >= 2) {
- log("runCGI: addHeader(\"" + line + "\")");
- }
- if (line.startsWith("HTTP")) {
- response.setStatus(getSCFromHttpStatusLine(line));
- } else if (line.indexOf(":") >= 0) {
- String header =
- line.substring(0, line.indexOf(":")).trim();
- String value =
- line.substring(line.indexOf(":") + 1).trim();
- if (header.equalsIgnoreCase("status")) {
- response.setStatus(getSCFromCGIStatusHeader(value));
+ while (isRunning) {
+ try {
+ //set headers
+ String line = null;
+ while (((line = cgiHeaderReader.readLine()) != null)
+ && !("".equals(line))) {
+ if (debug >= 2) {
+ log("runCGI: addHeader(\"" + line + "\")");
+ }
+ if (line.startsWith("HTTP")) {
+ response.setStatus(getSCFromHttpStatusLine(line));
+ } else if (line.indexOf(":") >= 0) {
+ String header =
+ line.substring(0, line.indexOf(":")).trim();
+ String value =
+ line.substring(line.indexOf(":") + 1).trim();
+ if (header.equalsIgnoreCase("status")) {
+ response.setStatus(getSCFromCGIStatusHeader(value));
+ } else {
+ response.addHeader(header , value);
+ }
} else {
- response.addHeader(header , value);
+ log("runCGI: bad header line \"" + line + "\"");
}
- } else {
- log("runCGI: bad header line \"" + line + "\"");
}
- }
-
- //write output
- byte[] bBuf = new byte[2048];
-
- OutputStream out = response.getOutputStream();
- cgiOutput = proc.getInputStream();
-
- try {
- while ((bufRead = cgiOutput.read(bBuf)) != -1) {
- if (debug >= 4) {
- log("runCGI: output " + bufRead +
- " bytes of data");
+
+ //write output
+ byte[] bBuf = new byte[2048];
+
+ OutputStream out = response.getOutputStream();
+ cgiOutput = proc.getInputStream();
+
+ try {
+ while ((bufRead = cgiOutput.read(bBuf)) != -1) {
+ if (debug >= 4) {
+ log("runCGI: output " + bufRead +
+ " bytes of data");
+ }
+ out.write(bBuf, 0, bufRead);
}
- out.write(bBuf, 0, bufRead);
+ } finally {
+ // Attempt to consume any leftover byte if something bad happens,
+ // such as a socket disconnect on the servlet side; otherwise, the
+ // external process could hang
+ if (bufRead != -1) {
+ while ((bufRead = cgiOutput.read(bBuf)) != -1) {}
+ }
}
- } finally {
- // Attempt to consume any leftover byte if something bad happens,
- // such as a socket disconnect on the servlet side; otherwise, the
- // external process could hang
- if (bufRead != -1) {
- while ((bufRead = cgiOutput.read(bBuf)) != -1) {}
+
+ proc.exitValue(); // Throws exception if alive
+
+ isRunning = false;
+
+ } catch (IllegalThreadStateException e) {
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException ignored) {
}
}
+ } //replacement for Process.waitFor()
- proc.exitValue(); // Throws exception if alive
-
- isRunning = false;
-
- } catch (IllegalThreadStateException e) {
- try {
- Thread.sleep(500);
- } catch (InterruptedException ignored) {
- }
+ // Close the output stream used
+ cgiOutput.close();
+ }
+ catch (IOException e){
+ log ("Caught exception " + e);
+ throw new IOException (e.toString());
+ }
+ finally{
+ if (debug > 4) {
+ log ("Running finally block");
}
- } //replacement for Process.waitFor()
-
- // Close the output stream used
- cgiOutput.close();
+ if (proc != null){
+ proc.destroy();
+ proc = null;
+ }
+ }
}
/**
@@ -1893,64 +1879,9 @@
log("runCGI: " + lineCount + " lines received on stderr") ;
} ;
}
-
-
- /**
- * Gets a string for input to a POST cgi script
- *
- * @param params ArrayList of query parameters to be passed to
- * the CGI script
- * @return for use as input to the CGI script
- */
-
- protected String getPostInput(ArrayList params) {
- StringBuffer qs = new StringBuffer("");
- for (int i=0; i < params.size(); i++) {
- NameValuePair nvp = (NameValuePair) this.params.get(i);
- String k = nvp.getName();
- String v = nvp.getValue();
- if ((k.indexOf("=") < 0) && (v.indexOf("=") < 0)) {
- qs.append(k);
- qs.append("=");
- qs.append(v);
- qs.append("&");
- }
- }
- if (qs.length() > 0) {
- // Remove last "&"
- qs.setLength(qs.length() - 1);
- return qs.toString();
- } else {
- return null;
- }
- }
} //class CGIRunner
/**
- * This is a simple class for storing name-value pairs.
- *
- * TODO: It might be worth moving this to the utils package there is a
- * wider requirement for this functionality.
- */
- protected class NameValuePair {
- private String name;
- private String value;
-
- NameValuePair(String name, String value) {
- this.name = name;
- this.value = value;
- }
-
- protected String getName() {
- return name;
- }
-
- protected String getValue() {
- return value;
- }
- }
-
- /**
* This is an input stream specifically for reading HTTP headers. It reads
* upto and including the two blank lines terminating the headers. It
* allows the content to be read using bytes or characters as appropriate.
Modified: labs/jbossweb/trunk/src/share/classes/org/apache/catalina/ssi/SSIProcessor.java
===================================================================
--- labs/jbossweb/trunk/src/share/classes/org/apache/catalina/ssi/SSIProcessor.java 2006-08-29 21:41:31 UTC (rev 6009)
+++ labs/jbossweb/trunk/src/share/classes/org/apache/catalina/ssi/SSIProcessor.java 2006-08-29 21:45:52 UTC (rev 6010)
@@ -232,12 +232,14 @@
boolean inside = false;
String[] vals = new String[count];
StringBuffer sb = new StringBuffer();
+ char endQuote = 0;
for (int bIdx = start; bIdx < cmd.length(); bIdx++) {
if (!inside) {
- while (bIdx < cmd.length() && cmd.charAt(bIdx) != '"')
+ while (bIdx < cmd.length() && !isQuote(cmd.charAt(bIdx)))
bIdx++;
if (bIdx >= cmd.length()) break;
inside = !inside;
+ endQuote = cmd.charAt(bIdx);
} else {
boolean escaped = false;
for (; bIdx < cmd.length(); bIdx++) {
@@ -248,7 +250,7 @@
continue;
}
// If we reach the other " then stop
- if (c == '"' && !escaped) break;
+ if (c == endQuote && !escaped) break;
// Since parsing of attributes and var
// substitution is done in separate places,
// we need to leave escape in the string
@@ -310,4 +312,8 @@
protected boolean isSpace(char c) {
return c == ' ' || c == '\n' || c == '\t' || c == '\r';
}
+
+ protected boolean isQuote(char c) {
+ return c == '\'' || c == '\"' || c == '`';
+ }
}
\ No newline at end of file
More information about the jboss-svn-commits
mailing list