[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