markt 2004/01/18 09:48:11 Modified: catalina/src/share/org/apache/catalina/servlets CGIServlet.java Log: - Fix bug 12361. Support CGI scripts in unpacked WARs. Scripts are extracted to the context work directory before execution. - Remove unused imports - thanks to Eclipse. Revision Changes Path 1.17 +102 -19 jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/servlets/CGIServlet.java Index: CGIServlet.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/servlets/CGIServlet.java,v retrieving revision 1.16 retrieving revision 1.17 diff -u -r1.16 -r1.17 --- CGIServlet.java 15 Jan 2004 00:56:53 -0000 1.16 +++ CGIServlet.java 18 Jan 2004 17:48:11 -0000 1.17 @@ -62,18 +62,13 @@ package org.apache.catalina.servlets; -import java.lang.Process; import java.io.File; -import java.io.Writer; -import java.io.Reader; -import java.io.PrintWriter; +import java.io.FileOutputStream; import java.io.BufferedWriter; import java.io.BufferedReader; import java.io.InputStream; -import java.io.OutputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; -import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.IOException; import java.net.URLEncoder; @@ -93,9 +88,8 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import javax.servlet.http.Cookie; -import org.apache.catalina.Context; import org.apache.catalina.Globals; -import org.apache.catalina.Wrapper; +import org.apache.catalina.util.IOTools; // import org.apache.catalina.util.StringManager; @@ -317,10 +311,13 @@ */ private String cgiPathPrefix = null; - /** the executable to use with the script */ private String cgiExecutable = "perl"; + /** object used to ensure multiple threads don't try to expand same file */ + static Object expandFileLock = new Object(); + + /** * Sets instance variables. * <P> @@ -731,6 +728,9 @@ /** real file system directory of the enclosing servlet's web app */ private String webAppRootDir = null; + /** tempdir for context - used to expand scripts in unexpanded wars */ + private File tmpDir = null; + /** derived cgi environment */ private Hashtable env = null; @@ -792,6 +792,7 @@ protected void setupFromContext(ServletContext context) { this.context = context; this.webAppRootDir = context.getRealPath("/"); + this.tmpDir = (File) context.getAttribute(Globals.WORK_DIR_ATTR); } @@ -944,11 +945,8 @@ + ", scriptname=" + scriptname + ", cginame=" + cginame); } return new String[] { path, scriptname, cginame, name }; - } - - /** * Constructs the CGI environment to be supplied to the invoked CGI * script; relies heavliy on Servlet API methods and findCGI @@ -992,6 +990,12 @@ sPathTranslatedOrig = sPathTranslatedOrig == null ? "" : sPathTranslatedOrig; + if (webAppRootDir == null ) { + // The app has not been deployed in exploded form + webAppRootDir = tmpDir.toString(); + expandCGIScript(); + } + sCGINames = findCGI(sPathInfoOrig, webAppRootDir, contextPath, @@ -1131,6 +1135,85 @@ } + /** + * Extracts requested resource from web app archive to context work + * directory to enable CGI script to be executed. + */ + protected void expandCGIScript() { + StringBuffer srcPath = new StringBuffer(); + StringBuffer destPath = new StringBuffer(); + InputStream is = null; + + // paths depend on mapping + if (cgiPathPrefix == null ) { + srcPath.append(pathInfo); + is = context.getResourceAsStream(srcPath.toString()); + destPath.append(tmpDir); + destPath.append(pathInfo); + } else { + // essentially same search algorithm as findCGI() + srcPath.append(cgiPathPrefix); + StringTokenizer pathWalker = + new StringTokenizer (pathInfo, "/"); + // start with first element + while (pathWalker.hasMoreElements() && (is == null)) { + srcPath.append("/"); + srcPath.append(pathWalker.nextElement()); + is = context.getResourceAsStream(srcPath.toString()); + } + destPath.append(tmpDir); + destPath.append("/"); + destPath.append(srcPath); + } + + if (is == null) { + // didn't find anything, give up now + if (debug >= 2) { + log("expandCGIScript: source '" + srcPath + "' not found"); + } + return; + } + + File f = new File(destPath.toString()); + if (f.exists()) { + // Don't need to expand if it already exists + return; + } + + // create directories + String dirPath = new String (destPath.toString().substring( + 0,destPath.toString().lastIndexOf("/"))); + File dir = new File(dirPath); + dir.mkdirs(); + + try { + synchronized (expandFileLock) { + // make sure file doesn't exist + if (f.exists()) { + return; + } + + // create file + if (!f.createNewFile()) { + return; + } + FileOutputStream fos = new FileOutputStream(f); + + // copy data + IOTools.flow(is, fos); + is.close(); + fos.close(); + if (debug >= 2) { + log("expandCGIScript: expanded '" + srcPath + "' to '" + destPath + "'"); + } + } + } catch (IOException ioe) { + // delete in case file is corrupted + if (f.exists()) { + f.delete(); + } + } + } /**
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]