Skip to content

Commit

Permalink
Merge 1f70627 into e870763
Browse files Browse the repository at this point in the history
  • Loading branch information
lukaszlenart committed Jan 8, 2021
2 parents e870763 + 1f70627 commit d1e88dc
Show file tree
Hide file tree
Showing 58 changed files with 316 additions and 132 deletions.
Expand Up @@ -40,7 +40,7 @@ public void testInvalidRersources1() throws Exception {
public void testInvalidRersources2() throws Exception {
try (final WebClient webClient = new WebClient()) {
try {
webClient.getPage(ParameterUtils.getBaseUrl() + "/struts/..%252f");
webClient.getPage(ParameterUtils.getBaseUrl() + "/static/..%252f");
Assert.fail("Previous request should have failed");
} catch (FailingHttpStatusCodeException e) {
}
Expand All @@ -49,7 +49,7 @@ public void testInvalidRersources2() throws Exception {

/*public void testInvalidRersources3() throws IOException {
try {
beginAt("/struts/..%252f..%252f..%252fWEB-INF/classes/org/apache/struts2/showcase/action/EmployeeAction.class/");
beginAt("/static/..%252f..%252f..%252fWEB-INF/classes/org/apache/struts2/showcase/action/EmployeeAction.class/");
fail("Previous request should have failed");
} catch (TestingEngineResponseException ex) {
// ok
Expand Down
12 changes: 6 additions & 6 deletions bundles/admin/src/main/resources/osgi/admin/shell.ftl
Expand Up @@ -22,13 +22,13 @@
<head>
<title>OSGi Console</title>

<link rel="stylesheet" type="text/css" href="<@s.url value="/static/css/shell.css" />" />
<link rel="stylesheet" type="text/css" href="<@s.url value="/static/css/main.css" />" />
<link rel="stylesheet" type="text/css" href="<@s.url value="/static/css/redmond/jquery-ui-1.12.1.redmond.css" />" />
<link rel="stylesheet" type="text/css" href="<@s.url value="${parameters.staticContentPath}/css/shell.css" />" />
<link rel="stylesheet" type="text/css" href="<@s.url value="${parameters.staticContentPath}/css/main.css" />" />
<link rel="stylesheet" type="text/css" href="<@s.url value="${parameters.staticContentPath}/css/redmond/jquery-ui-1.12.1.redmond.css" />" />

<script src="<@s.url value="/static/js/shell.js" />"></script>
<script src="<@s.url value="/static/js/jquery-1.12.4.min.js" />"></script>
<script src="<@s.url value="/static/js/jquery-ui-1.12.1.min.js" />"></script>
<script src="<@s.url value="${parameters.staticContentPath}/js/shell.js" />"></script>
<script src="<@s.url value="${parameters.staticContentPath}/js/jquery-1.12.4.min.js" />"></script>
<script src="<@s.url value="${parameters.staticContentPath}/js/jquery-ui-1.12.1.min.js" />"></script>
</head>
<body>
<div class="menu">
Expand Down
8 changes: 4 additions & 4 deletions bundles/admin/src/main/resources/osgi/admin/viewBundle.ftl
Expand Up @@ -22,11 +22,11 @@
<head>
<title>${bundle.symbolicName!}</title>

<link rel="stylesheet" type="text/css" href="<@s.url value="/static/css/main.css" />" />
<link rel="stylesheet" type="text/css" href="<@s.url value="/static/css/redmond/jquery-ui-1.12.1.redmond.css" />" />
<link rel="stylesheet" type="text/css" href="<@s.url value="${parameters.staticContentPath}/css/main.css" />" />
<link rel="stylesheet" type="text/css" href="<@s.url value="${parameters.staticContentPath}/css/redmond/jquery-ui-1.12.1.redmond.css" />" />

<script src="<@s.url value="/static/js/jquery-1.12.4.min.js" />"></script>
<script src="<@s.url value="/static/js/jquery-ui-1.12.1.min.js" />"></script>
<script src="<@s.url value="${parameters.staticContentPath}/js/jquery-1.12.4.min.js" />"></script>
<script src="<@s.url value="${parameters.staticContentPath}/js/jquery-ui-1.12.1.min.js" />"></script>

<script type="text/javascript">
$(function() {
Expand Down
8 changes: 4 additions & 4 deletions bundles/admin/src/main/resources/osgi/admin/viewBundles.ftl
Expand Up @@ -22,11 +22,11 @@
<head>
<title>OSGi Bundles</title>

<link rel="stylesheet" type="text/css" href="<@s.url value="/static/css/main.css" />" />
<link rel="stylesheet" type="text/css" href="<@s.url value="/static/css/redmond/jquery-ui-1.12.1.redmond.css" />" />
<link rel="stylesheet" type="text/css" href="<@s.url value="${parameters.staticContentPath}/css/main.css" />" />
<link rel="stylesheet" type="text/css" href="<@s.url value="${parameters.staticContentPath}/css/redmond/jquery-ui-1.12.1.redmond.css" />" />

<script src="<@s.url value="/static/js/jquery-1.12.4.min.js" />"></script>
<script src="<@s.url value="/static/js/jquery-ui-1.12.1.min.js" />"></script>
<script src="<@s.url value="${parameters.staticContentPath}/js/jquery-1.12.4.min.js" />"></script>
<script src="<@s.url value="${parameters.staticContentPath}/js/jquery-ui-1.12.1.min.js" />"></script>
</head>
<body>

Expand Down
3 changes: 3 additions & 0 deletions core/src/main/java/org/apache/struts2/StrutsConstants.java
Expand Up @@ -129,6 +129,9 @@ public final class StrutsConstants {
/** Token to use to indicate start of theme to be expanded. */
public static final String STRUTS_UI_THEME_EXPANSION_TOKEN = "struts.ui.theme.expansion.token";

/** A path to static content, by default and from historical point of view it's /static. */
public static final String STRUTS_UI_STATIC_CONTENT_PATH = "struts.ui.staticContentPath";

/** The maximize size of a multipart request (file upload) */
public static final String STRUTS_MULTIPART_MAXSIZE = "struts.multipart.maxSize";

Expand Down
12 changes: 11 additions & 1 deletion core/src/main/java/org/apache/struts2/components/UIBean.java
Expand Up @@ -30,6 +30,7 @@
import org.apache.struts2.components.template.TemplateEngine;
import org.apache.struts2.components.template.TemplateEngineManager;
import org.apache.struts2.components.template.TemplateRenderingContext;
import org.apache.struts2.dispatcher.StaticContentLoader;
import org.apache.struts2.util.TextProviderHelper;
import org.apache.struts2.views.annotations.StrutsTagAttribute;
import org.apache.struts2.views.util.ContextUtil;
Expand Down Expand Up @@ -317,7 +318,7 @@
* <tr>
* <td>tooltipIcon</td>
* <td>String</td>
* <td>/struts/static/tooltip/tooltip.gif</td>
* <td>/static/tooltip/tooltip.gif</td>
* <td>The url to the tooltip icon</td>
* <tr>
* <td>tooltipDelay</td>
Expand Down Expand Up @@ -506,6 +507,8 @@ public UIBean(ValueStack stack, HttpServletRequest request, HttpServletResponse
protected String defaultTemplateDir;
protected String defaultUITheme;
protected String uiThemeExpansionToken;
protected String uiStaticContentPath;

protected TemplateEngineManager templateEngineManager;

@Inject(StrutsConstants.STRUTS_UI_TEMPLATEDIR)
Expand All @@ -523,6 +526,11 @@ public void setUIThemeExpansionToken(String uiThemeExpansionToken) {
this.uiThemeExpansionToken = uiThemeExpansionToken;
}

@Inject(StrutsConstants.STRUTS_UI_STATIC_CONTENT_PATH)
public void setStaticContentPath(String uiStaticContentPath) {
this.uiStaticContentPath = StaticContentLoader.Validator.validateStaticContentPath(uiStaticContentPath);
}

@Inject
public void setTemplateEngineManager(TemplateEngineManager mgr) {
this.templateEngineManager = mgr;
Expand Down Expand Up @@ -645,6 +653,8 @@ public void evaluateParams() {
addParameter("themeExpansionToken", uiThemeExpansionToken);
addParameter("expandTheme", uiThemeExpansionToken + theme);

addParameter("staticContentPath", findString(uiStaticContentPath));

String name = null;
String providedLabel = null;

Expand Down
Expand Up @@ -29,6 +29,7 @@

import org.apache.commons.lang3.StringUtils;
import org.apache.struts2.StrutsConstants;
import org.apache.struts2.dispatcher.StaticContentLoader;

public class ConstantConfig {
private Boolean devMode;
Expand Down Expand Up @@ -143,6 +144,7 @@ public class ConstantConfig {
private BeanConfig localizedTextProvider;
private Boolean disallowProxyMemberAccess;
private Integer ognlAutoGrowthCollectionLimit;
private String staticContentPath;

protected String beanConfToString(BeanConfig beanConf) {
return beanConf == null ? null : beanConf.getName();
Expand Down Expand Up @@ -273,6 +275,7 @@ public Map<String, String> getAllAsStringsMap() {
map.put(StrutsConstants.STRUTS_LOCALIZED_TEXT_PROVIDER, beanConfToString(localizedTextProvider));
map.put(StrutsConstants.STRUTS_DISALLOW_PROXY_MEMBER_ACCESS, Objects.toString(disallowProxyMemberAccess, null));
map.put(StrutsConstants.STRUTS_OGNL_AUTO_GROWTH_COLLECTION_LIMIT, Objects.toString(ognlAutoGrowthCollectionLimit, null));
map.put(StrutsConstants.STRUTS_UI_STATIC_CONTENT_PATH, Objects.toString(staticContentPath, StaticContentLoader.DEFAULT_STATIC_CONTENT_PATH));

return map;
}
Expand Down Expand Up @@ -1344,4 +1347,12 @@ public Integer getOgnlAutoGrowthCollectionLimit() {
public void setOgnlAutoGrowthCollectionLimit(Integer ognlAutoGrowthCollectionLimit) {
this.ognlAutoGrowthCollectionLimit = ognlAutoGrowthCollectionLimit;
}

public String getStaticContentPath() {
return staticContentPath;
}

public void setStaticContentPath(String staticContentPath) {
this.staticContentPath = StaticContentLoader.Validator.validateStaticContentPath(staticContentPath);
}
}
Expand Up @@ -34,7 +34,12 @@
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.*;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;

/**
* <p>
Expand All @@ -43,8 +48,8 @@
*
* <p>
* This class is used to serve common static content needed when using various parts of Struts, such as JavaScript
* files, CSS files, etc. It works by looking for requests to /struts/* (or /static/*), and then mapping the value after "/struts/"
* to common packages in Struts and, optionally, in your class path. By default, the following packages are
* files, CSS files, etc. It works by looking for requests to {@link #uiStaticContentPath}/* and then mapping the value
* after to common packages in Struts and, optionally, in your class path. By default, the following packages are
* automatically searched:
* </p>
*
Expand All @@ -55,7 +60,7 @@
* </ul>
*
* <p>
* This means that you can simply request /struts/xhtml/styles.css and the XHTML UI theme's default stylesheet
* This means that you can simply request {@link #uiStaticContentPath}/xhtml/styles.css and the XHTML UI theme's default stylesheet
* will be returned. Likewise, many of the AJAX UI components require various JavaScript files, which are found in the
* org.apache.struts2.static package. If you wish to add additional packages to be searched, you can add a comma
* separated (space, tab and new line will do as well) list in the filter init parameter named "packages". <b>Be
Expand All @@ -68,7 +73,7 @@ public class DefaultStaticContentLoader implements StaticContentLoader {
/**
* Provide a logging instance.
*/
private Logger LOG = LogManager.getLogger(DefaultStaticContentLoader.class);
private final Logger LOG = LogManager.getLogger(DefaultStaticContentLoader.class);

/**
* Store set of path prefixes to use with static resources.
Expand All @@ -80,6 +85,11 @@ public class DefaultStaticContentLoader implements StaticContentLoader {
*/
protected boolean serveStatic;

/**
* Store state of {@link StrutsConstants#STRUTS_UI_STATIC_CONTENT_PATH} setting.
*/
protected String uiStaticContentPath;

/**
* Store state of StrutsConstants.STRUTS_SERVE_STATIC_BROWSER_CACHE setting.
*/
Expand All @@ -100,20 +110,23 @@ public class DefaultStaticContentLoader implements StaticContentLoader {
/**
* Modify state of StrutsConstants.STRUTS_SERVE_STATIC_CONTENT setting.
*
* @param serveStaticContent
* New setting
* @param serveStaticContent New setting
*/
@Inject(StrutsConstants.STRUTS_SERVE_STATIC_CONTENT)
public void setServeStaticContent(String serveStaticContent) {
this.serveStatic = BooleanUtils.toBoolean(serveStaticContent);
}

@Inject(StrutsConstants.STRUTS_UI_STATIC_CONTENT_PATH)
public void setStaticContentPath(String uiStaticContentPath) {
this.uiStaticContentPath = StaticContentLoader.Validator.validateStaticContentPath(uiStaticContentPath);
}

/**
* Modify state of StrutsConstants.STRUTS_SERVE_STATIC_BROWSER_CACHE
* setting.
*
* @param serveStaticBrowserCache
* New setting
* @param serveStaticBrowserCache New setting
*/
@Inject(StrutsConstants.STRUTS_SERVE_STATIC_BROWSER_CACHE)
public void setServeStaticBrowserCache(String serveStaticBrowserCache) {
Expand All @@ -122,6 +135,7 @@ public void setServeStaticBrowserCache(String serveStaticBrowserCache) {

/**
* Modify state of StrutsConstants.STRUTS_I18N_ENCODING setting.
*
* @param encoding New setting
*/
@Inject(StrutsConstants.STRUTS_I18N_ENCODING)
Expand Down Expand Up @@ -164,8 +178,7 @@ protected String getAdditionalPackages() {
/**
* Create a string array from a comma-delimited list of packages.
*
* @param packages
* A comma-delimited String listing packages
* @param packages A comma-delimited String listing packages
* @return A string array of packages
*/
protected List<String> parse(String packages) {
Expand Down Expand Up @@ -194,7 +207,7 @@ protected List<String> parse(String packages) {
* javax.servlet.http.HttpServletResponse)
*/
public void findStaticResource(String path, HttpServletRequest request, HttpServletResponse response)
throws IOException {
throws IOException {
String name = cleanupPath(path);
for (String pathPrefix : pathPrefixes) {
URL resourceUrl = findResource(buildPath(name, pathPrefix));
Expand Down Expand Up @@ -225,7 +238,7 @@ public void findStaticResource(String path, HttpServletRequest request, HttpServ
LOG.warn("Unable to send error response, code: {};", HttpServletResponse.SC_NOT_FOUND, e1);
} catch (IllegalStateException ise) {
// Log illegalstate instead of passing unrecoverable exception to calling thread
LOG.warn("Unable to send error response, code: {}; isCommited: {};", HttpServletResponse.SC_NOT_FOUND, response.isCommitted(), ise);
LOG.warn("Unable to send error response, code: {}; isCommitted: {};", HttpServletResponse.SC_NOT_FOUND, response.isCommitted(), ise);
}
}

Expand Down Expand Up @@ -285,15 +298,15 @@ protected void process(InputStream is, String path, HttpServletRequest request,
* Look for a static resource in the classpath.
*
* @param path The resource path
* @return The inputstream of the resource
* @return The URL of the resource
* @throws IOException If there is a problem locating the resource
*/
protected URL findResource(String path) throws IOException {
return ClassLoaderUtil.getResource(path, getClass());
}

/**
* @param name resource name
* @param name resource name
* @param packagePrefix The package prefix to use to locate the resource
* @return full path
* @throws UnsupportedEncodingException If there is a encoding problem
Expand All @@ -310,7 +323,6 @@ protected String buildPath(String name, String packagePrefix) throws Unsupported
}



/**
* Determine the content type for the resource name.
*
Expand Down Expand Up @@ -342,12 +354,9 @@ protected String getContentType(String name) {
/**
* Copy bytes from the input stream to the output stream.
*
* @param input
* The input stream
* @param output
* The output stream
* @throws IOException
* If anything goes wrong
* @param input The input stream
* @param output The output stream
* @throws IOException If anything goes wrong
*/
protected void copy(InputStream input, OutputStream output) throws IOException {
final byte[] buffer = new byte[4096];
Expand All @@ -359,15 +368,18 @@ protected void copy(InputStream input, OutputStream output) throws IOException {
}

public boolean canHandle(String resourcePath) {
return serveStatic && (resourcePath.startsWith("/struts/") || resourcePath.startsWith("/static/"));
return serveStatic && resourcePath.startsWith(uiStaticContentPath + "/");
}

/**
* @param path requested path
* @return path without leading "/struts" or "/static"
* @return path without leading {@link #uiStaticContentPath}
*/
protected String cleanupPath(String path) {
//path will start with "/struts" or "/static", remove them
return path.substring(7);
if (path.startsWith(uiStaticContentPath)) {
return path.substring(uiStaticContentPath.length());
} else {
return path;
}
}
}

0 comments on commit d1e88dc

Please sign in to comment.