markt 2004/01/18 09:46:32 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. Revision Changes Path 1.13 +101 -10 jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/servlets/CGIServlet.java Index: CGIServlet.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/servlets/CGIServlet.java,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- CGIServlet.java 15 Jan 2004 00:57:59 -0000 1.12 +++ CGIServlet.java 18 Jan 2004 17:46:32 -0000 1.13 @@ -66,6 +66,7 @@ import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -90,6 +91,7 @@ import javax.servlet.http.HttpSession; import org.apache.catalina.Globals; +import org.apache.catalina.util.IOTools; /** @@ -313,6 +315,9 @@ /** the command 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> @@ -721,6 +726,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; @@ -782,6 +790,7 @@ protected void setupFromContext(ServletContext context) { this.context = context; this.webAppRootDir = context.getRealPath("/"); + this.tmpDir = (File) context.getAttribute(Globals.WORK_DIR_ATTR); } @@ -934,11 +943,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 @@ -977,6 +983,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, @@ -1117,6 +1129,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]