You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2006/07/22 02:19:37 UTC

svn commit: r424503 - in /tomcat/container/tc5.5.x: catalina/src/share/org/apache/catalina/servlets/CGIServlet.java webapps/docs/changelog.xml

Author: markt
Date: Fri Jul 21 17:19:37 2006
New Revision: 424503

URL: http://svn.apache.org/viewvc?rev=424503&view=rev
Log:
Partial fix for bug part of 34801. Add handling of IOExceptions during long running CGI requests.

Modified:
    tomcat/container/tc5.5.x/catalina/src/share/org/apache/catalina/servlets/CGIServlet.java
    tomcat/container/tc5.5.x/webapps/docs/changelog.xml

Modified: tomcat/container/tc5.5.x/catalina/src/share/org/apache/catalina/servlets/CGIServlet.java
URL: http://svn.apache.org/viewvc/tomcat/container/tc5.5.x/catalina/src/share/org/apache/catalina/servlets/CGIServlet.java?rev=424503&r1=424502&r2=424503&view=diff
==============================================================================
--- tomcat/container/tc5.5.x/catalina/src/share/org/apache/catalina/servlets/CGIServlet.java (original)
+++ tomcat/container/tc5.5.x/catalina/src/share/org/apache/catalina/servlets/CGIServlet.java Fri Jul 21 17:19:37 2006
@@ -1685,103 +1685,118 @@
             command.append(cmdAndArgs.toString());
             cmdAndArgs = command;
 
-            rt = Runtime.getRuntime();
-            proc = rt.exec(cmdAndArgs.toString(), hashToStringArray(env), wd);
-
-            String sContentLength = (String) env.get("CONTENT_LENGTH");
-
-            if(!"".equals(sContentLength)) {
-                commandsStdIn = new BufferedOutputStream(proc.getOutputStream());
-                IOTools.flow(stdin, commandsStdIn);
-                commandsStdIn.flush();
-                commandsStdIn.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
-             */
-
-            boolean isRunning = true;
-            commandsStdErr = new BufferedReader
-                (new InputStreamReader(proc.getErrorStream()));
-            final BufferedReader stdErrRdr = commandsStdErr ;
+            try {
+                rt = Runtime.getRuntime();
+                proc = rt.exec(cmdAndArgs.toString(), hashToStringArray(env), wd);
+    
+                String sContentLength = (String) env.get("CONTENT_LENGTH");
 
-            new Thread() {
-                public void run () {
-                    sendToLog(stdErrRdr) ;
-                } ;
-            }.start() ;
+                if(!"".equals(sContentLength)) {
+                    commandsStdIn = new BufferedOutputStream(proc.getOutputStream());
+                    IOTools.flow(stdin, commandsStdIn);
+                    commandsStdIn.flush();
+                    commandsStdIn.close();
+                }
 
-            InputStream cgiHeaderStream =
-                new HTTPHeaderInputStream(proc.getInputStream());
-            BufferedReader cgiHeaderReader =
-                new BufferedReader(new InputStreamReader(cgiHeaderStream));
+                /* 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));
             
-            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);
+                            }
+                        } 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) {}
                             }
-                            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) {}
+        
+                        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;
+                }
+            }
         }
 
         /**

Modified: tomcat/container/tc5.5.x/webapps/docs/changelog.xml
URL: http://svn.apache.org/viewvc/tomcat/container/tc5.5.x/webapps/docs/changelog.xml?rev=424503&r1=424502&r2=424503&view=diff
==============================================================================
--- tomcat/container/tc5.5.x/webapps/docs/changelog.xml (original)
+++ tomcat/container/tc5.5.x/webapps/docs/changelog.xml Fri Jul 21 17:19:37 2006
@@ -56,6 +56,10 @@
         query string via the QUERY_STRING environment variable; provide POST
         content unmodified to stdin; and never call getParameters(). (markt) 
       </fix>
+      <fix>
+        <bug>34801</bug>: Partial fix that adds handling of IOExceptions during
+        long running CGI requests. Based on a patch by Chris Davey. (markt)
+      </fix>
   </changelog>
   </subsection> 
   <subsection name="Webapps">



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org