diff --git a/java/org/apache/catalina/Context.java b/java/org/apache/catalina/Context.java index 928c1bfcd079..ddb29516b618 100644 --- a/java/org/apache/catalina/Context.java +++ b/java/org/apache/catalina/Context.java @@ -16,6 +16,7 @@ */ package org.apache.catalina; +import java.io.IOException; import java.net.URL; import java.util.Locale; import java.util.Map; @@ -38,6 +39,7 @@ import org.apache.tomcat.util.descriptor.web.FilterMap; import org.apache.tomcat.util.descriptor.web.LoginConfig; import org.apache.tomcat.util.descriptor.web.SecurityConstraint; +import org.apache.tomcat.util.file.ConfigurationSource.Resource; import org.apache.tomcat.util.http.CookieProcessor; /** @@ -84,6 +86,11 @@ public interface Context extends Container, ContextBind { String CHANGE_SESSION_ID_EVENT = "changeSessionId"; + /** + * Prefix for resource lookup. + */ + String WEBAPP_PROTOCOL = "webapp:"; + // ------------------------------------------------------------- Properties /** @@ -1963,4 +1970,17 @@ void setAllowMultipleLeadingForwardSlashInPath( * @param dispatcherWrapsSameObject the new flag value */ void setDispatcherWrapsSameObject(boolean dispatcherWrapsSameObject); + + + /** + * Find configuration file with the specified path, first looking into the + * webapp resources, then delegating to + * ConfigFileLoader.getSource().getResource. The + * WEBAPP_PROTOCOL constant prefix is used to denote webapp + * resources. + * @param name The resource name + * @return the resource + * @throws IOException if an error occurs or if the resource does not exist + */ + Resource findConfigFileResource(String name) throws IOException; } diff --git a/java/org/apache/catalina/core/StandardContext.java b/java/org/apache/catalina/core/StandardContext.java index 6476bf08c5c6..b8c911a9c300 100644 --- a/java/org/apache/catalina/core/StandardContext.java +++ b/java/org/apache/catalina/core/StandardContext.java @@ -20,6 +20,7 @@ import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; +import java.net.URISyntaxException; import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.ArrayDeque; @@ -127,6 +128,8 @@ import org.apache.tomcat.util.descriptor.web.MessageDestination; import org.apache.tomcat.util.descriptor.web.SecurityCollection; import org.apache.tomcat.util.descriptor.web.SecurityConstraint; +import org.apache.tomcat.util.file.ConfigFileLoader; +import org.apache.tomcat.util.file.ConfigurationSource.Resource; import org.apache.tomcat.util.http.CookieProcessor; import org.apache.tomcat.util.http.Rfc6265CookieProcessor; import org.apache.tomcat.util.scan.StandardJarScanner; @@ -3497,6 +3500,25 @@ public String[] findWrapperListeners() { } + @Override + public Resource findConfigFileResource(String name) throws IOException { + if (name.startsWith(WEBAPP_PROTOCOL)) { + String path = name.substring(WEBAPP_PROTOCOL.length()); + WebResource resource = getResources().getResource(path); + if (resource.canRead()) { + InputStream stream = resource.getInputStream(); + try { + return new Resource(stream, resource.getURL().toURI()); + } catch (URISyntaxException e) { + stream.close(); + } + } + return null; + } else { + return ConfigFileLoader.getSource().getResource(name); + } + } + /** * Reload this web application, if reloading is supported. *

diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 6d58f1ceb270..537749e57a2b 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -117,6 +117,12 @@ if the web applications were deliberately crafted to allow it even when allowLinking was set to false. (markt) + + Add utlity config file resource lookup on Context to allow + looking up resources from the webapp (prefixed with + webapp:) and make the resource lookup API more visible. + (remm) +