Author: funkman
Date: Thu Sep 13 08:19:59 2007
New Revision: 575332

URL: http://svn.apache.org/viewvc?rev=575332&view=rev
Log:
Allow for Aliases at the resource level. 

This is to prevent situations of relying on symlinks, or Filters 
while still make outside directories appear as part of the webapp. 
(A common feature request seen on the user list) 

Example usage:
<Context ... >
  <Resources className="org.apache.naming.resources.FileDirContext"
               aliases="/doh/=C:/tmp/woohoo/,
                        /mmmmmm/=C:/opt/data/doughnuts/" />
</Context>

If the feature is NOT used - there is no additional overhead.



Modified:
    tomcat/tc6.0.x/trunk/java/org/apache/naming/resources/FileDirContext.java
    tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml

Modified: 
tomcat/tc6.0.x/trunk/java/org/apache/naming/resources/FileDirContext.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/naming/resources/FileDirContext.java?rev=575332&r1=575331&r2=575332&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/naming/resources/FileDirContext.java 
(original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/naming/resources/FileDirContext.java 
Thu Sep 13 08:19:59 2007
@@ -108,6 +108,17 @@
     protected boolean allowLinking = false;
 
 
+    /**
+     * Aliases
+     */
+    protected String aliases;
+
+
+    /**
+     * Aliases in decoded form.
+     */
+    protected Alias[] pathAliases;
+
     // ------------------------------------------------------------- Properties
 
 
@@ -123,22 +134,22 @@
      */
     public void setDocBase(String docBase) {
 
-    // Validate the format of the proposed document root
-    if (docBase == null)
-        throw new IllegalArgumentException
-        (sm.getString("resources.null"));
+        // Validate the format of the proposed document root
+        if (docBase == null)
+            throw new IllegalArgumentException
+            (sm.getString("resources.null"));
 
-    // Calculate a File object referencing this document base directory
-    base = new File(docBase);
+        // Calculate a File object referencing this document base directory
+        base = new File(docBase);
         try {
             base = base.getCanonicalFile();
         } catch (IOException e) {
             // Ignore
         }
 
-    // Validate that the document base is an existing directory
-    if (!base.exists() || !base.isDirectory() || !base.canRead())
-        throw new IllegalArgumentException
+        // Validate that the document base is an existing directory
+        if (!base.exists() || !base.isDirectory() || !base.canRead())
+            throw new IllegalArgumentException
         (sm.getString("fileResources.base", docBase));
         this.absoluteBase = base.getAbsolutePath();
         super.setDocBase(docBase);
@@ -177,18 +188,69 @@
         return allowLinking;
     }
 
-
-    // --------------------------------------------------------- Public Methods
+    /**
+     * Get the alias string in use.
+     */
+    public String getAliases(String aliases) {
+        return aliases;
+    }
 
 
     /**
-     * Release any resources allocated for this directory context.
+     * Set files system aliases. Aliases are of the form
+     * <pre>prefix=path,prefix2=path2</pre>
+     * For example: 
+     * <pre>
+     *   /images/=/tmp/images/,
+     *   /pdf/=/usr/local/data/pdfs/
+     * </pre>
      */
-    public void release() {
-        super.release();
+    public void setAliases(String aliases) {
+        this.aliases = aliases;
+
+        pathAliases = null;
+        if (this.aliases!=null) {
+            this.aliases = this.aliases.trim();
+        }
+        if (this.aliases==null||this.aliases.length()==0) {
+            this.aliases=null;
+            return;
+        }
+
+        String[] split1 = this.aliases.split(",");
+        ArrayList aliasList = new ArrayList();
+        for (int i=0; split1!=null && i<split1.length; i++) {
+            String[] kvp = split1[i].split("=");
+            if (kvp!=null&&kvp.length==2) {
+                kvp[0] = kvp[0].trim();
+                kvp[1] = kvp[1].trim();
+
+                if (kvp[0].length()>0 && kvp[1].length()>0) {
+                    Alias alias = new Alias();
+                    alias.prefix=kvp[0];
+                    alias.basePath= new File(kvp[1]);
+                    alias.absPath=alias.basePath.getAbsolutePath();
+                    aliasList.add(alias);
+                }
+            }
+        }
+
+        if (aliasList.size()>0) {
+            pathAliases = new Alias[aliasList.size()];
+            for (int i=0; i<aliasList.size(); i++) {
+                pathAliases[i] = (Alias)aliasList.get(i);
+            }
+        } else {
+            this.aliases=null;
+        }
     }
 
 
+    // --------------------------------------------------------- Public Methods
+
+
+
+
     // -------------------------------------------------------- Context Methods
 
 
@@ -273,7 +335,20 @@
             throw new NamingException
                 (sm.getString("resources.notFound", oldName));
 
-        File newFile = new File(base, newName);
+        File baseDir = base;
+        String absoluteBaseDir = absoluteBase;
+
+        if (pathAliases!=null) {
+            for (int i=0; i<pathAliases.length; i++) {
+                if (newName.startsWith(pathAliases[i].prefix)) {
+                    baseDir = pathAliases[i].basePath;
+                    newName = 
newName.substring(pathAliases[i].prefix.length());
+                    break;
+                }
+            }
+        }
+
+        File newFile = new File(baseDir, newName);
 
         file.renameTo(newFile);
 
@@ -495,8 +570,19 @@
         throws NamingException {
 
         // Note: No custom attributes allowed
+        File baseDir = base;
+
+        if (pathAliases!=null) {
+            for (int i=0; i<pathAliases.length; i++) {
+                if (name.startsWith(pathAliases[i].prefix)) {
+                    baseDir = pathAliases[i].basePath;
+                    name = name.substring(pathAliases[i].prefix.length());
+                    break;
+                }
+            }
+        }
 
-        File file = new File(base, name);
+        File file = new File(baseDir, name);
         if (file.exists())
             throw new NameAlreadyBoundException
                 (sm.getString("resources.alreadyBound", name));
@@ -530,7 +616,19 @@
         // Note: No custom attributes allowed
         // Check obj type
 
-        File file = new File(base, name);
+        File baseDir = base;
+
+        if (pathAliases!=null) {
+            for (int i=0; i<pathAliases.length; i++) {
+                if (name.startsWith(pathAliases[i].prefix)) {
+                    baseDir = pathAliases[i].basePath;
+                    name = name.substring(pathAliases[i].prefix.length());
+                    break;
+                }
+            }
+        }
+
+        File file = new File(baseDir, name);
 
         InputStream is = null;
         if (obj instanceof Resource) {
@@ -601,7 +699,19 @@
     public DirContext createSubcontext(String name, Attributes attrs)
         throws NamingException {
 
-        File file = new File(base, name);
+        File baseDir = base;
+
+        if (pathAliases!=null) {
+            for (int i=0; i<pathAliases.length; i++) {
+                if (name.startsWith(pathAliases[i].prefix)) {
+                    baseDir = pathAliases[i].basePath;
+                    name = name.substring(pathAliases[i].prefix.length());
+                    break;
+                }
+            }
+        }
+
+        File file = new File(baseDir, name);
         if (file.exists())
             throw new NameAlreadyBoundException
                 (sm.getString("resources.alreadyBound", name));
@@ -765,46 +875,46 @@
      */
     protected String normalize(String path) {
 
-    String normalized = path;
+        String normalized = path;
 
-    // Normalize the slashes and add leading slash if necessary
-    if (File.separatorChar == '\\' && normalized.indexOf('\\') >= 0)
-        normalized = normalized.replace('\\', '/');
-    if (!normalized.startsWith("/"))
-        normalized = "/" + normalized;
-
-    // Resolve occurrences of "//" in the normalized path
-    while (true) {
-        int index = normalized.indexOf("//");
-        if (index < 0)
-        break;
-        normalized = normalized.substring(0, index) +
-        normalized.substring(index + 1);
-    }
-
-    // Resolve occurrences of "/./" in the normalized path
-    while (true) {
-        int index = normalized.indexOf("/./");
-        if (index < 0)
-        break;
-        normalized = normalized.substring(0, index) +
-        normalized.substring(index + 2);
-    }
-
-    // Resolve occurrences of "/../" in the normalized path
-    while (true) {
-        int index = normalized.indexOf("/../");
-        if (index < 0)
-        break;
-        if (index == 0)
-        return (null);  // Trying to go outside our context
-        int index2 = normalized.lastIndexOf('/', index - 1);
-        normalized = normalized.substring(0, index2) +
-        normalized.substring(index + 3);
-    }
+        // Normalize the slashes and add leading slash if necessary
+        if (File.separatorChar == '\\' && normalized.indexOf('\\') >= 0)
+            normalized = normalized.replace('\\', '/');
+        if (!normalized.startsWith("/"))
+            normalized = "/" + normalized;
+
+        // Resolve occurrences of "//" in the normalized path
+        while (true) {
+            int index = normalized.indexOf("//");
+            if (index < 0)
+            break;
+            normalized = normalized.substring(0, index) +
+            normalized.substring(index + 1);
+        }
+
+        // Resolve occurrences of "/./" in the normalized path
+        while (true) {
+            int index = normalized.indexOf("/./");
+            if (index < 0)
+            break;
+            normalized = normalized.substring(0, index) +
+            normalized.substring(index + 2);
+        }
+
+        // Resolve occurrences of "/../" in the normalized path
+        while (true) {
+            int index = normalized.indexOf("/../");
+            if (index < 0)
+            break;
+            if (index == 0)
+            return (null);  // Trying to go outside our context
+            int index2 = normalized.lastIndexOf('/', index - 1);
+            normalized = normalized.substring(0, index2) +
+            normalized.substring(index + 3);
+        }
 
-    // Return the normalized path that we have completed
-    return (normalized);
+        // Return the normalized path that we have completed
+        return (normalized);
 
     }
 
@@ -818,12 +928,27 @@
      */
     protected File file(String name) {
 
-        File file = new File(base, name);
+        File baseDir = base;
+        String absoluteBaseDir = absoluteBase;
+
+        if (pathAliases!=null) {
+            for (int i=0; i<pathAliases.length; i++) {
+                if (name.startsWith(pathAliases[i].prefix)) {
+                    baseDir = pathAliases[i].basePath;
+                    absoluteBaseDir = pathAliases[i].absPath;
+                    name = name.substring(pathAliases[i].prefix.length());
+                    break;
+                }
+            }
+        }
+
+        File file = new File(baseDir, name);
+
         if (file.exists() && file.canRead()) {
 
-               if (allowLinking)
-                       return file;
-               
+            if (allowLinking)
+                return file;
+
             // Check that this file belongs to our root path
             String canPath = null;
             try {
@@ -834,7 +959,7 @@
                 return null;
 
             // Check to see if going outside of the web application root
-            if (!canPath.startsWith(absoluteBase)) {
+            if (!canPath.startsWith(absoluteBaseDir)) {
                 return null;
             }
 
@@ -846,14 +971,14 @@
                 String absPath = normalize(fileAbsPath);
                 if (canPath != null)
                     canPath = normalize(canPath);
-                if ((absoluteBase.length() < absPath.length())
-                    && (absoluteBase.length() < canPath.length())) {
-                    absPath = absPath.substring(absoluteBase.length() + 1);
+                if ((absoluteBaseDir.length() < absPath.length())
+                    && (absoluteBaseDir.length() < canPath.length())) {
+                    absPath = absPath.substring(absoluteBaseDir.length() + 1);
                     if ((canPath == null) || (absPath == null))
                         return null;
                     if (absPath.equals(""))
                         absPath = "/";
-                    canPath = canPath.substring(absoluteBase.length() + 1);
+                    canPath = canPath.substring(absoluteBaseDir.length() + 1);
                     if (canPath.equals(""))
                         canPath = "/";
                     if (!canPath.equals(absPath))
@@ -1105,10 +1230,10 @@
             return super.getResourceType();
         }
 
-        
+
         /**
          * Get canonical path.
-         * 
+         *
          * @return String the file's canonical path
          */
         public String getCanonicalPath() {
@@ -1121,10 +1246,15 @@
             }
             return canonicalPath;
         }
-        
+
 
     }
 
+    protected class Alias {
+        String prefix;
+        File basePath;
+        String absPath;
+    }
 
 }
 

Modified: tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml?rev=575332&r1=575331&r2=575332&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml Thu Sep 13 08:19:59 2007
@@ -73,6 +73,9 @@
         In the APR connector, start accepting connections after fully starting
         the connector, to prevent possible exceptions due to non initialized 
fields. (remm)
       </fix>
+      <add>
+         Allow for aliases in FileDirContext. (funkman)
+      </add>
     </changelog>
   </subsection>
   <subsection name="Jasper">



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to