Author: schultz
Date: Wed Jun 6 20:17:43 2012
New Revision: 1347095
URL: http://svn.apache.org/viewvc?rev=1347095&view=rev
Log:
Back-port of r1347087 from trunk.
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=53373
Trim whitespace from around <Context> aliases delimiters (,=) to improve
readability of many aliases.
Modified:
tomcat/tc7.0.x/trunk/ (props changed)
tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/BaseDirContext.java
tomcat/tc7.0.x/trunk/test/org/apache/naming/resources/TestNamingContext.java
tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml
tomcat/tc7.0.x/trunk/webapps/docs/config/context.xml
Propchange: tomcat/tc7.0.x/trunk/
------------------------------------------------------------------------------
Merged /tomcat/trunk:r1347087
Modified:
tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/BaseDirContext.java
URL:
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/BaseDirContext.java?rev=1347095&r1=1347094&r2=1347095&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/BaseDirContext.java
(original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/BaseDirContext.java
Wed Jun 6 20:17:43 2012
@@ -242,8 +242,21 @@ public abstract class BaseDirContext imp
String[] kvps = theAliases.split(",");
for (String kvp : kvps) {
+ // Skip blanks introduced by regexp split and/or poor input
+ kvp = kvp.trim();
+ if(0 == kvp.length())
+ continue;
+
String[] kv = kvp.split("=");
- if (kv.length != 2 || kv[0].length() == 0 || kv[1].length() == 0)
+ if (kv.length != 2)
+ throw new IllegalArgumentException(
+ sm.getString("resources.invalidAliasMapping", kvp));
+
+ // Trim whitespace from key and value
+ kv[0] = kv[0].trim();
+ kv[1] = kv[1].trim();
+
+ if(kv[0].length() == 0 || kv[1].length() == 0)
throw new IllegalArgumentException(
sm.getString("resources.invalidAliasMapping", kvp));
Modified:
tomcat/tc7.0.x/trunk/test/org/apache/naming/resources/TestNamingContext.java
URL:
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/test/org/apache/naming/resources/TestNamingContext.java?rev=1347095&r1=1347094&r2=1347095&view=diff
==============================================================================
---
tomcat/tc7.0.x/trunk/test/org/apache/naming/resources/TestNamingContext.java
(original)
+++
tomcat/tc7.0.x/trunk/test/org/apache/naming/resources/TestNamingContext.java
Wed Jun 6 20:17:43 2012
@@ -16,6 +16,8 @@
*/
package org.apache.naming.resources;
+import java.io.File;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
@@ -30,6 +32,8 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import junit.framework.Assert;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -89,6 +93,142 @@ public class TestNamingContext extends T
}
+ // Recursively deletes a directory and its contents
+ private boolean rmdir(File dir)
+ {
+ if(!dir.exists()) return false;
+ if(!dir.isDirectory()) return false;
+
+ File[] files = dir.listFiles();
+ if(null != files) {
+ for(int i=0; i<files.length; ++i) {
+ if(files[i].isDirectory())
+ {
+ if(!rmdir(files[i])) {
+ return false;
+ }
+ } else {
+ if(!files[i].delete()) {
+ return false;
+ }
+ }
+ }
+ }
+ return dir.delete();
+ }
+
+ @Test
+ public void testAliases() throws Exception
+ {
+ // Some sample text
+ String foxText = "The quick brown fox jumps over the lazy dog";
+ String loremIpsum = "Lorem ipsum dolor sit amet, consectetur
adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
aliqua.";
+
+ // Set up a temporary docBase and some alternates that we can
+ // set up as aliases.
+ File tmpDir = new File(System.getProperty("java.io.tmpdir"),
+ "tomcat-unit-test." +
TestNamingContext.class.getName());
+
+ if(tmpDir.exists())
+ {
+ // Remove any old test files
+ if(tmpDir.isDirectory()) {
+ if(!rmdir(tmpDir))
+ throw new IOException("Could not delete old temp
directory: " + tmpDir);
+ } else {
+ if(!tmpDir.delete())
+ throw new IOException("Could not delete old temp file: " +
tmpDir);
+ }
+ }
+ File docBase = new File(tmpDir, "docBase");
+ File alternate1 = new File(tmpDir, "alternate1");
+ File alternate2 = new File(tmpDir, "alternate2");
+
+ if(!tmpDir.mkdirs())
+ throw new IOException("Could not create temp directory " + tmpDir);
+ if(!docBase.mkdir())
+ throw new IOException("Could not create temp directory " +
docBase);
+ if(!alternate1.mkdir())
+ throw new IOException("Could not create temp directory " +
alternate1);
+ if(!alternate2.mkdir())
+ throw new IOException("Could not create temp directory " +
alternate2);
+
+ // Create a file in each alternate directory that we can attempt to
access
+ FileOutputStream fos = new FileOutputStream(new File(alternate1,
"test1.txt"));
+ fos.write(foxText.getBytes("UTF-8"));
+ fos.flush(); fos.close();
+
+ fos = new FileOutputStream(new File(alternate2, "test2.txt"));
+ fos.write(loremIpsum.getBytes("UTF-8"));
+ fos.flush(); fos.close();
+
+ // Finally, create the Context
+ FileDirContext ctx = new FileDirContext();
+ ctx.setDocBase(docBase.getCanonicalPath());
+ ctx.setAliases("/a1=" + alternate1.getCanonicalPath()
+ +",/a2=" + alternate2.getCanonicalPath());
+
+ // Check first alias
+ Object file = ctx.lookup("/a1/test1.txt");
+
+ Assert.assertNotNull(file);
+ Assert.assertTrue(file instanceof Resource);
+
+ byte[] buffer = new byte[4096];
+ Resource res = (Resource)file;
+
+ int len = res.streamContent().read(buffer);
+ String contents = new String(buffer, 0, len, "UTF-8");
+
+ assertEquals(foxText, contents);
+
+ // Check second alias
+ file = ctx.lookup("/a2/test2.txt");
+
+ Assert.assertNotNull(file);
+ Assert.assertTrue(file instanceof Resource);
+
+ res = (Resource)file;
+ len = res.streamContent().read(buffer);
+ contents = new String(buffer, 0, len, "UTF-8");
+
+ assertEquals(loremIpsum, contents);
+
+ // Test aliases with spaces around the separators
+ ctx.setAliases(" /a1= " + alternate1.getCanonicalPath()
+ + "\n\n"
+ +", /a2 =\n" + alternate2.getCanonicalPath()
+ + ",");
+
+ // Check first alias
+ file = ctx.lookup("/a1/test1.txt");
+
+ Assert.assertNotNull(file);
+ Assert.assertTrue(file instanceof Resource);
+
+ res = (Resource)file;
+ len = res.streamContent().read(buffer);
+ contents = new String(buffer, 0, len, "UTF-8");
+
+ assertEquals(foxText, contents);
+
+ // Check second alias
+ file = ctx.lookup("/a2/test2.txt");
+
+ Assert.assertNotNull(file);
+ Assert.assertTrue(file instanceof Resource);
+
+ res = (Resource)file;
+ len = res.streamContent().read(buffer);
+ contents = new String(buffer, 0, len, "UTF-8");
+
+ assertEquals(loremIpsum, contents);
+
+ // Clean-up
+ if(!rmdir(tmpDir))
+ throw new IOException("Could not clean-up temp directory" +
tmpDir);
+ }
+
public static final class Bug49994Servlet extends HttpServlet {
private static final long serialVersionUID = 1L;
Modified: tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml
URL:
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml?rev=1347095&r1=1347094&r2=1347095&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Wed Jun 6 20:17:43 2012
@@ -225,6 +225,10 @@
applications to use WebSocket when running under a security manager.
(markt/kkolinko)
</fix>
+ <fix>
+ <bug>53373</bug>: Allow whitespace around delimiters in <Context>
+ aliases for readability. (schultz)
+ </fix>
</changelog>
</subsection>
<subsection name="Coyote">
Modified: tomcat/tc7.0.x/trunk/webapps/docs/config/context.xml
URL:
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/config/context.xml?rev=1347095&r1=1347094&r2=1347095&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/webapps/docs/config/context.xml (original)
+++ tomcat/tc7.0.x/trunk/webapps/docs/config/context.xml Wed Jun 6 20:17:43
2012
@@ -534,6 +534,11 @@
<code>aliasPathN</code> must include a leading '/' and
<code>docBaseN</code> must be an absolute path to either a .war file or
a directory.</p>
+ <p>Whitespace is permitted around both the <code>,</code> and
+ <code>=</code> delimiters, and will be trimmed. Therefore, an aliases
+ attribute with the value <code>"/aliasPath1 = docBase1,<br/>
+ /aliasPath2= docBase2"</code> is equivalent to
+ <code>"/aliasPath1=docBase1,/aliasPath2=docBase2"</code></p>
<p>A resource will be searched for in the first <code>docBaseN</code>
for which <code>aliasPathN</code> is a leading path segment of the
resource. If there is no such alias, then the resource will be searched
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]