Author: violetagg
Date: Wed Nov 11 09:55:51 2015
New Revision: 1713793

URL: http://svn.apache.org/viewvc?rev=1713793&view=rev
Log:
Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=56777
Allow file based configuration resources (user database, certificate revocation 
lists, keystores and trust stores) to be configured using URLs as well as 
files. Back-port provided by Huxing Zhang.

Added:
    
tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/ClasspathURLStreamHandler.java
   (with props)
    tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/file/ConfigFileLoader.java 
  (with props)
    
tomcat/tc7.0.x/trunk/test/org/apache/naming/resources/TestClasspathUrlStreamHandler.java
   (with props)
    tomcat/tc7.0.x/trunk/test/org/apache/tomcat/util/file/
    
tomcat/tc7.0.x/trunk/test/org/apache/tomcat/util/file/TestConfigFileLoader.java 
  (with props)
Modified:
    tomcat/tc7.0.x/trunk/java/org/apache/catalina/realm/MemoryRealm.java
    tomcat/tc7.0.x/trunk/java/org/apache/catalina/users/MemoryUserDatabase.java
    
tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/DirContextURLStreamHandlerFactory.java
    
tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/LocalStrings.properties
    tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java
    
tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java
    tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml
    tomcat/tc7.0.x/trunk/webapps/docs/config/http.xml
    tomcat/tc7.0.x/trunk/webapps/docs/config/realm.xml
    tomcat/tc7.0.x/trunk/webapps/docs/jndi-resources-howto.xml

Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/realm/MemoryRealm.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/realm/MemoryRealm.java?rev=1713793&r1=1713792&r2=1713793&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/catalina/realm/MemoryRealm.java 
(original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/realm/MemoryRealm.java Wed 
Nov 11 09:55:51 2015
@@ -19,17 +19,18 @@
 package org.apache.catalina.realm;
 
 
-import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
 import java.security.Principal;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Map;
 
-import org.apache.catalina.Globals;
 import org.apache.catalina.LifecycleException;
 import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
 import org.apache.tomcat.util.digester.Digester;
+import org.apache.tomcat.util.file.ConfigFileLoader;
 
 
 /**
@@ -282,30 +283,42 @@ public class MemoryRealm  extends RealmB
     @Override
     protected void startInternal() throws LifecycleException {
 
-        // Validate the existence of our database file
-        File file = new File(pathname);
-        if (!file.isAbsolute())
-            file = new File(System.getProperty(Globals.CATALINA_BASE_PROP), 
pathname);
-        if (!file.exists() || !file.canRead())
-            throw new LifecycleException
-                (sm.getString("memoryRealm.loadExist",
-                              file.getAbsolutePath()));
-
-        // Load the contents of the database file
-        if (log.isDebugEnabled())
-            log.debug(sm.getString("memoryRealm.loadPath",
-                             file.getAbsolutePath()));
-        Digester digester = getDigester();
+        String pathName = getPathname();
+        InputStream is = null;
+
         try {
-            synchronized (digester) {
-                digester.push(this);
-                digester.parse(file);
+            is = ConfigFileLoader.getInputStream(pathName);
+
+            // Load the contents of the database file
+            if (log.isDebugEnabled()) {
+                log.debug(sm.getString("memoryRealm.loadPath", pathName));
             }
-        } catch (Exception e) {
-            throw new LifecycleException
-                (sm.getString("memoryRealm.readXml"), e);
+
+            Digester digester = getDigester();
+            try {
+                synchronized (digester) {
+                    digester.push(this);
+                    digester.parse(is);
+                }
+            } catch (Exception e) {
+                throw new LifecycleException
+                        (sm.getString("memoryRealm.readXml"), e);
+            } finally {
+                digester.reset();
+            }
+
+        } catch (IOException ioe) {
+            throw new LifecycleException(sm.getString("memoryRealm.loadExist",
+                            pathName), ioe);
+
         } finally {
-            digester.reset();
+            if (is != null) {
+                try {
+                    is.close();
+                } catch (IOException e) {
+                    // ignore
+                }
+            }
         }
 
         super.startInternal();

Modified: 
tomcat/tc7.0.x/trunk/java/org/apache/catalina/users/MemoryUserDatabase.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/users/MemoryUserDatabase.java?rev=1713793&r1=1713792&r2=1713793&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/catalina/users/MemoryUserDatabase.java 
(original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/users/MemoryUserDatabase.java 
Wed Nov 11 09:55:51 2015
@@ -17,9 +17,9 @@
 package org.apache.catalina.users;
 
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
 import java.util.HashMap;
@@ -34,6 +34,7 @@ import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
 import org.apache.tomcat.util.digester.AbstractObjectCreationFactory;
 import org.apache.tomcat.util.digester.Digester;
+import org.apache.tomcat.util.file.ConfigFileLoader;
 import org.apache.tomcat.util.res.StringManager;
 import org.xml.sax.Attributes;
 
@@ -394,52 +395,44 @@ public class MemoryUserDatabase implemen
                 groups.clear();
                 roles.clear();
 
-                // Construct a reader for the XML input file (if it exists)
-                File file = new File(pathname);
-                if (!file.isAbsolute()) {
-                    file = new 
File(System.getProperty(Globals.CATALINA_BASE_PROP),
-                                    pathname);
-                }
-                if (!file.exists()) {
-                    log.error(sm.getString("memoryUserDatabase.fileNotFound",
-                            file.getAbsolutePath()));
-                    return;
-                }
+                String pathName = getPathname();
+                InputStream is = null;
 
-                // Construct a digester to read the XML input file
-                Digester digester = new Digester();
                 try {
-                    digester.setFeature(
-                            
"http://apache.org/xml/features/allow-java-encodings";,
-                            true);
-                } catch (Exception e) {
-                    
log.warn(sm.getString("memoryUserDatabase.xmlFeatureEncoding"), e);
-                }
-                digester.addFactoryCreate
-                    ("tomcat-users/group",
-                     new MemoryGroupCreationFactory(this), true);
-                digester.addFactoryCreate
-                    ("tomcat-users/role",
-                     new MemoryRoleCreationFactory(this), true);
-                digester.addFactoryCreate
-                    ("tomcat-users/user",
-                     new MemoryUserCreationFactory(this), true);
+                    is = ConfigFileLoader.getInputStream(pathName);
 
-                // Parse the XML input file to load this database
-                FileInputStream fis = null;
-                try {
-                    fis =  new FileInputStream(file);
-                    digester.parse(fis);
+                    // Construct a digester to read the XML input file
+                    Digester digester = new Digester();
+                    try {
+                        digester.setFeature(
+                                
"http://apache.org/xml/features/allow-java-encodings";,
+                                true);
+                    } catch (Exception e) {
+                        
log.warn(sm.getString("memoryUserDatabase.xmlFeatureEncoding"), e);
+                    }
+                    digester.addFactoryCreate
+                            ("tomcat-users/group",
+                                    new MemoryGroupCreationFactory(this), 
true);
+                    digester.addFactoryCreate
+                            ("tomcat-users/role",
+                                    new MemoryRoleCreationFactory(this), true);
+                    digester.addFactoryCreate
+                            ("tomcat-users/user",
+                                    new MemoryUserCreationFactory(this), true);
+
+                    // Parse the XML input to load this database
+                    digester.parse(is);
+                } catch (IOException ioe) {
+                    log.error(sm.getString("memoryUserDatabase.fileNotFound", 
pathName));
                 } finally {
-                    if (fis != null) {
+                    if (is != null) {
                         try {
-                            fis.close();
+                            is.close();
                         } catch (IOException ioe) {
                             // Ignore
                         }
                     }
                 }
-
             }
         }
 

Added: 
tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/ClasspathURLStreamHandler.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/ClasspathURLStreamHandler.java?rev=1713793&view=auto
==============================================================================
--- 
tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/ClasspathURLStreamHandler.java
 (added)
+++ 
tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/ClasspathURLStreamHandler.java
 Wed Nov 11 09:55:51 2015
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.naming.resources;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+
+import org.apache.tomcat.util.res.StringManager;
+
+public class ClasspathURLStreamHandler extends URLStreamHandler {
+
+    private static final StringManager sm =
+            StringManager.getManager(Constants.Package);
+
+
+    @Override
+    protected URLConnection openConnection(URL u) throws IOException {
+        String path = u.getPath();
+
+        // Thread context class loader first
+        URL classpathUrl = 
Thread.currentThread().getContextClassLoader().getResource(path);
+        if (classpathUrl == null) {
+            // This class's class loader if no joy with the tccl
+            classpathUrl = ClasspathURLStreamHandler.class.getResource(path);
+        }
+
+        if (classpathUrl == null) {
+            throw new 
FileNotFoundException(sm.getString("classpathUrlStreamHandler.notFound", u));
+        }
+
+        return classpathUrl.openConnection();
+    }
+}

Propchange: 
tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/ClasspathURLStreamHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/DirContextURLStreamHandlerFactory.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/DirContextURLStreamHandlerFactory.java?rev=1713793&r1=1713792&r2=1713793&view=diff
==============================================================================
--- 
tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/DirContextURLStreamHandlerFactory.java
 (original)
+++ 
tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/DirContextURLStreamHandlerFactory.java
 Wed Nov 11 09:55:51 2015
@@ -23,8 +23,9 @@ import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
 
 /**
- * Factory for Stream handlers to a JNDI directory context that also supports
- * users specifying additional stream handler.
+ * Factory for Stream handlers to a JNDI directory context,
+ * or for Stream handlers to a classpath url,
+ * which also supports users specifying additional stream handler.
  * 
  * @author <a href="mailto:r...@apache.org";>Remy Maucherat</a>
  */
@@ -64,6 +65,8 @@ public class DirContextURLStreamHandlerF
     public URLStreamHandler createURLStreamHandler(String protocol) {
         if (protocol.equals("jndi")) {
             return new DirContextURLStreamHandler();
+        } else if (protocol.equals("classpath")) {
+            return new ClasspathURLStreamHandler();
         } else {
             for (URLStreamHandlerFactory factory : userFactories) {
                 URLStreamHandler handler =

Modified: 
tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/LocalStrings.properties
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/LocalStrings.properties?rev=1713793&r1=1713792&r2=1713793&view=diff
==============================================================================
--- 
tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/LocalStrings.properties 
(original)
+++ 
tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/LocalStrings.properties 
Wed Nov 11 09:55:51 2015
@@ -43,3 +43,4 @@ standardResources.exists=File base {0} d
 standardResources.notStarted=Resources has not yet been started
 standardResources.null=Document base cannot be null
 standardResources.slash=Document base {0} must not end with a slash
+classpathUrlStreamHandler.notFound=Unable to load the resource [{0}] using the 
thread context class loader or the current class's class loader

Added: 
tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/file/ConfigFileLoader.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/file/ConfigFileLoader.java?rev=1713793&view=auto
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/file/ConfigFileLoader.java 
(added)
+++ tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/file/ConfigFileLoader.java 
Wed Nov 11 09:55:51 2015
@@ -0,0 +1,85 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+package org.apache.tomcat.util.file;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+
+/**
+ * This class is used to obtain {@link InputStream}s for configuration files
+ * from a given location String. This allows greater flexibility than these
+ * files having to be loaded directly from a file system.
+ */
+public class ConfigFileLoader {
+
+    private static final File CATALINA_BASE_FILE;
+    private static final URI CATALINA_BASE_URI;
+
+    static {
+        CATALINA_BASE_FILE = new File(System.getProperty("catalina.base"));
+        CATALINA_BASE_URI = CATALINA_BASE_FILE.toURI();
+    }
+
+    private ConfigFileLoader() {
+        // Utility class. Hide the default constructor.
+    }
+
+
+    /**
+     * Load the resource from the specified location.
+     *
+     * @param location The location for the resource of interest. The location
+     *                 may be a URL or a file path. Relative paths will be
+     *                 resolved against CATALINA_BASE.
+     *
+     * @return The InputStream for the given resource. The caller is 
responsible
+     *         for closing this stream when it is no longer used.
+     *
+     * @throws IOException If an InputStream cannot be created using the
+     *                     provided location
+     */
+    public static InputStream getInputStream(String location) throws 
IOException {
+        // Absolute URIs will be left alone
+        // Relative files will be resolved relative to catalina base
+        // Absolute files will be converted to URIs
+
+        // Location was originally always a file before URI support was added 
so
+        // try file first.
+
+        // First guess, an absolute file path
+        File file = new File(location);
+
+        if (!file.isAbsolute()) {
+            // Second guess, a file path relative to CATALINA_BASE
+            file = new File(CATALINA_BASE_FILE, location);
+        }
+
+        if (file.isFile()) {
+            return new FileInputStream(file);
+        }
+
+        // Third and final guess, a URI
+        URI uri = CATALINA_BASE_URI.resolve(location);
+        return uri.toURL().openStream();
+    }
+
+
+}
\ No newline at end of file

Propchange: 
tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/file/ConfigFileLoader.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java?rev=1713793&r1=1713792&r2=1713793&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java 
(original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java 
Wed Nov 11 09:55:51 2015
@@ -16,7 +16,6 @@
  */
 package org.apache.tomcat.util.net;
 
-import java.io.File;
 import java.io.OutputStreamWriter;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
@@ -728,25 +727,6 @@ public abstract class AbstractEndpoint<S
         }
     }
 
-
-    public String adjustRelativePath(String path, String relativeTo) {
-        // Empty or null path can't point to anything useful. The assumption is
-        // that the value is deliberately empty / null so leave it that way.
-        if (path == null || path.length() == 0) {
-            return path;
-        }
-        String newPath = path;
-        File f = new File(newPath);
-        if ( !f.isAbsolute()) {
-            newPath = relativeTo + File.separator + newPath;
-            f = new File(newPath);
-        }
-        if (!f.exists()) {
-            getLog().warn("configured file:["+newPath+"] does not exist.");
-        }
-        return newPath;
-    }
-
     protected abstract Log getLog();
     // Flags to indicate optional feature support
     // Some of these are always hard-coded, some are hard-coded to false (i.e.
@@ -833,8 +813,7 @@ public abstract class AbstractEndpoint<S
     private String keystoreFile = System.getProperty("user.home")+"/.keystore";
     public String getKeystoreFile() { return keystoreFile;}
     public void setKeystoreFile(String s ) {
-        keystoreFile = adjustRelativePath(s,
-                System.getProperty(Constants.CATALINA_BASE_PROP));
+        keystoreFile = s;
     }
 
     private String keystorePass = null;
@@ -874,8 +853,7 @@ public abstract class AbstractEndpoint<S
     private String truststoreFile = 
System.getProperty("javax.net.ssl.trustStore");
     public String getTruststoreFile() {return truststoreFile;}
     public void setTruststoreFile(String s) {
-        truststoreFile = adjustRelativePath(s,
-                System.getProperty(Constants.CATALINA_BASE_PROP));
+        truststoreFile = s;
     }
 
     private String truststorePass =

Modified: 
tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java?rev=1713793&r1=1713792&r2=1713793&view=diff
==============================================================================
--- 
tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java
 (original)
+++ 
tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java
 Wed Nov 11 09:55:51 2015
@@ -17,8 +17,6 @@
 
 package org.apache.tomcat.util.net.jsse;
 
-import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
@@ -63,6 +61,7 @@ import javax.net.ssl.X509KeyManager;
 
 import org.apache.tomcat.util.compat.JreCompat;
 import org.apache.tomcat.util.compat.JreVendor;
+import org.apache.tomcat.util.file.ConfigFileLoader;
 import org.apache.tomcat.util.net.AbstractEndpoint;
 import org.apache.tomcat.util.net.Constants;
 import org.apache.tomcat.util.net.SSLUtil;
@@ -431,12 +430,7 @@ public class JSSESocketFactory implement
             }
             if(!("PKCS11".equalsIgnoreCase(type) ||
                     "".equalsIgnoreCase(path))) {
-                File keyStoreFile = new File(path);
-                if (!keyStoreFile.isAbsolute()) {
-                    keyStoreFile = new File(System.getProperty(
-                            Constants.CATALINA_BASE_PROP), path);
-                }
-                istream = new FileInputStream(keyStoreFile);
+                istream = ConfigFileLoader.getInputStream(path);
             }
 
             char[] storePass = null;
@@ -718,16 +712,11 @@ public class JSSESocketFactory implement
     protected Collection<? extends CRL> getCRLs(String crlf)
         throws IOException, CRLException, CertificateException {
 
-        File crlFile = new File(crlf);
-        if( !crlFile.isAbsolute() ) {
-            crlFile = new File(
-                    System.getProperty(Constants.CATALINA_BASE_PROP), crlf);
-        }
         Collection<? extends CRL> crls = null;
         InputStream is = null;
         try {
             CertificateFactory cf = CertificateFactory.getInstance("X.509");
-            is = new FileInputStream(crlFile);
+            is = ConfigFileLoader.getInputStream(crlf);
             crls = cf.generateCRLs(is);
         } catch(IOException iex) {
             throw iex;

Added: 
tomcat/tc7.0.x/trunk/test/org/apache/naming/resources/TestClasspathUrlStreamHandler.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/test/org/apache/naming/resources/TestClasspathUrlStreamHandler.java?rev=1713793&view=auto
==============================================================================
--- 
tomcat/tc7.0.x/trunk/test/org/apache/naming/resources/TestClasspathUrlStreamHandler.java
 (added)
+++ 
tomcat/tc7.0.x/trunk/test/org/apache/naming/resources/TestClasspathUrlStreamHandler.java
 Wed Nov 11 09:55:51 2015
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.naming.resources;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Properties;
+
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class TestClasspathUrlStreamHandler {
+
+    @BeforeClass
+    public static void setup() {
+        
URL.setURLStreamHandlerFactory(DirContextURLStreamHandlerFactory.getInstance());
+    }
+
+    @Test
+    public void testClasspathURL01() throws IOException {
+        URL u = new 
URL("classpath:/org/apache/naming/resources/LocalStrings.properties");
+        InputStream is = null;
+        Properties p = new Properties();
+        try {
+            is = u.openStream();
+            p.load(is);
+        } finally {
+           if (is != null) {
+               is.close();
+           }
+        }
+        String msg = (String) p.get("resources.null");
+        Assert.assertEquals("Document base cannot be null",  msg);
+    }
+}
\ No newline at end of file

Propchange: 
tomcat/tc7.0.x/trunk/test/org/apache/naming/resources/TestClasspathUrlStreamHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
tomcat/tc7.0.x/trunk/test/org/apache/tomcat/util/file/TestConfigFileLoader.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/test/org/apache/tomcat/util/file/TestConfigFileLoader.java?rev=1713793&view=auto
==============================================================================
--- 
tomcat/tc7.0.x/trunk/test/org/apache/tomcat/util/file/TestConfigFileLoader.java 
(added)
+++ 
tomcat/tc7.0.x/trunk/test/org/apache/tomcat/util/file/TestConfigFileLoader.java 
Wed Nov 11 09:55:51 2015
@@ -0,0 +1,85 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+package org.apache.tomcat.util.file;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import org.apache.naming.resources.DirContextURLStreamHandlerFactory;
+import org.apache.tomcat.util.http.fileupload.FileUtils;
+
+public class TestConfigFileLoader {
+
+    @BeforeClass
+    public static void setup() {
+        URL.setURLStreamHandlerFactory(
+                DirContextURLStreamHandlerFactory.getInstance());
+        File buildDir = new File(
+                System.getProperty("tomcat.test.tomcatbuild", "output/build"));
+        System.setProperty("catalina.base", buildDir.getAbsolutePath());
+    }
+
+    @Test
+    public void test01() throws IOException {
+        doTest("classpath:org/apache/catalina/mbeans-descriptors.xml");
+    }
+
+    @Test(expected=FileNotFoundException.class)
+    public void test02() throws IOException {
+        doTest("classpath:org/apache/catalina/foo");
+    }
+
+    @Test
+    public void test03() throws IOException {
+        doTest("conf/server.xml");
+    }
+
+    @Test(expected=FileNotFoundException.class)
+    public void test04() throws IOException {
+        doTest("conf/unknown");
+    }
+
+    @Test
+    public void testAbsolutePath() throws IOException {
+        File test = new File(System.getProperty("java.io.tmpdir"), 
"testAbsolutePath");
+        if (test.exists()) {
+            FileUtils.forceDelete(test);
+        }
+        test.createNewFile();
+        doTest(test.getAbsolutePath());
+    }
+
+    private void doTest(String path) throws IOException {
+        InputStream is = null;
+        try {
+            is = ConfigFileLoader.getInputStream(path);
+            Assert.assertNotNull(is);
+        } finally {
+            if (is != null) {
+                is.close();
+            }
+        }
+    }
+}
\ No newline at end of file

Propchange: 
tomcat/tc7.0.x/trunk/test/org/apache/tomcat/util/file/TestConfigFileLoader.java
------------------------------------------------------------------------------
    svn:eol-style = native

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=1713793&r1=1713792&r2=1713793&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Wed Nov 11 09:55:51 2015
@@ -60,6 +60,12 @@
 <section name="Tomcat 7.0.66 (violetagg)">
   <subsection name="Catalina">
     <changelog>
+      <fix>
+        <bug>56777</bug>: Allow file based configuration resources (user
+        database, certificate revocation lists, keystores and trust stores) to
+        be configured using URLs as well as files. Back-port provided by Huxing
+        Zhang. (markt/violetagg)
+      </fix>
       <add>
         <bug>58486</bug>: Protect against two further possible memory leaks
         associated with XML parsing. (markt)

Modified: tomcat/tc7.0.x/trunk/webapps/docs/config/http.xml
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/config/http.xml?rev=1713793&r1=1713792&r2=1713793&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/webapps/docs/config/http.xml (original)
+++ tomcat/tc7.0.x/trunk/webapps/docs/config/http.xml Wed Nov 11 09:55:51 2015
@@ -1019,7 +1019,8 @@
     <attribute name="crlFile" required="false">
       <p>The certificate revocation list to be used to verify client
       certificates. If not defined, client certificates will not be checked
-      against a certificate revocation list.</p>
+      against a certificate revocation list. The file may be specified using a
+      URL, an absolute path or a relative (to CATAINA_BASE) path.</p>
     </attribute>
 
     <attribute name="keyAlias" required="false">
@@ -1044,7 +1045,8 @@
       the file "<code>.keystore</code>" in the operating system home
       directory of the user that is running Tomcat. If your
       <code>keystoreType</code> doesn't need a file use <code>""</code>
-      (empty string) for this parameter.</p>
+      (empty string) for this parameter. The file may be specified using a
+      URL, an absolute path or a relative (to CATAINA_BASE) path.</p>
     </attribute>
 
     <attribute name="keystorePass" required="false">
@@ -1138,7 +1140,8 @@
       <p>The trust store file to use to validate client certificates. The
       default is the value of the <code>javax.net.ssl.trustStore</code> system
       property. If neither this attribute nor the default system property is
-      set, no trust store will be configured.</p>
+      set, no trust store will be configured. The file may be specified using a
+      URL, an absolute path or a relative (to CATAINA_BASE) path.</p>
     </attribute>
 
     <attribute name="truststorePass" required="false">

Modified: tomcat/tc7.0.x/trunk/webapps/docs/config/realm.xml
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/config/realm.xml?rev=1713793&r1=1713792&r2=1713793&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/webapps/docs/config/realm.xml (original)
+++ tomcat/tc7.0.x/trunk/webapps/docs/config/realm.xml Wed Nov 11 09:55:51 2015
@@ -811,8 +811,8 @@
       </attribute>
 
       <attribute name="pathname" required="false">
-        <p>Absolute or relative (to $CATALINA_BASE) pathname to the XML file
-        containing our user information.  See below for details on the
+        <p>URL, absolute path or relative path (to $CATALINA_BASE) for the XML
+        file containing our user information.  See below for details on the
         XML element format required.  If no pathname is specified, the
         default value is <code>conf/tomcat-users.xml</code>.</p>
       </attribute>

Modified: tomcat/tc7.0.x/trunk/webapps/docs/jndi-resources-howto.xml
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/jndi-resources-howto.xml?rev=1713793&r1=1713792&r2=1713793&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/webapps/docs/jndi-resources-howto.xml (original)
+++ tomcat/tc7.0.x/trunk/webapps/docs/jndi-resources-howto.xml Wed Nov 11 
09:55:51 2015
@@ -471,8 +471,9 @@ public class MyBean2 {
           pathname="conf/tomcat-users.xml"
           readonly="false" />]]></source>
 
-    <p>The <code>pathname</code> attribute can be absolute or relative. If
-    relative, it is relative to <code>$CATALINA_BASE</code>.</p>
+    <p>The <code>pathname</code> attribute can be a URL, an absolute path or a
+    relative path. If relative, it is relative to <code>$CATALINA_BASE</code>.
+    </p>
 
     <p>The <code>readonly</code> attribute is optional and defaults to
     <code>true</code> if not supplied. If the XML is writeable then it will be



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to