JBossWeb SVN: r1392 - branches/2.1.x/webapps/docs/config.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2010-02-26 11:58:25 -0500 (Fri, 26 Feb 2010)
New Revision: 1392
Modified:
branches/2.1.x/webapps/docs/config/ajp.xml
Log:
JBWEB-145
Modified: branches/2.1.x/webapps/docs/config/ajp.xml
===================================================================
--- branches/2.1.x/webapps/docs/config/ajp.xml 2010-02-26 16:47:42 UTC (rev 1391)
+++ branches/2.1.x/webapps/docs/config/ajp.xml 2010-02-26 16:58:25 UTC (rev 1392)
@@ -119,12 +119,6 @@
number specified here.</p>
</attribute>
- <attribute name="request.registerRequests" required="false">
- <p>This attribute controls request registration for JMX monitoring
- of the Connector. It is enabled by default, but may be turned
- it off to save a bit of memory.</p>
- </attribute>
-
<attribute name="scheme" required="false">
<p>Set this attribute to the name of the protocol you wish to have
returned by calls to <code>request.getScheme()</code>. For
@@ -243,6 +237,11 @@
to a particular port number on a particular IP address.</p>
</attribute>
+ <attribute name="requiredSecret" required="false">
+ <p>Only requests from workers with this secret keyword will be accepted.
+ Not used by default.</p>
+ </attribute>
+
<attribute name="tcpNoDelay" required="false">
<p>If set to <code>true</code>, the TCP_NO_DELAY option will be
set on the server socket, which improves performance under most
14 years, 10 months
JBossWeb SVN: r1391 - trunk/webapps/docs/config.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2010-02-26 11:47:42 -0500 (Fri, 26 Feb 2010)
New Revision: 1391
Modified:
trunk/webapps/docs/config/ajp.xml
Log:
JBWEB-145
Modified: trunk/webapps/docs/config/ajp.xml
===================================================================
--- trunk/webapps/docs/config/ajp.xml 2010-02-18 14:03:13 UTC (rev 1390)
+++ trunk/webapps/docs/config/ajp.xml 2010-02-26 16:47:42 UTC (rev 1391)
@@ -119,12 +119,6 @@
number specified here.</p>
</attribute>
- <attribute name="request.registerRequests" required="false">
- <p>This attribute controls request registration for JMX monitoring
- of the Connector. It is enabled by default, but may be turned
- it off to save a bit of memory.</p>
- </attribute>
-
<attribute name="scheme" required="false">
<p>Set this attribute to the name of the protocol you wish to have
returned by calls to <code>request.getScheme()</code>. For
@@ -243,6 +237,11 @@
to a particular port number on a particular IP address.</p>
</attribute>
+ <attribute name="requiredSecret" required="false">
+ <p>Only requests from workers with this secret keyword will be accepted.
+ Not used by default.</p>
+ </attribute>
+
<attribute name="tcpNoDelay" required="false">
<p>If set to <code>true</code>, the TCP_NO_DELAY option will be
set on the server socket, which improves performance under most
14 years, 10 months
JBossWeb SVN: r1390 - in trunk: java/org/apache/jasper/compiler and 5 other directories.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2010-02-18 09:03:13 -0500 (Thu, 18 Feb 2010)
New Revision: 1390
Modified:
trunk/java/org/apache/catalina/realm/JNDIRealm.java
trunk/java/org/apache/jasper/compiler/JavacErrorDetail.java
trunk/java/org/apache/jasper/resources/LocalStrings.properties
trunk/java/org/apache/jasper/security/SecurityClassLoad.java
trunk/java/org/apache/jasper/servlet/JspServletWrapper.java
trunk/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java
trunk/webapps/docs/changelog.xml
Log:
- Port minor Tomcat patches.
Modified: trunk/java/org/apache/catalina/realm/JNDIRealm.java
===================================================================
--- trunk/java/org/apache/catalina/realm/JNDIRealm.java 2010-02-17 02:03:46 UTC (rev 1389)
+++ trunk/java/org/apache/catalina/realm/JNDIRealm.java 2010-02-18 14:03:13 UTC (rev 1390)
@@ -24,6 +24,7 @@
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
@@ -1673,7 +1674,7 @@
Set<String> newThisRound = new HashSet<String>(); // Stores the groups we find in this iteration
for (String groupDN : newGroupDNs) {
- filter = roleFormat.format(new String[] { groupDN, groupDN });
+ filter = roleFormat.format(new String[] { groupDN });
if (containerLog.isTraceEnabled()) {
containerLog.trace("Perform a nested group search with base "+ roleBase + " and filter " + filter);
@@ -2196,26 +2197,38 @@
}
-}
+ /**
+ * A private class representing a User
+ */
+ protected static class User {
+
+ private String username = null;
+ private String dn = null;
+ private String password = null;
+ private ArrayList<String> roles = null;
-// ------------------------------------------------------ Private Classes
-
-/**
- * A private class representing a User
- */
-class User {
- String username = null;
- String dn = null;
- String password = null;
- ArrayList<String> roles = null;
-
-
- User(String username, String dn, String password,
- ArrayList<String> roles) {
- this.username = username;
- this.dn = dn;
- this.password = password;
- this.roles = roles;
+ User(String username, String dn, String password,
+ ArrayList<String> roles) {
+ this.username = username;
+ this.dn = dn;
+ this.password = password;
+ this.roles = roles;
+ }
+
+ public String getUserName() {
+ return username;
+ }
+
+ public String getDN() {
+ return dn;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public List<String> getRoles() {
+ return Collections.unmodifiableList(roles);
+ }
}
-
}
Modified: trunk/java/org/apache/jasper/compiler/JavacErrorDetail.java
===================================================================
--- trunk/java/org/apache/jasper/compiler/JavacErrorDetail.java 2010-02-17 02:03:46 UTC (rev 1389)
+++ trunk/java/org/apache/jasper/compiler/JavacErrorDetail.java 2010-02-18 14:03:13 UTC (rev 1390)
@@ -71,18 +71,9 @@
* @param jspBeginLineNum The start line number of the JSP element
* responsible for the compilation error
* @param errMsg The compilation error message
+ * @param ctxt The compilation context
*/
public JavacErrorDetail(String javaFileName,
- int javaLineNum,
- String jspFileName,
- int jspBeginLineNum,
- StringBuilder errMsg) {
-
- this(javaFileName, javaLineNum, jspFileName, jspBeginLineNum, errMsg,
- null);
- }
-
- public JavacErrorDetail(String javaFileName,
int javaLineNum,
String jspFileName,
int jspBeginLineNum,
@@ -94,14 +85,24 @@
this.jspBeginLineNum = jspBeginLineNum;
if (jspBeginLineNum > 0 && ctxt != null) {
+ InputStream is = null;
+ FileInputStream fis = null;
+
try {
// Read both files in, so we can inspect them
- String[] jspLines = readFile
- (ctxt.getResourceAsStream(jspFileName));
+ is = ctxt.getResourceAsStream(jspFileName);
+ String[] jspLines = readFile(is);
- String[] javaLines = readFile
- (new FileInputStream(ctxt.getServletJavaFileName()));
+ fis = new FileInputStream(ctxt.getServletJavaFileName());
+ String[] javaLines = readFile(fis);
+ if (jspLines.length < jspBeginLineNum) {
+ // Avoid ArrayIndexOutOfBoundsException
+ // Probably bug 48494 but could be some other cause
+ jspExtract = Localizer.getMessage("jsp.error.bug48494");
+ return;
+ }
+
// If the line contains the opening of a multi-line scriptlet
// block, then the JSP line number we got back is probably
// faulty. Scan forward to match the java line...
@@ -134,6 +135,21 @@
} catch (IOException ioe) {
// Can't read files - ignore
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException ioe) {
+ // Ignore
+ }
+ }
+ if (fis != null) {
+ try {
+ fis.close();
+ } catch (IOException ioe) {
+ // Ignore
+ }
+ }
}
}
}
@@ -202,13 +218,13 @@
*/
private String[] readFile(InputStream s) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(s));
- List lines = new ArrayList();
+ List<String> lines = new ArrayList<String>();
String line;
while ( (line = reader.readLine()) != null ) {
lines.add(line);
}
- return (String[]) lines.toArray( new String[lines.size()] );
+ return lines.toArray( new String[lines.size()] );
}
}
Modified: trunk/java/org/apache/jasper/resources/LocalStrings.properties
===================================================================
--- trunk/java/org/apache/jasper/resources/LocalStrings.properties 2010-02-17 02:03:46 UTC (rev 1389)
+++ trunk/java/org/apache/jasper/resources/LocalStrings.properties 2010-02-18 14:03:13 UTC (rev 1390)
@@ -441,3 +441,6 @@
jsp.error.tag.invalid.trimdirectivewhitespaces=Tag directive: invalid value for trimDirectiveWhitespaces
jsp.error.page.conflict.trimdirectivewhitespaces=Page directive: illegal to have multiple occurrences of 'trimDirectiveWhitespaces' with different values (old: {0}, new: {1})
jsp.error.tag.conflict.trimdirectivewhitespaces=Tag directive: illegal to have multiple occurrences of 'trimDirectiveWhitespaces' with different values (old: {0}, new: {1})
+
+# JavacErrorDetail
+jsp.error.bug48494=Unable to display JSP extract. Probably due to a JRE bug (see Tomcat bug 48498 for details).
Modified: trunk/java/org/apache/jasper/security/SecurityClassLoad.java
===================================================================
--- trunk/java/org/apache/jasper/security/SecurityClassLoad.java 2010-02-17 02:03:46 UTC (rev 1389)
+++ trunk/java/org/apache/jasper/security/SecurityClassLoad.java 2010-02-18 14:03:13 UTC (rev 1390)
@@ -99,6 +99,9 @@
loader.loadClass( basePackage +
"runtime.JspContextWrapper");
+ // Trigger loading of class and reading of property
+ SecurityUtil.isPackageProtectionEnabled();
+
loader.loadClass( basePackage +
"servlet.JspServletWrapper");
Modified: trunk/java/org/apache/jasper/servlet/JspServletWrapper.java
===================================================================
--- trunk/java/org/apache/jasper/servlet/JspServletWrapper.java 2010-02-17 02:03:46 UTC (rev 1389)
+++ trunk/java/org/apache/jasper/servlet/JspServletWrapper.java 2010-02-18 14:03:13 UTC (rev 1390)
@@ -166,7 +166,7 @@
}
public ServletContext getServletContext() {
- return config.getServletContext();
+ return ctxt.getServletContext();
}
/**
Modified: trunk/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java
===================================================================
--- trunk/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java 2010-02-17 02:03:46 UTC (rev 1389)
+++ trunk/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java 2010-02-18 14:03:13 UTC (rev 1390)
@@ -307,9 +307,6 @@
if( truststorePassword == null) {
truststorePassword = System.getProperty("javax.net.ssl.trustStorePassword");
}
- if( truststorePassword == null ) {
- truststorePassword = getKeystorePassword();
- }
if(log.isDebugEnabled()) {
log.debug("TrustPass = " + truststorePassword);
}
@@ -336,7 +333,7 @@
log.debug("trustProvider = " + truststoreProvider);
}
- if (truststoreFile != null && truststorePassword != null){
+ if (truststoreFile != null){
trustStore = getStore(truststoreType, truststoreProvider,
truststoreFile, truststorePassword);
}
@@ -367,7 +364,11 @@
istream = new FileInputStream(keyStoreFile);
}
- ks.load(istream, pass.toCharArray());
+ char[] storePass = null;
+ if (pass != null) {
+ storePass = pass.toCharArray();
+ }
+ ks.load(istream, storePass);
} catch (FileNotFoundException fnfe) {
log.error(sm.getString("jsse.keystore_load_failed", type, path,
fnfe.getMessage()), fnfe);
Modified: trunk/webapps/docs/changelog.xml
===================================================================
--- trunk/webapps/docs/changelog.xml 2010-02-17 02:03:46 UTC (rev 1389)
+++ trunk/webapps/docs/changelog.xml 2010-02-18 14:03:13 UTC (rev 1390)
@@ -20,9 +20,6 @@
<subsection name="Catalina">
<changelog>
<fix>
- <bug>48629</bug>: Nested role seach fix in JNDI realm, submitted by Gabriel. (markt)
- </fix>
- <fix>
Add LDAP connection timeout in JNDI realm. (markt)
</fix>
<fix>
@@ -38,6 +35,9 @@
<fix>
<bug>48384</bug>: Per directory XSLT for default servlet. (markt)
</fix>
+ <fix>
+ <bug>48589</bug>: JNDI realm extensibility. (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Coyote">
@@ -45,6 +45,9 @@
<fix>
<bug>48660</bug>: Add to vary header. (markt)
</fix>
+ <fix>
+ <bug>48545</bug>: Optional password on truststores. (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Jasper">
@@ -62,6 +65,18 @@
<fix>
Rebase ELSupport. (remm)
</fix>
+ <fix>
+ <bug>42314</bug>: More stream closing when reporting errors. (markt)
+ </fix>
+ <fix>
+ <bug>48498</bug>: Workaround for XML parser bug when reporting errors. (markt)
+ </fix>
+ <fix>
+ <bug>48580</bug>: Possible security exception on first JSP access. (markt)
+ </fix>
+ <fix>
+ <bug>48582</bug>: Avoid NPE on compilation errors of tag files. (markt)
+ </fix>
</changelog>
</subsection>
</section>
14 years, 10 months
JBossWeb SVN: r1389 - in trunk: java/org/apache/coyote/http11 and 1 other directories.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2010-02-16 21:03:46 -0500 (Tue, 16 Feb 2010)
New Revision: 1389
Modified:
trunk/java/org/apache/catalina/servlets/DefaultServlet.java
trunk/java/org/apache/catalina/servlets/WebdavServlet.java
trunk/java/org/apache/coyote/http11/Http11AprProcessor.java
trunk/java/org/apache/coyote/http11/Http11Processor.java
trunk/webapps/docs/changelog.xml
trunk/webapps/docs/default-servlet.xml
Log:
- Port 3 minor patches.
Modified: trunk/java/org/apache/catalina/servlets/DefaultServlet.java
===================================================================
--- trunk/java/org/apache/catalina/servlets/DefaultServlet.java 2010-02-17 02:02:44 UTC (rev 1388)
+++ trunk/java/org/apache/catalina/servlets/DefaultServlet.java 2010-02-17 02:03:46 UTC (rev 1389)
@@ -127,6 +127,12 @@
/**
+ * Allow customized directory listing per context.
+ */
+ protected String contextXsltFile = null;
+
+
+ /**
* Allow customized directory listing per instance.
*/
protected String globalXsltFile = null;
@@ -244,6 +250,7 @@
fileEncoding = getServletConfig().getInitParameter("fileEncoding");
globalXsltFile = getServletConfig().getInitParameter("globalXsltFile");
+ contextXsltFile = getServletConfig().getInitParameter("contextXsltFile");
localXsltFile = getServletConfig().getInitParameter("localXsltFile");
readmeFile = getServletConfig().getInitParameter("readmeFile");
@@ -1139,6 +1146,10 @@
trimmed.equalsIgnoreCase(localXsltFile))
continue;
+ if (contextXsltFile != null
+ && (cacheEntry.name + trimmed).equals(contextXsltFile))
+ continue;
+
CacheEntry childCacheEntry =
resources.lookupCache(cacheEntry.name + resourceName);
if (!childCacheEntry.exists) {
@@ -1436,11 +1447,19 @@
} catch (NamingException e) {
if (debug > 10)
log("localXsltFile '" + localXsltFile + "' not found", e);
-
- return null;
}
}
+ if (contextXsltFile != null) {
+ InputStream is =
+ getServletContext().getResourceAsStream(contextXsltFile);
+ if (is != null)
+ return is;
+
+ if (debug > 10)
+ log("contextXsltFile '" + contextXsltFile + "' not found");
+ }
+
/* Open and read in file in one fell swoop to reduce chance
* chance of leaving handle open.
*/
Modified: trunk/java/org/apache/catalina/servlets/WebdavServlet.java
===================================================================
--- trunk/java/org/apache/catalina/servlets/WebdavServlet.java 2010-02-17 02:02:44 UTC (rev 1388)
+++ trunk/java/org/apache/catalina/servlets/WebdavServlet.java 2010-02-17 02:03:46 UTC (rev 1389)
@@ -2028,6 +2028,11 @@
return;
CacheEntry cacheEntry = resources.lookupCache(path);
+ if (!cacheEntry.exists) {
+ // File is in directory listing but doesn't appear to exist
+ // Broken symlink or odd permission settings?
+ return;
+ }
generatedXML.writeElement(null, "response", XMLWriter.OPENING);
String status = new String("HTTP/1.1 " + WebdavStatus.SC_OK + " "
Modified: trunk/java/org/apache/coyote/http11/Http11AprProcessor.java
===================================================================
--- trunk/java/org/apache/coyote/http11/Http11AprProcessor.java 2010-02-17 02:02:44 UTC (rev 1388)
+++ trunk/java/org/apache/coyote/http11/Http11AprProcessor.java 2010-02-17 02:03:46 UTC (rev 1389)
@@ -1722,7 +1722,7 @@
outputBuffer.addActiveFilter(outputFilters[Constants.GZIP_FILTER]);
headers.setValue("Content-Encoding").setString("gzip");
// Make Proxies happy via Vary (from mod_deflate)
- headers.setValue("Vary").setString("Accept-Encoding");
+ headers.addValue("Vary").setString("Accept-Encoding");
}
// Add date header
Modified: trunk/java/org/apache/coyote/http11/Http11Processor.java
===================================================================
--- trunk/java/org/apache/coyote/http11/Http11Processor.java 2010-02-17 02:02:44 UTC (rev 1388)
+++ trunk/java/org/apache/coyote/http11/Http11Processor.java 2010-02-17 02:03:46 UTC (rev 1389)
@@ -1605,7 +1605,7 @@
outputBuffer.addActiveFilter(outputFilters[Constants.GZIP_FILTER]);
headers.setValue("Content-Encoding").setString("gzip");
// Make Proxies happy via Vary (from mod_deflate)
- headers.setValue("Vary").setString("Accept-Encoding");
+ headers.addValue("Vary").setString("Accept-Encoding");
}
// Add date header
Modified: trunk/webapps/docs/changelog.xml
===================================================================
--- trunk/webapps/docs/changelog.xml 2010-02-17 02:02:44 UTC (rev 1388)
+++ trunk/webapps/docs/changelog.xml 2010-02-17 02:03:46 UTC (rev 1389)
@@ -29,10 +29,22 @@
<bug>48050</bug>: createSubcontext method returns Context with wrong name. Based on a
suggestion by gingyang.xu. (markt)
</fix>
+ <fix>
+ <bug>48318</bug>: Handle unreadable resources in WebDAV. (markt)
+ </fix>
+ <fix>
+ <jira>19</jira>: Optionally expose principal from Session if present. (remm)
+ </fix>
+ <fix>
+ <bug>48384</bug>: Per directory XSLT for default servlet. (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Coyote">
<changelog>
+ <fix>
+ <bug>48660</bug>: Add to vary header. (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Jasper">
@@ -47,6 +59,9 @@
<fix>
<bug>48668</bug>: Fix handling of EL like strings when EL is disabled. (markt)
</fix>
+ <fix>
+ Rebase ELSupport. (remm)
+ </fix>
</changelog>
</subsection>
</section>
Modified: trunk/webapps/docs/default-servlet.xml
===================================================================
--- trunk/webapps/docs/default-servlet.xml 2010-02-17 02:02:44 UTC (rev 1388)
+++ trunk/webapps/docs/default-servlet.xml 2010-02-17 02:03:46 UTC (rev 1389)
@@ -101,19 +101,32 @@
<attribute name="globalXsltFile" required="false">
<p>If you wish to customize your directory listing, you
can use an XSL transformation. This value is an absolute
- file name which be used for all direcotory listings.
- This can be disabled by per webapp by also declaring the
- default servlet in your local webapp's web.xml. The format
- of the xml is shown below.
+ file name which be used for all directory listings.
+ This can be overridden per context and/or per directory. See
+ <strong>contextXsltFile</strong> and <strong>localXsltFile</strong>
+ below. The format of the xml is shown below.
</p>
</attribute>
+ <attribute name="contextXsltFile" required="false">
+ <p>You may also customize your directory listing by context by
+ configuring <code>contextXsltFile</code>. This should be a context
+ relative path (e.g.: <code>/path/to/context.xslt</code>). This
+ overrides <code>globalXsltFile</code>. If this value is present but a
+ file does not exist, then <code>globalXsltFile</code> will be used. If
+ <code>globalXsltFile</code> does not exist, then the default
+ directory listing will be shown.
+ </p>
+ </attribute>
+
<attribute name="localXsltFile" required="false">
<p>You may also customize your directory listing by directory by
configuring <code>localXsltFile</code>. This should be a relative
file name in the directory where the listing will take place.
- This overrides <code>globalXsltFile</code>. If this value
- is present but a file does not exist, then
+ This overrides <code>globalXsltFile</code> and
+ <code>contextXsltFile</code>. If this value is present but a file
+ does not exist, then <code>contextXsltFile</code> will be used. If
+ <code>contextXsltFile</code> does not exist, then
<code>globalXsltFile</code> will be used. If
<code>globalXsltFile</code> does not exist, then the default
directory listing will be shown.</p>
14 years, 10 months
JBossWeb SVN: r1388 - trunk/java/org/apache/el/lang.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2010-02-16 21:02:44 -0500 (Tue, 16 Feb 2010)
New Revision: 1388
Modified:
trunk/java/org/apache/el/lang/ELSupport.java
Log:
- Rebase ELSupport.
Modified: trunk/java/org/apache/el/lang/ELSupport.java
===================================================================
--- trunk/java/org/apache/el/lang/ELSupport.java 2010-02-17 01:28:24 UTC (rev 1387)
+++ trunk/java/org/apache/el/lang/ELSupport.java 2010-02-17 02:02:44 UTC (rev 1388)
@@ -32,7 +32,7 @@
* A helper class that implements the EL Specification
*
* @author Jacob Hookom [jacob(a)hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author$
+ * @version $Change: 181177 $$Date$$Author$
*/
public class ELSupport {
@@ -50,10 +50,33 @@
}
/**
- * @param obj0
- * @param obj1
- * @return
- * @throws EvaluationException
+ * Compare two objects, after coercing to the same type if appropriate.
+ *
+ * If the objects are identical, or they are equal according to
+ * {@link #equals(Object, Object)} then return 0.
+ *
+ * If either object is a BigDecimal, then coerce both to BigDecimal first.
+ * Similarly for Double(Float), BigInteger, and Long(Integer, Char, Short, Byte).
+ *
+ * Otherwise, check that the first object is an instance of Comparable, and compare
+ * against the second object. If that is null, return 1, otherwise
+ * return the result of comparing against the second object.
+ *
+ * Similarly, if the second object is Comparable, if the first is null, return -1,
+ * else return the result of comparing against the first object.
+ *
+ * A null object is considered as:
+ * <ul>
+ * <li>ZERO when compared with Numbers</li>
+ * <li>the empty string for String compares</li>
+ * <li>Otherwise null is considered to be lower than anything else.</li>
+ * </ul>
+ *
+ * @param obj0 first object
+ * @param obj1 second object
+ * @return -1, 0, or 1 if this object is less than, equal to, or greater than val.
+ * @throws ELException if neither object is Comparable
+ * @throws ClassCastException if the objects are not mutually comparable
*/
public final static int compare(final Object obj0, final Object obj1)
throws ELException {
@@ -83,20 +106,32 @@
if (obj0 instanceof String || obj1 instanceof String) {
return coerceToString(obj0).compareTo(coerceToString(obj1));
}
- if (obj0 instanceof Comparable) {
- return (obj1 != null) ? ((Comparable) obj0).compareTo(obj1) : 1;
+ if (obj0 instanceof Comparable<?>) {
+ @SuppressWarnings("unchecked") // checked above
+ final Comparable<Object> comparable = (Comparable<Object>) obj0;
+ return (obj1 != null) ? comparable.compareTo(obj1) : 1;
}
- if (obj1 instanceof Comparable) {
- return (obj0 != null) ? -((Comparable) obj1).compareTo(obj0) : -1;
+ if (obj1 instanceof Comparable<?>) {
+ @SuppressWarnings("unchecked") // checked above
+ final Comparable<Object> comparable = (Comparable<Object>) obj1;
+ return (obj0 != null) ? -comparable.compareTo(obj0) : -1;
}
throw new ELException(MessageFactory.get("error.compare", obj0, obj1));
}
/**
- * @param obj0
- * @param obj1
- * @return
- * @throws EvaluationException
+ * Compare two objects for equality, after coercing to the same type if appropriate.
+ *
+ * If the objects are identical (including both null) return true.
+ * If either object is null, return false.
+ * If either object is Boolean, coerce both to Boolean and check equality.
+ * Similarly for Enum, String, BigDecimal, Double(Float), Long(Integer, Short, Byte, Character)
+ * Otherwise default to using Object.equals().
+ *
+ * @param obj0 the first object
+ * @param obj1 the second object
+ * @return true if the objects are equal
+ * @throws ELException
*/
public final static boolean equals(final Object obj0, final Object obj1)
throws ELException {
@@ -143,24 +178,35 @@
* @param type
* @return
*/
- public final static Enum coerceToEnum(final Object obj, Class type)
- throws ELException {
+ public final static Enum<?> coerceToEnum(final Object obj, Class type) {
if (obj == null || "".equals(obj)) {
return null;
}
- if (obj.getClass().isEnum()) {
- return (Enum) obj;
+ if (type.isAssignableFrom(obj.getClass())) {
+ return (Enum<?>) obj;
}
+
+ if (!(obj instanceof String)) {
+ throw new ELException(MessageFactory.get("error.convert",
+ obj, obj.getClass(), type));
+ }
+
+ Enum<?> result;
try {
- return Enum.valueOf(type, obj.toString());
- } catch (Exception e) {
- throw new ELException(e);
+ result = Enum.valueOf(type, (String) obj);
+ } catch (IllegalArgumentException iae) {
+ throw new ELException(MessageFactory.get("error.convert",
+ obj, obj.getClass(), type));
}
+ return result;
}
/**
- * @param obj
- * @return
+ * Convert an object to Boolean.
+ * Null and empty string are false.
+ * @param obj the object to convert
+ * @return the Boolean value of the object
+ * @throws ELException if object is not Boolean or String
*/
public final static Boolean coerceToBoolean(final Object obj)
throws ELException {
@@ -259,8 +305,8 @@
number, number.getClass(), type));
}
- public final static Number coerceToNumber(final Object obj, final Class<?> type)
- throws ELException {
+ public final static Number coerceToNumber(final Object obj,
+ final Class<?> type) throws ELException {
if (obj == null || "".equals(obj)) {
return coerceToNumber(ZERO, type);
}
@@ -282,34 +328,69 @@
protected final static Number coerceToNumber(final String val,
final Class<?> type) throws ELException {
- try {
- if (Long.TYPE == type || Long.class.equals(type)) {
+ if (Long.TYPE == type || Long.class.equals(type)) {
+ try {
return Long.valueOf(val);
+ } catch (NumberFormatException nfe) {
+ throw new ELException(MessageFactory.get("error.convert",
+ val, String.class, type));
}
- if (Integer.TYPE == type || Integer.class.equals(type)) {
+ }
+ if (Integer.TYPE == type || Integer.class.equals(type)) {
+ try {
return Integer.valueOf(val);
+ } catch (NumberFormatException nfe) {
+ throw new ELException(MessageFactory.get("error.convert",
+ val, String.class, type));
}
- if (Double.TYPE == type || Double.class.equals(type)) {
+ }
+ if (Double.TYPE == type || Double.class.equals(type)) {
+ try {
return Double.valueOf(val);
+ } catch (NumberFormatException nfe) {
+ throw new ELException(MessageFactory.get("error.convert",
+ val, String.class, type));
}
- if (BigInteger.class.equals(type)) {
+ }
+ if (BigInteger.class.equals(type)) {
+ try {
return new BigInteger(val);
+ } catch (NumberFormatException nfe) {
+ throw new ELException(MessageFactory.get("error.convert",
+ val, String.class, type));
}
- if (BigDecimal.class.equals(type)) {
+ }
+ if (BigDecimal.class.equals(type)) {
+ try {
return new BigDecimal(val);
+ } catch (NumberFormatException nfe) {
+ throw new ELException(MessageFactory.get("error.convert",
+ val, String.class, type));
}
- if (Byte.TYPE == type || Byte.class.equals(type)) {
+ }
+ if (Byte.TYPE == type || Byte.class.equals(type)) {
+ try {
return Byte.valueOf(val);
+ } catch (NumberFormatException nfe) {
+ throw new ELException(MessageFactory.get("error.convert",
+ val, String.class, type));
}
- if (Short.TYPE == type || Short.class.equals(type)) {
+ }
+ if (Short.TYPE == type || Short.class.equals(type)) {
+ try {
return Short.valueOf(val);
+ } catch (NumberFormatException nfe) {
+ throw new ELException(MessageFactory.get("error.convert",
+ val, String.class, type));
}
- if (Float.TYPE == type || Float.class.equals(type)) {
+ }
+ if (Float.TYPE == type || Float.class.equals(type)) {
+ try {
return Float.valueOf(val);
+ } catch (NumberFormatException nfe) {
+ throw new ELException(MessageFactory.get("error.convert",
+ val, String.class, type));
}
- } catch (Exception e) {
- throw new ELException(MessageFactory.get("error.convert",
- val, String.class, type), e);
}
throw new ELException(MessageFactory.get("error.convert",
@@ -317,16 +398,17 @@
}
/**
+ * Coerce an object to a string
* @param obj
- * @return
+ * @return the String value of the object
*/
public final static String coerceToString(final Object obj) {
if (obj == null) {
return "";
} else if (obj instanceof String) {
return (String) obj;
- } else if (obj instanceof Enum) {
- return ((Enum) obj).name();
+ } else if (obj instanceof Enum<?>) {
+ return ((Enum<?>) obj).name();
} else {
return obj.toString();
}
@@ -351,8 +433,8 @@
}
}
- public final static Object coerceToType(final Object obj, final Class<?> type)
- throws ELException {
+ public final static Object coerceToType(final Object obj,
+ final Class<?> type) throws ELException {
if (type == null || Object.class.equals(type) ||
(obj != null && type.isAssignableFrom(obj.getClass()))) {
return obj;
@@ -390,8 +472,9 @@
}
/**
- * @param obj
- * @return
+ * Check if an array contains any {@code null} entries.
+ * @param obj array to be checked
+ * @return true if the array contains a {@code null}
*/
public final static boolean containsNulls(final Object[] obj) {
for (int i = 0; i < obj.length; i++) {
14 years, 10 months
JBossWeb SVN: r1387 - trunk/java/org/apache/catalina/connector.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2010-02-16 20:28:24 -0500 (Tue, 16 Feb 2010)
New Revision: 1387
Modified:
trunk/java/org/apache/catalina/connector/Request.java
Log:
- Add optional code to expose the principal associated with the session (without any auth or login, obviously).
Modified: trunk/java/org/apache/catalina/connector/Request.java
===================================================================
--- trunk/java/org/apache/catalina/connector/Request.java 2010-02-10 17:25:53 UTC (rev 1386)
+++ trunk/java/org/apache/catalina/connector/Request.java 2010-02-17 01:28:24 UTC (rev 1387)
@@ -147,7 +147,11 @@
Globals.STRICT_SERVLET_COMPLIANCE
|| Boolean.valueOf(System.getProperty("org.apache.catalina.connector.Request.CHECK_ASYNC", "true")).booleanValue();
-
+
+ protected static final boolean USE_PRINCIPAL_FROM_SESSION =
+ Boolean.valueOf(System.getProperty("org.apache.catalina.connector.Request.USE_PRINCIPAL_FROM_SESSION", "false")).booleanValue();
+
+
// ----------------------------------------------------------- Constructors
@@ -2379,7 +2383,8 @@
public boolean isUserInRole(String role) {
// Have we got an authenticated principal at all?
- if (userPrincipal == null)
+ Principal principal = doGetUserPrincipal();
+ if (principal == null)
return (false);
// Identify the Realm we will use for checking role assignmenets
@@ -2393,12 +2398,12 @@
if (wrapper != null) {
String realRole = wrapper.findSecurityReference(role);
if ((realRole != null) &&
- realm.hasRole(userPrincipal, realRole))
+ realm.hasRole(principal, realRole))
return (true);
}
// Check for a role defined directly as a <security-role>
- return (realm.hasRole(userPrincipal, role));
+ return (realm.hasRole(principal, role));
}
@@ -2415,15 +2420,30 @@
* Return the principal that has been authenticated for this Request.
*/
public Principal getUserPrincipal() {
- if (userPrincipal instanceof GenericPrincipal) {
- return ((GenericPrincipal) userPrincipal).getUserPrincipal();
+ Principal principal = doGetUserPrincipal();
+ if (principal instanceof GenericPrincipal) {
+ return ((GenericPrincipal) principal).getUserPrincipal();
} else {
- return (userPrincipal);
+ return (principal);
}
}
/**
+ * Return the principal that has been authenticated for this Request.
+ */
+ protected Principal doGetUserPrincipal() {
+ if (USE_PRINCIPAL_FROM_SESSION && userPrincipal == null) {
+ Session session = doGetSession(false);
+ Principal principal = session.getPrincipal();
+ if (principal != null)
+ return principal;
+ }
+ return userPrincipal;
+ }
+
+
+ /**
* Return the session associated with this Request, creating one
* if necessary.
*/
14 years, 10 months
JBossWeb SVN: r1386 - branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/catalina/loader.
by jbossweb-commits@lists.jboss.org
Author: jfrederic.clere(a)jboss.com
Date: 2010-02-10 12:25:53 -0500 (Wed, 10 Feb 2010)
New Revision: 1386
Modified:
branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/catalina/loader/WebappClassLoader.java
Log:
Fix for JBPAPP-3343.
Modified: branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/catalina/loader/WebappClassLoader.java
===================================================================
--- branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/catalina/loader/WebappClassLoader.java 2010-02-10 13:06:01 UTC (rev 1385)
+++ branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/catalina/loader/WebappClassLoader.java 2010-02-10 17:25:53 UTC (rev 1386)
@@ -43,6 +43,8 @@
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
import java.util.Vector;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
@@ -232,7 +234,14 @@
/**
* The list of not found resources.
*/
- protected HashMap notFoundResources = new HashMap();
+ protected HashMap<String, String> notFoundResources =
+ new LinkedHashMap<String, String>() {
+ private static final long serialVersionUID = 1L;
+ protected boolean removeEldestEntry(
+ Map.Entry<String, String> eldest) {
+ return size() > 1000;
+ }
+ };
/**
14 years, 10 months
JBossWeb SVN: r1385 - in branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/catalina: startup and 1 other directory.
by jbossweb-commits@lists.jboss.org
Author: jfrederic.clere(a)jboss.com
Date: 2010-02-10 08:06:01 -0500 (Wed, 10 Feb 2010)
New Revision: 1385
Modified:
branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/catalina/loader/LocalStrings.properties
branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/catalina/loader/WebappClassLoader.java
branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/catalina/startup/ContextConfig.java
branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/catalina/startup/ExpandWar.java
branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/catalina/startup/HostConfig.java
branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/catalina/startup/LocalStrings.properties
Log:
Port 892815 (even we don't use that part).
Modified: branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/catalina/loader/LocalStrings.properties
===================================================================
--- branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/catalina/loader/LocalStrings.properties 2010-02-10 12:44:59 UTC (rev 1384)
+++ branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/catalina/loader/LocalStrings.properties 2010-02-10 13:06:01 UTC (rev 1385)
@@ -13,7 +13,9 @@
standardLoader.removeRepository=Removing repository {0}
standardLoader.starting=Starting this Loader
standardLoader.stopping=Stopping this Loader
+webappClassLoader.illegalJarPath=Illegal JAR entry detected with name {0}
webappClassLoader.stopped=Illegal access: this web application instance has been stopped already. Could not load {0}. The eventual following stack trace is caused by an error thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access, and has no functional impact.
+webappClassLoader.validationErrorJarPath=Unable to validate JAR entry with name {0}
webappLoader.addRepository=Adding repository {0}
webappLoader.deploy=Deploying class repositories to work directory {0}
webappLoader.jarDeploy=Deploy JAR {0} to {1}
Modified: branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/catalina/loader/WebappClassLoader.java
===================================================================
--- branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/catalina/loader/WebappClassLoader.java 2010-02-10 12:44:59 UTC (rev 1384)
+++ branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/catalina/loader/WebappClassLoader.java 2010-02-10 13:06:01 UTC (rev 1385)
@@ -325,8 +325,8 @@
* Path where resources loaded from JARs will be extracted.
*/
protected File loaderDir = null;
+ protected String canonicalLoaderDir = null;
-
/**
* The PermissionCollection for each CodeSource for a web
* application context.
@@ -518,6 +518,18 @@
*/
public void setWorkDir(File workDir) {
this.loaderDir = new File(workDir, "loader");
+ if (loaderDir == null) {
+ canonicalLoaderDir = null;
+ } else {
+ try {
+ canonicalLoaderDir = loaderDir.getCanonicalPath();
+ if (!canonicalLoaderDir.endsWith(File.separator)) {
+ canonicalLoaderDir += File.separator;
+ }
+ } catch (IOException ioe) {
+ canonicalLoaderDir = null;
+ }
+ }
}
/**
@@ -2005,6 +2017,18 @@
(".class"))) {
resourceFile = new File
(loaderDir, jarEntry2.getName());
+ try {
+ if (!resourceFile.getCanonicalPath().startsWith(
+ canonicalLoaderDir)) {
+ throw new IllegalArgumentException(
+ sm.getString("webappClassLoader.illegalJarPath",
+ jarEntry2.getName()));
+ }
+ } catch (IOException ioe) {
+ throw new IllegalArgumentException(
+ sm.getString("webappClassLoader.validationErrorJarPath",
+ jarEntry2.getName()), ioe);
+ }
resourceFile.getParentFile().mkdirs();
FileOutputStream os = null;
InputStream is = null;
Modified: branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/catalina/startup/ContextConfig.java
===================================================================
--- branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/catalina/startup/ContextConfig.java 2010-02-10 12:44:59 UTC (rev 1384)
+++ branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/catalina/startup/ContextConfig.java 2010-02-10 13:06:01 UTC (rev 1385)
@@ -874,9 +874,8 @@
if (contextPath.equals("")) {
contextPath = "ROOT";
} else {
- if (contextPath.lastIndexOf('/') > 0) {
- contextPath = "/" + contextPath.substring(1).replace('/','#');
- }
+ // Context path must start with '/'
+ contextPath = "/" + contextPath.substring(1).replace('/','#');
}
if (docBase.toLowerCase().endsWith(".war") && !file.isDirectory() && unpackWARs) {
URL war = new URL("jar:" + (new File(docBase)).toURI().toURL() + "!/");
@@ -886,19 +885,24 @@
if (context instanceof StandardContext) {
((StandardContext) context).setOriginalDocBase(origDocBase);
}
+ } else if (docBase.toLowerCase().endsWith(".war") &&
+ !file.isDirectory() && !unpackWARs) {
+ URL war =
+ new URL("jar:" + (new File (docBase)).toURI().toURL() + "!/");
+ ExpandWar.validate(host, war, contextPath);
} else {
File docDir = new File(docBase);
if (!docDir.exists()) {
File warFile = new File(docBase + ".war");
+ URL war = new URL("jar:" + warFile.toURI().toURL() + "!/");
if (warFile.exists()) {
if (unpackWARs) {
- URL war =
- new URL("jar:" + warFile.toURI().toURL() + "!/");
docBase = ExpandWar.expand(host, war, contextPath);
file = new File(docBase);
docBase = file.getCanonicalPath();
} else {
docBase = warFile.getCanonicalPath();
+ ExpandWar.validate(host, war, contextPath);
}
}
if (context instanceof StandardContext) {
@@ -1259,7 +1263,8 @@
if (!docBaseFile.isAbsolute()) {
docBaseFile = new File(appBase, docBase);
}
- ExpandWar.delete(docBaseFile);
+ // No need to log failure - it is expected in this case
+ ExpandWar.delete(docBaseFile, false);
}
ok = true;
Modified: branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/catalina/startup/ExpandWar.java
===================================================================
--- branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/catalina/startup/ExpandWar.java 2010-02-10 12:44:59 UTC (rev 1384)
+++ branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/catalina/startup/ExpandWar.java 2010-02-10 13:06:01 UTC (rev 1385)
@@ -105,7 +105,8 @@
* (must start with "jar:")
* @param pathname Context path name for web application
*
- * @exception IllegalArgumentException if this is not a "jar:" URL
+ * @exception IllegalArgumentException if this is not a "jar:" URL or if the
+ * WAR file is invalid
* @exception IOException if an input/output error was encountered
* during expansion
*/
@@ -123,6 +124,7 @@
(sm.getString("hostConfig.appBase",
appBase.getAbsolutePath()));
}
+
File docBase = new File(appBase, pathname);
if (docBase.exists()) {
// War file is already installed
@@ -133,16 +135,29 @@
docBase.mkdir();
// Expand the WAR into the new document base directory
+ String canonicalDocBasePrefix = docBase.getCanonicalPath();
+ if (!canonicalDocBasePrefix.endsWith(File.separator)) {
+ canonicalDocBasePrefix += File.separator;
+ }
JarURLConnection juc = (JarURLConnection) war.openConnection();
juc.setUseCaches(false);
JarFile jarFile = null;
InputStream input = null;
+ boolean success = false;
try {
jarFile = juc.getJarFile();
Enumeration jarEntries = jarFile.entries();
while (jarEntries.hasMoreElements()) {
JarEntry jarEntry = (JarEntry) jarEntries.nextElement();
String name = jarEntry.getName();
+ File expandedFile = new File(docBase, name);
+ if (!expandedFile.getCanonicalPath().startsWith(
+ canonicalDocBasePrefix)) {
+ // Trying to expand outside the docBase
+ // Throw an exception to stop the deployment
+ throw new IllegalArgumentException(
+ sm.getString("expandWar.illegalPath",war, name));
+ }
int last = name.lastIndexOf('/');
if (last >= 0) {
File parent = new File(docBase,
@@ -155,21 +170,24 @@
input = jarFile.getInputStream(jarEntry);
// Bugzilla 33636
- File expandedFile = expand(input, docBase, name);
+ expand(input, expandedFile);
long lastModified = jarEntry.getTime();
- if ((lastModified != -1) && (lastModified != 0) && (expandedFile != null)) {
+ if ((lastModified != -1) && (lastModified != 0)) {
expandedFile.setLastModified(lastModified);
}
input.close();
input = null;
}
+ success = true;
} catch (IOException e) {
- // If something went wrong, delete expanded dir to keep things
- // clean
- deleteDir(docBase);
throw e;
} finally {
+ if (!success) {
+ // If something went wrong, delete expanded dir to keep things
+ // clean
+ deleteDir(docBase);
+ }
if (input != null) {
try {
input.close();
@@ -195,6 +213,69 @@
/**
+ * Validate the WAR file found at the specified URL.
+ *
+ * @param host Host war is being installed for
+ * @param war URL of the web application archive to be validated
+ * (must start with "jar:")
+ * @param pathname Context path name for web application
+ *
+ * @exception IllegalArgumentException if this is not a "jar:" URL or if the
+ * WAR file is invalid
+ * @exception IOException if an input/output error was encountered
+ * during validation
+ */
+ public static void validate(Host host, URL war, String pathname)
+ throws IOException {
+
+ // Make the appBase absolute
+ File appBase = new File(host.getAppBase());
+ if (!appBase.isAbsolute()) {
+ appBase = new File(System.getProperty("catalina.base"),
+ host.getAppBase());
+ }
+
+ File docBase = new File(appBase, pathname);
+
+ // Calculate the document base directory
+ String canonicalDocBasePrefix = docBase.getCanonicalPath();
+ if (!canonicalDocBasePrefix.endsWith(File.separator)) {
+ canonicalDocBasePrefix += File.separator;
+ }
+ JarURLConnection juc = (JarURLConnection) war.openConnection();
+ juc.setUseCaches(false);
+ JarFile jarFile = null;
+ try {
+ jarFile = juc.getJarFile();
+ Enumeration<JarEntry> jarEntries = jarFile.entries();
+ while (jarEntries.hasMoreElements()) {
+ JarEntry jarEntry = jarEntries.nextElement();
+ String name = jarEntry.getName();
+ File expandedFile = new File(docBase, name);
+ if (!expandedFile.getCanonicalPath().startsWith(
+ canonicalDocBasePrefix)) {
+ // Entry located outside the docBase
+ // Throw an exception to stop the deployment
+ throw new IllegalArgumentException(
+ sm.getString("expandWar.illegalPath",war, name));
+ }
+ }
+ } catch (IOException e) {
+ throw e;
+ } finally {
+ if (jarFile != null) {
+ try {
+ jarFile.close();
+ } catch (Throwable t) {
+ // Ignore
+ }
+ jarFile = null;
+ }
+ }
+ }
+
+
+ /**
* Copy the specified file or directory to the destination.
*
* @param src File object representing the source
@@ -254,27 +335,62 @@
/**
* Delete the specified directory, including all of its contents and
- * subdirectories recursively.
+ * sub-directories recursively. Any failure will be logged.
*
* @param dir File object representing the directory to be deleted
*/
public static boolean delete(File dir) {
+ // Log failure by default
+ return delete(dir, true);
+ }
+
+ /**
+ * Delete the specified directory, including all of its contents and
+ * sub-directories recursively.
+ *
+ * @param dir File object representing the directory to be deleted
+ * @param logFailure <code>true</code> if failure to delete the resource
+ * should be logged
+ */
+ public static boolean delete(File dir, boolean logFailure) {
+ boolean result;
if (dir.isDirectory()) {
- return deleteDir(dir);
+ result = deleteDir(dir, logFailure);
} else {
- return dir.delete();
+ if (dir.exists()) {
+ result = dir.delete();
+ } else {
+ result = true;
+ }
}
+ if (logFailure && !result) {
+ log.error(sm.getString(
+ "expandWar.deleteFailed", dir.getAbsolutePath()));
+ }
+ return result;
}
/**
* Delete the specified directory, including all of its contents and
- * subdirectories recursively.
+ * sub-directories recursively. Any failure will be logged.
*
* @param dir File object representing the directory to be deleted
*/
public static boolean deleteDir(File dir) {
+ return deleteDir(dir, true);
+ }
+ /**
+ * Delete the specified directory, including all of its contents and
+ * sub-directories recursively.
+ *
+ * @param dir File object representing the directory to be deleted
+ * @param logFailure <code>true</code> if failure to delete the resource
+ * should be logged
+ */
+ public static boolean deleteDir(File dir, boolean logFailure) {
+
String files[] = dir.list();
if (files == null) {
files = new String[0];
@@ -282,13 +398,26 @@
for (int i = 0; i < files.length; i++) {
File file = new File(dir, files[i]);
if (file.isDirectory()) {
- deleteDir(file);
+ deleteDir(file, logFailure);
} else {
file.delete();
}
}
- return dir.delete();
+ boolean result;
+ if (dir.exists()) {
+ result = dir.delete();
+ } else {
+ result = true;
+ }
+
+ if (logFailure && !result) {
+ log.error(sm.getString(
+ "expandWar.deleteFailed", dir.getAbsolutePath()));
+ }
+
+ return result;
+
}
@@ -302,11 +431,27 @@
* @return A handle to the expanded File
*
* @exception IOException if an input/output error occurs
+ *
+ * @deprecated
*/
protected static File expand(InputStream input, File docBase, String name)
throws IOException {
+ File file = new File(docBase, name);
+ expand(input, file);
+ return file;
+ }
- File file = new File(docBase, name);
+
+ /**
+ * Expand the specified input stream into the specified file.
+ *
+ * @param input InputStream to be copied
+ * @param file The file to be created
+ *
+ * @exception IOException if an input/output error occurs
+ */
+ private static void expand(InputStream input, File file)
+ throws IOException {
BufferedOutputStream output = null;
try {
output =
@@ -327,8 +472,6 @@
}
}
}
-
- return file;
}
Modified: branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/catalina/startup/HostConfig.java
===================================================================
--- branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/catalina/startup/HostConfig.java 2010-02-10 12:44:59 UTC (rev 1384)
+++ branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/catalina/startup/HostConfig.java 2010-02-10 13:06:01 UTC (rev 1385)
@@ -26,7 +26,9 @@
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.LinkedHashMap;
+import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
@@ -149,6 +151,11 @@
*/
protected static Digester digester = createDigester();
+ /**
+ * The list of Wars in the appBase to be ignored because they are invalid
+ * (e.g. contain /../ sequences).
+ */
+ protected Set<String> invalidWars = new HashSet<String>();
// ------------------------------------------------------------- Properties
@@ -696,13 +703,23 @@
if (files[i].equalsIgnoreCase("WEB-INF"))
continue;
File dir = new File(appBase, files[i]);
- if (files[i].toLowerCase().endsWith(".war")) {
+ if (files[i].toLowerCase().endsWith(".war") && dir.isFile()
+ && !invalidWars.contains(files[i]) ) {
// Calculate the context path and make sure it is unique
String contextPath = "/" + files[i].replace('#','/');
int period = contextPath.lastIndexOf(".");
if (period >= 0)
contextPath = contextPath.substring(0, period);
+
+ // Check for WARs with /../ /./ or similar sequences in the name
+ if (!validateContextPath(appBase, contextPath)) {
+ log.error(sm.getString(
+ "hostConfig.illegalWarName", files[i]));
+ invalidWars.add(files[i]);
+ continue;
+ }
+
if (contextPath.equals("/ROOT"))
contextPath = "";
@@ -720,6 +737,42 @@
}
+ private boolean validateContextPath(File appBase, String contextPath) {
+ // More complicated than the ideal as the canonical path may or may
+ // not end with File.separator for a directory
+
+ StringBuilder docBase;
+ String canonicalDocBase = null;
+
+ try {
+ String canonicalAppBase = appBase.getCanonicalPath();
+ docBase = new StringBuilder(canonicalAppBase);
+ if (canonicalAppBase.endsWith(File.separator)) {
+ docBase.append(contextPath.substring(1).replace(
+ '/', File.separatorChar));
+ } else {
+ docBase.append(contextPath.replace('/', File.separatorChar));
+ }
+ // At this point docBase should be canonical but will not end
+ // with File.separator
+
+ canonicalDocBase =
+ (new File(docBase.toString())).getCanonicalPath();
+
+ // If the canonicalDocBase ends with File.separator, add one to
+ // docBase before they are compared
+ if (canonicalDocBase.endsWith(File.separator)) {
+ docBase.append(File.separator);
+ }
+ } catch (IOException ioe) {
+ return false;
+ }
+
+ // Compare the two. If they are not the same, the contextPath must
+ // have /../ like sequences in it
+ return canonicalDocBase.equals(docBase.toString());
+ }
+
/**
* @param contextPath
* @param dir
Modified: branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/catalina/startup/LocalStrings.properties
===================================================================
--- branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/catalina/startup/LocalStrings.properties 2010-02-10 12:44:59 UTC (rev 1384)
+++ branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/catalina/startup/LocalStrings.properties 2010-02-10 13:06:01 UTC (rev 1385)
@@ -42,6 +42,8 @@
engineConfig.start=EngineConfig: Processing START
engineConfig.stop=EngineConfig: Processing STOP
expandWar.copy=Error copying {0} to {1}
+expandWar.deleteFailed=[{0}] could not be completely deleted. The presence of the remaining files may cause problems
+expandWar.illegalPath=The archive [{0}] is malformed and will be ignored: an entry contains an illegal path [{1}]
hostConfig.appBase=Application base directory {0} does not exist
hostConfig.canonicalizing=Error delete redeploy resources from context [{0}]
hostConfig.cce=Lifecycle event data object {0} is not a Host
@@ -61,6 +63,7 @@
hostConfig.expand=Expanding web application archive {0}
hostConfig.expand.error=Exception while expanding web application archive {0}
hostConfig.expanding=Expanding discovered web application archives
+hostConfig.illegalWarName=The war name [{0}] is invalid. The archive will be ignored.
hostConfig.jmx.register=Register context [{0}] failed
hostConfig.jmx.unregister=Unregister context [{0}] failed
hostConfig.reload=Reloading context [{0}]
14 years, 10 months
JBossWeb SVN: r1384 - in branches/2.1.x: java/org/apache/catalina/startup and 1 other directories.
by jbossweb-commits@lists.jboss.org
Author: jfrederic.clere(a)jboss.com
Date: 2010-02-10 07:44:59 -0500 (Wed, 10 Feb 2010)
New Revision: 1384
Modified:
branches/2.1.x/java/org/apache/catalina/loader/LocalStrings.properties
branches/2.1.x/java/org/apache/catalina/loader/WebappClassLoader.java
branches/2.1.x/java/org/apache/catalina/startup/ContextConfig.java
branches/2.1.x/java/org/apache/catalina/startup/ExpandWar.java
branches/2.1.x/java/org/apache/catalina/startup/HostConfig.java
branches/2.1.x/java/org/apache/catalina/startup/LocalStrings.properties
branches/2.1.x/webapps/docs/changelog.xml
Log:
Port 892815 (even we don't use that part).
Modified: branches/2.1.x/java/org/apache/catalina/loader/LocalStrings.properties
===================================================================
--- branches/2.1.x/java/org/apache/catalina/loader/LocalStrings.properties 2010-02-10 12:35:31 UTC (rev 1383)
+++ branches/2.1.x/java/org/apache/catalina/loader/LocalStrings.properties 2010-02-10 12:44:59 UTC (rev 1384)
@@ -13,7 +13,9 @@
standardLoader.removeRepository=Removing repository {0}
standardLoader.starting=Starting this Loader
standardLoader.stopping=Stopping this Loader
+webappClassLoader.illegalJarPath=Illegal JAR entry detected with name {0}
webappClassLoader.stopped=Illegal access: this web application instance has been stopped already. Could not load {0}. The eventual following stack trace is caused by an error thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access, and has no functional impact.
+webappClassLoader.validationErrorJarPath=Unable to validate JAR entry with name {0}
webappLoader.addRepository=Adding repository {0}
webappLoader.deploy=Deploying class repositories to work directory {0}
webappLoader.jarDeploy=Deploy JAR {0} to {1}
Modified: branches/2.1.x/java/org/apache/catalina/loader/WebappClassLoader.java
===================================================================
--- branches/2.1.x/java/org/apache/catalina/loader/WebappClassLoader.java 2010-02-10 12:35:31 UTC (rev 1383)
+++ branches/2.1.x/java/org/apache/catalina/loader/WebappClassLoader.java 2010-02-10 12:44:59 UTC (rev 1384)
@@ -324,8 +324,8 @@
* Path where resources loaded from JARs will be extracted.
*/
protected File loaderDir = null;
+ protected String canonicalLoaderDir = null;
-
/**
* The PermissionCollection for each CodeSource for a web
* application context.
@@ -517,6 +517,18 @@
*/
public void setWorkDir(File workDir) {
this.loaderDir = new File(workDir, "loader");
+ if (loaderDir == null) {
+ canonicalLoaderDir = null;
+ } else {
+ try {
+ canonicalLoaderDir = loaderDir.getCanonicalPath();
+ if (!canonicalLoaderDir.endsWith(File.separator)) {
+ canonicalLoaderDir += File.separator;
+ }
+ } catch (IOException ioe) {
+ canonicalLoaderDir = null;
+ }
+ }
}
/**
@@ -2003,6 +2015,18 @@
(".class"))) {
resourceFile = new File
(loaderDir, jarEntry2.getName());
+ try {
+ if (!resourceFile.getCanonicalPath().startsWith(
+ canonicalLoaderDir)) {
+ throw new IllegalArgumentException(
+ sm.getString("webappClassLoader.illegalJarPath",
+ jarEntry2.getName()));
+ }
+ } catch (IOException ioe) {
+ throw new IllegalArgumentException(
+ sm.getString("webappClassLoader.validationErrorJarPath",
+ jarEntry2.getName()), ioe);
+ }
resourceFile.getParentFile().mkdirs();
FileOutputStream os = null;
InputStream is = null;
Modified: branches/2.1.x/java/org/apache/catalina/startup/ContextConfig.java
===================================================================
--- branches/2.1.x/java/org/apache/catalina/startup/ContextConfig.java 2010-02-10 12:35:31 UTC (rev 1383)
+++ branches/2.1.x/java/org/apache/catalina/startup/ContextConfig.java 2010-02-10 12:44:59 UTC (rev 1384)
@@ -874,9 +874,8 @@
if (contextPath.equals("")) {
contextPath = "ROOT";
} else {
- if (contextPath.lastIndexOf('/') > 0) {
- contextPath = "/" + contextPath.substring(1).replace('/','#');
- }
+ // Context path must start with '/'
+ contextPath = "/" + contextPath.substring(1).replace('/','#');
}
if (docBase.toLowerCase().endsWith(".war") && !file.isDirectory() && unpackWARs) {
URL war = new URL("jar:" + (new File(docBase)).toURI().toURL() + "!/");
@@ -886,18 +885,24 @@
if (context instanceof StandardContext) {
((StandardContext) context).setOriginalDocBase(origDocBase);
}
+ } else if (docBase.toLowerCase().endsWith(".war") &&
+ !file.isDirectory() && !unpackWARs) {
+ URL war =
+ new URL("jar:" + (new File (docBase)).toURI().toURL() + "!/");
+ ExpandWar.validate(host, war, contextPath);
} else {
File docDir = new File(docBase);
if (!docDir.exists()) {
File warFile = new File(docBase + ".war");
+ URL war = new URL("jar:" + warFile.toURI().toURL() + "!/");
if (warFile.exists()) {
if (unpackWARs) {
- URL war = new URL("jar:" + warFile.toURI().toURL() + "!/");
docBase = ExpandWar.expand(host, war, contextPath);
file = new File(docBase);
docBase = file.getCanonicalPath();
} else {
docBase = warFile.getCanonicalPath();
+ ExpandWar.validate(host, war, contextPath);
}
}
if (context instanceof StandardContext) {
@@ -1258,7 +1263,8 @@
if (!docBaseFile.isAbsolute()) {
docBaseFile = new File(appBase, docBase);
}
- ExpandWar.delete(docBaseFile);
+ // No need to log failure - it is expected in this case
+ ExpandWar.delete(docBaseFile, false);
}
ok = true;
Modified: branches/2.1.x/java/org/apache/catalina/startup/ExpandWar.java
===================================================================
--- branches/2.1.x/java/org/apache/catalina/startup/ExpandWar.java 2010-02-10 12:35:31 UTC (rev 1383)
+++ branches/2.1.x/java/org/apache/catalina/startup/ExpandWar.java 2010-02-10 12:44:59 UTC (rev 1384)
@@ -105,7 +105,8 @@
* (must start with "jar:")
* @param pathname Context path name for web application
*
- * @exception IllegalArgumentException if this is not a "jar:" URL
+ * @exception IllegalArgumentException if this is not a "jar:" URL or if the
+ * WAR file is invalid
* @exception IOException if an input/output error was encountered
* during expansion
*/
@@ -123,6 +124,7 @@
(sm.getString("hostConfig.appBase",
appBase.getAbsolutePath()));
}
+
File docBase = new File(appBase, pathname);
if (docBase.exists()) {
// War file is already installed
@@ -133,16 +135,29 @@
docBase.mkdir();
// Expand the WAR into the new document base directory
+ String canonicalDocBasePrefix = docBase.getCanonicalPath();
+ if (!canonicalDocBasePrefix.endsWith(File.separator)) {
+ canonicalDocBasePrefix += File.separator;
+ }
JarURLConnection juc = (JarURLConnection) war.openConnection();
juc.setUseCaches(false);
JarFile jarFile = null;
InputStream input = null;
+ boolean success = false;
try {
jarFile = juc.getJarFile();
Enumeration jarEntries = jarFile.entries();
while (jarEntries.hasMoreElements()) {
JarEntry jarEntry = (JarEntry) jarEntries.nextElement();
String name = jarEntry.getName();
+ File expandedFile = new File(docBase, name);
+ if (!expandedFile.getCanonicalPath().startsWith(
+ canonicalDocBasePrefix)) {
+ // Trying to expand outside the docBase
+ // Throw an exception to stop the deployment
+ throw new IllegalArgumentException(
+ sm.getString("expandWar.illegalPath",war, name));
+ }
int last = name.lastIndexOf('/');
if (last >= 0) {
File parent = new File(docBase,
@@ -155,21 +170,24 @@
input = jarFile.getInputStream(jarEntry);
// Bugzilla 33636
- File expandedFile = expand(input, docBase, name);
+ expand(input, expandedFile);
long lastModified = jarEntry.getTime();
- if ((lastModified != -1) && (lastModified != 0) && (expandedFile != null)) {
+ if ((lastModified != -1) && (lastModified != 0)) {
expandedFile.setLastModified(lastModified);
}
input.close();
input = null;
}
+ success = true;
} catch (IOException e) {
- // If something went wrong, delete expanded dir to keep things
- // clean
- deleteDir(docBase);
throw e;
} finally {
+ if (!success) {
+ // If something went wrong, delete expanded dir to keep things
+ // clean
+ deleteDir(docBase);
+ }
if (input != null) {
try {
input.close();
@@ -195,6 +213,69 @@
/**
+ * Validate the WAR file found at the specified URL.
+ *
+ * @param host Host war is being installed for
+ * @param war URL of the web application archive to be validated
+ * (must start with "jar:")
+ * @param pathname Context path name for web application
+ *
+ * @exception IllegalArgumentException if this is not a "jar:" URL or if the
+ * WAR file is invalid
+ * @exception IOException if an input/output error was encountered
+ * during validation
+ */
+ public static void validate(Host host, URL war, String pathname)
+ throws IOException {
+
+ // Make the appBase absolute
+ File appBase = new File(host.getAppBase());
+ if (!appBase.isAbsolute()) {
+ appBase = new File(System.getProperty("catalina.base"),
+ host.getAppBase());
+ }
+
+ File docBase = new File(appBase, pathname);
+
+ // Calculate the document base directory
+ String canonicalDocBasePrefix = docBase.getCanonicalPath();
+ if (!canonicalDocBasePrefix.endsWith(File.separator)) {
+ canonicalDocBasePrefix += File.separator;
+ }
+ JarURLConnection juc = (JarURLConnection) war.openConnection();
+ juc.setUseCaches(false);
+ JarFile jarFile = null;
+ try {
+ jarFile = juc.getJarFile();
+ Enumeration<JarEntry> jarEntries = jarFile.entries();
+ while (jarEntries.hasMoreElements()) {
+ JarEntry jarEntry = jarEntries.nextElement();
+ String name = jarEntry.getName();
+ File expandedFile = new File(docBase, name);
+ if (!expandedFile.getCanonicalPath().startsWith(
+ canonicalDocBasePrefix)) {
+ // Entry located outside the docBase
+ // Throw an exception to stop the deployment
+ throw new IllegalArgumentException(
+ sm.getString("expandWar.illegalPath",war, name));
+ }
+ }
+ } catch (IOException e) {
+ throw e;
+ } finally {
+ if (jarFile != null) {
+ try {
+ jarFile.close();
+ } catch (Throwable t) {
+ // Ignore
+ }
+ jarFile = null;
+ }
+ }
+ }
+
+
+ /**
* Copy the specified file or directory to the destination.
*
* @param src File object representing the source
@@ -254,27 +335,62 @@
/**
* Delete the specified directory, including all of its contents and
- * subdirectories recursively.
+ * sub-directories recursively. Any failure will be logged.
*
* @param dir File object representing the directory to be deleted
*/
public static boolean delete(File dir) {
+ // Log failure by default
+ return delete(dir, true);
+ }
+
+ /**
+ * Delete the specified directory, including all of its contents and
+ * sub-directories recursively.
+ *
+ * @param dir File object representing the directory to be deleted
+ * @param logFailure <code>true</code> if failure to delete the resource
+ * should be logged
+ */
+ public static boolean delete(File dir, boolean logFailure) {
+ boolean result;
if (dir.isDirectory()) {
- return deleteDir(dir);
+ result = deleteDir(dir, logFailure);
} else {
- return dir.delete();
+ if (dir.exists()) {
+ result = dir.delete();
+ } else {
+ result = true;
+ }
}
+ if (logFailure && !result) {
+ log.error(sm.getString(
+ "expandWar.deleteFailed", dir.getAbsolutePath()));
+ }
+ return result;
}
/**
* Delete the specified directory, including all of its contents and
- * subdirectories recursively.
+ * sub-directories recursively. Any failure will be logged.
*
* @param dir File object representing the directory to be deleted
*/
public static boolean deleteDir(File dir) {
+ return deleteDir(dir, true);
+ }
+ /**
+ * Delete the specified directory, including all of its contents and
+ * sub-directories recursively.
+ *
+ * @param dir File object representing the directory to be deleted
+ * @param logFailure <code>true</code> if failure to delete the resource
+ * should be logged
+ */
+ public static boolean deleteDir(File dir, boolean logFailure) {
+
String files[] = dir.list();
if (files == null) {
files = new String[0];
@@ -282,13 +398,26 @@
for (int i = 0; i < files.length; i++) {
File file = new File(dir, files[i]);
if (file.isDirectory()) {
- deleteDir(file);
+ deleteDir(file, logFailure);
} else {
file.delete();
}
}
- return dir.delete();
+ boolean result;
+ if (dir.exists()) {
+ result = dir.delete();
+ } else {
+ result = true;
+ }
+
+ if (logFailure && !result) {
+ log.error(sm.getString(
+ "expandWar.deleteFailed", dir.getAbsolutePath()));
+ }
+
+ return result;
+
}
@@ -302,11 +431,27 @@
* @return A handle to the expanded File
*
* @exception IOException if an input/output error occurs
+ *
+ * @deprecated
*/
protected static File expand(InputStream input, File docBase, String name)
throws IOException {
+ File file = new File(docBase, name);
+ expand(input, file);
+ return file;
+ }
- File file = new File(docBase, name);
+
+ /**
+ * Expand the specified input stream into the specified file.
+ *
+ * @param input InputStream to be copied
+ * @param file The file to be created
+ *
+ * @exception IOException if an input/output error occurs
+ */
+ private static void expand(InputStream input, File file)
+ throws IOException {
BufferedOutputStream output = null;
try {
output =
@@ -327,8 +472,6 @@
}
}
}
-
- return file;
}
Modified: branches/2.1.x/java/org/apache/catalina/startup/HostConfig.java
===================================================================
--- branches/2.1.x/java/org/apache/catalina/startup/HostConfig.java 2010-02-10 12:35:31 UTC (rev 1383)
+++ branches/2.1.x/java/org/apache/catalina/startup/HostConfig.java 2010-02-10 12:44:59 UTC (rev 1384)
@@ -28,7 +28,9 @@
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.LinkedHashMap;
+import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
@@ -153,6 +155,11 @@
*/
protected static Digester digester = createDigester();
+ /**
+ * The list of Wars in the appBase to be ignored because they are invalid
+ * (e.g. contain /../ sequences).
+ */
+ protected Set<String> invalidWars = new HashSet<String>();
// ------------------------------------------------------------- Properties
@@ -708,13 +715,22 @@
if (files[i].equalsIgnoreCase("WEB-INF"))
continue;
File dir = new File(appBase, files[i]);
- if (files[i].toLowerCase().endsWith(".war") && dir.isFile()) {
+ if (files[i].toLowerCase().endsWith(".war") && dir.isFile()
+ && !invalidWars.contains(files[i]) ) {
// Calculate the context path and make sure it is unique
String contextPath = "/" + files[i].replace('#','/');
int period = contextPath.lastIndexOf(".");
- if (period >= 0)
- contextPath = contextPath.substring(0, period);
+ contextPath = contextPath.substring(0, period);
+
+ // Check for WARs with /../ /./ or similar sequences in the name
+ if (!validateContextPath(appBase, contextPath)) {
+ log.error(sm.getString(
+ "hostConfig.illegalWarName", files[i]));
+ invalidWars.add(files[i]);
+ continue;
+ }
+
if (contextPath.equals("/ROOT"))
contextPath = "";
@@ -732,6 +748,42 @@
}
+ private boolean validateContextPath(File appBase, String contextPath) {
+ // More complicated than the ideal as the canonical path may or may
+ // not end with File.separator for a directory
+
+ StringBuilder docBase;
+ String canonicalDocBase = null;
+
+ try {
+ String canonicalAppBase = appBase.getCanonicalPath();
+ docBase = new StringBuilder(canonicalAppBase);
+ if (canonicalAppBase.endsWith(File.separator)) {
+ docBase.append(contextPath.substring(1).replace(
+ '/', File.separatorChar));
+ } else {
+ docBase.append(contextPath.replace('/', File.separatorChar));
+ }
+ // At this point docBase should be canonical but will not end
+ // with File.separator
+
+ canonicalDocBase =
+ (new File(docBase.toString())).getCanonicalPath();
+
+ // If the canonicalDocBase ends with File.separator, add one to
+ // docBase before they are compared
+ if (canonicalDocBase.endsWith(File.separator)) {
+ docBase.append(File.separator);
+ }
+ } catch (IOException ioe) {
+ return false;
+ }
+
+ // Compare the two. If they are not the same, the contextPath must
+ // have /../ like sequences in it
+ return canonicalDocBase.equals(docBase.toString());
+ }
+
/**
* @param contextPath
* @param war
Modified: branches/2.1.x/java/org/apache/catalina/startup/LocalStrings.properties
===================================================================
--- branches/2.1.x/java/org/apache/catalina/startup/LocalStrings.properties 2010-02-10 12:35:31 UTC (rev 1383)
+++ branches/2.1.x/java/org/apache/catalina/startup/LocalStrings.properties 2010-02-10 12:44:59 UTC (rev 1384)
@@ -42,6 +42,8 @@
engineConfig.start=EngineConfig: Processing START
engineConfig.stop=EngineConfig: Processing STOP
expandWar.copy=Error copying {0} to {1}
+expandWar.deleteFailed=[{0}] could not be completely deleted. The presence of the remaining files may cause problems
+expandWar.illegalPath=The archive [{0}] is malformed and will be ignored: an entry contains an illegal path [{1}]
hostConfig.appBase=Application base directory {0} does not exist
hostConfig.canonicalizing=Error delete redeploy resources from context [{0}]
hostConfig.cce=Lifecycle event data object {0} is not a Host
@@ -61,6 +63,7 @@
hostConfig.expand=Expanding web application archive {0}
hostConfig.expand.error=Exception while expanding web application archive {0}
hostConfig.expanding=Expanding discovered web application archives
+hostConfig.illegalWarName=The war name [{0}] is invalid. The archive will be ignored.
hostConfig.jmx.register=Register context [{0}] failed
hostConfig.jmx.unregister=Unregister context [{0}] failed
hostConfig.reload=Reloading context [{0}]
Modified: branches/2.1.x/webapps/docs/changelog.xml
===================================================================
--- branches/2.1.x/webapps/docs/changelog.xml 2010-02-10 12:35:31 UTC (rev 1383)
+++ branches/2.1.x/webapps/docs/changelog.xml 2010-02-10 12:44:59 UTC (rev 1384)
@@ -85,6 +85,12 @@
<add>
Add the PING/PING_RSP logic to cluster listener. (jfclere)
</add>
+ <fix>
+ Various (un)deployment related improvements including better handling of
+ failed (un)deployment, additional checking for valid zip entries that
+ don't make sense in a WAR and improved validation of WAR file names.
+ (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Coyote">
14 years, 10 months