diff --git a/applications/product/src/main/java/org/apache/ofbiz/product/category/ftl/UrlRegexpTransform.java b/applications/product/src/main/java/org/apache/ofbiz/product/category/ftl/UrlRegexpTransform.java
index ec008c7c4ed..2d57b98b726 100644
--- a/applications/product/src/main/java/org/apache/ofbiz/product/category/ftl/UrlRegexpTransform.java
+++ b/applications/product/src/main/java/org/apache/ofbiz/product/category/ftl/UrlRegexpTransform.java
@@ -103,6 +103,7 @@ public Writer getWriter(final Writer out, @SuppressWarnings("rawtypes") Map args
final StringBuffer buf = new StringBuffer();
final boolean fullPath = checkArg(args, "fullPath", false);
final boolean secure = checkArg(args, "secure", false);
+ final boolean shortener = checkArg(args, "pathShortener", false);
final boolean encode = checkArg(args, "encode", true);
final String controlPath = convertToString(args.get("controlPath"));
final String webSiteId = convertToString(args.get("webSiteId"));
@@ -142,7 +143,7 @@ public void close() throws IOException {
RequestHandler rh = RequestHandler.from(request);
String seoUrl = seoUrl(rh.makeLink(request, response, buf.toString(), fullPath,
- secure || request.isSecure(), encode, controlPath), userLogin == null);
+ secure || request.isSecure(), encode, controlPath, shortener), userLogin == null);
String requestURI = buf.toString();
// add / update csrf token to link when required
@@ -159,7 +160,7 @@ public void close() throws IOException {
ComponentConfig.WebappInfo webAppInfo = WebAppUtil.getWebappInfoFromWebsiteId(webSiteId);
StringBuilder newUrlBuff = new StringBuilder(250);
OfbizUrlBuilder builder = OfbizUrlBuilder.from(webAppInfo, delegator);
- builder.buildFullUrl(newUrlBuff, buf.toString(), secure);
+ builder.buildFullUrl(newUrlBuff, buf.toString(), secure, shortener);
String newUrl = newUrlBuff.toString();
if (encode) {
newUrl = URLEncoder.encode(newUrl, "UTF-8");
diff --git a/framework/common/webcommon/WEB-INF/common-controller.xml b/framework/common/webcommon/WEB-INF/common-controller.xml
index fa7f592437a..b6ef970a153 100644
--- a/framework/common/webcommon/WEB-INF/common-controller.xml
+++ b/framework/common/webcommon/WEB-INF/common-controller.xml
@@ -109,6 +109,10 @@ under the License.
+
+
+
+
diff --git a/framework/security/config/security.properties b/framework/security/config/security.properties
index c7effe8d3f6..be3bdf052ab 100644
--- a/framework/security/config/security.properties
+++ b/framework/security/config/security.properties
@@ -323,3 +323,6 @@ Content-Security-Policy=Content-Security-Policy-Report-Only
#-- Define policy directives, see https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
PolicyDirectives=default-src 'self'
+
+#-- Give the size of shortener path when the functionality to shorter the url is used
+path.shortener.size=10
\ No newline at end of file
diff --git a/framework/webapp/dtd/site-conf.xsd b/framework/webapp/dtd/site-conf.xsd
index 8f2927a3371..cbf2cfde81f 100644
--- a/framework/webapp/dtd/site-conf.xsd
+++ b/framework/webapp/dtd/site-conf.xsd
@@ -530,7 +530,8 @@ under the License.
request-redirect-noparam,
url,
url-redirect,
- cross-redirect
+ cross-redirect,
+ shortener
@@ -625,6 +626,13 @@ under the License.
+
+
+
+ Call ofbiz shortener to resolve the next uri to call
+
+
+
diff --git a/framework/webapp/entitydef/entitymodel.xml b/framework/webapp/entitydef/entitymodel.xml
index 010969815b5..f8403d7a62c 100644
--- a/framework/webapp/entitydef/entitymodel.xml
+++ b/framework/webapp/entitydef/entitymodel.xml
@@ -30,10 +30,24 @@ under the License.
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/framework/webapp/ofbiz-component.xml b/framework/webapp/ofbiz-component.xml
index 54e4b39280b..152f9310e7e 100644
--- a/framework/webapp/ofbiz-component.xml
+++ b/framework/webapp/ofbiz-component.xml
@@ -31,5 +31,5 @@ under the License.
-->
-
+
diff --git a/framework/webapp/src/main/groovy/org/apache/ofbiz/webapp/test/OfbizPathShortenerTests.groovy b/framework/webapp/src/main/groovy/org/apache/ofbiz/webapp/test/OfbizPathShortenerTests.groovy
new file mode 100644
index 00000000000..824e3b30cba
--- /dev/null
+++ b/framework/webapp/src/main/groovy/org/apache/ofbiz/webapp/test/OfbizPathShortenerTests.groovy
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * 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.ofbiz.webapp.test
+
+import org.apache.ofbiz.service.testtools.OFBizTestCase
+import org.apache.ofbiz.webapp.OfbizPathShortener
+
+class OfbizPathShortenerTests extends OFBizTestCase {
+
+ OfbizPathShortenerTests(String name) {
+ super(name)
+ }
+ void testComputeLongUrlToShortUrl() {
+ String longUri = "passwordChange?USERNAME=admin&TOKEN=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxML" +
+ "LL.eyJ1c2VyTG9naW5JZCI6Imx1Y2lsZS5wZWxsZXRpZXJAZWRsbi5vcmciLCJpc3MiOiJBcGFjaGVPRkJpeiIsImV4cCI6MTcyNTU" +
+ "0MjM0OSwiaWF0IjoxNzI1NTQwNTQLLL.Rycl_L-u4ZeWkx82pWWGu7gycfsHQxIxE8zu1nQ5oueGDBeOXALL-SJzMuvSARbpxCwF9A" +
+ "jl4rTxgoEYuRMoHg&JavaScriptEnabled=Y&Albert=Yoda"
+ assert OfbizPathShortener.resolveShortenedPath(this.getDelegator(), longUri).length() < 11
+ }
+ void testResolveLongUrlComputedFromShort() {
+ String longUri = "passwordChange?USERNAME=admin&TOKEN=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxML" +
+ "LL.eyJ1c2VyTG9naW5JZCI6Imx1Y2lsZS5wZWxsZXRpZXJAZWRsbi5vcmciLCJpc3MiOiJBcGFjaGVPRkJpeiIsImV4cCI6MTcyNTU" +
+ "0MjM0OSwiaWF0IjoxNzI1NTQwNTQLLL.Rycl_L-u4ZeWkx82pWWGu7gycfsHQxIxE8zu1nQ5oueGDBeOXALL-SJzMuvSARbpxCwF9A" +
+ "jl4rTxgoEYuRMoHg&JavaScriptEnabled=Y"
+ String shortUri = OfbizPathShortener.resolveShortenedPath(this.getDelegator(), longUri)
+ assert longUri == OfbizPathShortener.resolveOriginalPathFromShortened(this.getDelegator(), shortUri)
+ }
+ void testResolveLongUrlComputedFromShortAlreadyStored() {
+ String longUri = "passwordChange?USERNAME=admin&TOKEN=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxML" +
+ "LL.eyJ1c2VyTG9naW5JZCI6Imx1Y2lsZS5wZWxsZXRpZXJAZWRsbi5vcmciLCJpc3MiOiJBcGFjaGVPRkJpeiIsImV4cCI6MTcyNTU" +
+ "0MjM0OSwiaWF0IjoxNzI1NTQwNTQLLL.Rycl_L-u4ZeWkx82pWWGu7gycfsHQxIxE8zu1nQ5oueGDBeOXALL-SJzMuvSARbpxCwF9A" +
+ "jl4rTxgoEYuRMoHg&JavaScriptEnabled=Y&And=Again"
+ String shortUriFirst = OfbizPathShortener.resolveShortenedPath(this.getDelegator(),longUri)
+ String shortUriSecond = OfbizPathShortener.resolveShortenedPath(this.getDelegator(),longUri)
+ assert shortUriSecond == shortUriFirst
+ }
+
+}
diff --git a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/OfbizPathShortener.java b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/OfbizPathShortener.java
new file mode 100644
index 00000000000..81f485d5594
--- /dev/null
+++ b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/OfbizPathShortener.java
@@ -0,0 +1,176 @@
+/*******************************************************************************
+ * 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.ofbiz.webapp;
+
+import java.util.Map;
+import javax.transaction.Transaction;
+import org.apache.commons.lang.RandomStringUtils;
+import org.apache.ofbiz.base.crypto.HashCrypt;
+import org.apache.ofbiz.base.util.UtilDateTime;
+import org.apache.ofbiz.base.util.UtilProperties;
+import org.apache.ofbiz.entity.Delegator;
+import org.apache.ofbiz.entity.GenericEntityException;
+import org.apache.ofbiz.entity.GenericValue;
+import org.apache.ofbiz.entity.transaction.GenericTransactionException;
+import org.apache.ofbiz.entity.transaction.TransactionUtil;
+import org.apache.ofbiz.entity.util.EntityQuery;
+
+public class OfbizPathShortener {
+ public static final String SHORTENED_PATH = "s/";
+ public static final String RESTORE_PATH = "../";
+
+ /**
+ * For an ofbiz path, return a shortened url that will be linked to the given path
+ * example : orderview?orderId=HA1023 -> s/izapnreiis
+ * @param delegator
+ * @param path to shorten
+ * @return a shortened key corresponding to the path
+ * @throws GenericEntityException
+ */
+ public static String shortenPath(Delegator delegator, String path) throws GenericEntityException {
+ return SHORTENED_PATH + resolveShortenedPath(delegator, path);
+ }
+
+ /**
+ * For the given path, check if a shortened path already exists otherwise generate a new one
+ * @param delegator
+ * @param path
+ * @return a shortened path corresponding to the given path
+ * @throws GenericEntityException
+ */
+ public static String resolveShortenedPath(Delegator delegator, String path) throws GenericEntityException {
+ String shortenedPath = resolveExistingShortenedPath(delegator, path);
+ int nbLoop = 0;
+ if (shortenedPath == null) {
+ do {
+ shortenedPath = generate();
+ nbLoop++;
+ } while (!recordPathMapping(delegator, path, shortenedPath) || nbLoop > 10);
+ }
+ return shortenedPath;
+ }
+
+ /**
+ * Try to resolve the original path, if failed, return to the webapp root. Use views request for that define on common-controller
+ * @param delegator
+ * @param shortenedPath
+ * @return the origin path corresponding to the given shortened path, webapp root otherwise
+ * @throws GenericEntityException
+ */
+ public static String restoreOriginalPath(Delegator delegator, String shortenedPath) throws GenericEntityException {
+ String originalPath = resolveOriginalPathFromShortened(delegator, shortenedPath);
+ return RESTORE_PATH + (originalPath != null ? originalPath : "views");
+ }
+
+ /**
+ * From a shortened path, resolve the origin path
+ * @param delegator
+ * @param shortenedPath path
+ * @return the original path corresponding to the shortened path
+ * @throws GenericEntityException
+ */
+ public static String resolveOriginalPathFromShortened(Delegator delegator, String shortenedPath) throws GenericEntityException {
+ return readPathMapping(delegator, shortenedPath);
+ }
+
+ /**
+ * For a path, function tried to resolve if it already presents in database
+ * For performance issue the function use the hash to resolve it
+ * @param delegator
+ * @param path
+ * @return the shortened path if found, null otherwise
+ * @throws GenericEntityException
+ */
+ private static String resolveExistingShortenedPath(Delegator delegator, String path) throws GenericEntityException {
+ GenericValue existingPath = EntityQuery.use(delegator)
+ .from("ShortenedPath")
+ .where("originalPathHash", generateHash(path))
+ .cache()
+ .queryFirst();
+ return existingPath != null ? existingPath.getString("shortenedPath") : null;
+ }
+
+ /**
+ * generate a random shortened path, the size can be set on property : security.
+ * @return shortened path
+ */
+ private static String generate() {
+ int shortenerSize = UtilProperties.getPropertyAsInteger("security", "path.shortener.size", 10);
+ return RandomStringUtils.randomAlphabetic(shortenerSize);
+ }
+
+ /**
+ * Create the mapping between an origin map and the shortened path
+ * This will be executed on dedicate transaction to be sure to not rollback it after.
+ * @param delegator
+ * @param path
+ * @param shortenedPath
+ * @return true if it's create with success
+ */
+ private static boolean recordPathMapping(Delegator delegator, String path, String shortenedPath) {
+ Transaction trans = null;
+ try {
+ try {
+ trans = TransactionUtil.suspend();
+ TransactionUtil.begin();
+ delegator.create("ShortenedPath", Map.of("shortenedPath", shortenedPath,
+ "originalPath", path,
+ "originalPathHash", generateHash(path),
+ "createdDate", UtilDateTime.nowTimestamp(),
+ "createdByUserLogin", "system"));
+ TransactionUtil.commit();
+ } catch (GenericEntityException e) {
+ TransactionUtil.rollback();
+ return false;
+ } finally {
+ TransactionUtil.resume(trans);
+ }
+ } catch (GenericTransactionException e) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * @param path
+ * @return a hash of the given path
+ */
+ private static String generateHash(String path) {
+ return HashCrypt.digestHash("SHA", path.getBytes());
+ }
+
+ /**
+ * Find the origin path corresponding to the shorter in database
+ * @param delegator
+ * @param shortenedPath
+ * @return the original path corresponding to shortened path given, null if not found
+ * @throws GenericEntityException
+ */
+ private static String readPathMapping(Delegator delegator, String shortenedPath) throws GenericEntityException {
+ GenericValue existingPath = EntityQuery.use(delegator)
+ .from("ShortenedPath")
+ .where("shortenedPath", shortenedPath)
+ .cache()
+ .queryOne();
+ return existingPath != null
+ ? existingPath.getString("originalPath")
+ : null;
+ }
+
+}
diff --git a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/OfbizUrlBuilder.java b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/OfbizUrlBuilder.java
index cfb80dfccf1..05c05cda404 100644
--- a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/OfbizUrlBuilder.java
+++ b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/OfbizUrlBuilder.java
@@ -57,7 +57,8 @@ public static OfbizUrlBuilder from(HttpServletRequest request) throws GenericEnt
URL url = ConfigXMLReader.getControllerConfigURL(request.getServletContext());
ControllerConfig config = ConfigXMLReader.getControllerConfig(url);
String servletPath = (String) request.getAttribute("_CONTROL_PATH_");
- builder = new OfbizUrlBuilder(config, webSiteProps, servletPath);
+ Delegator delegator = (Delegator) request.getAttribute("delegator");
+ builder = new OfbizUrlBuilder(delegator, config, webSiteProps, servletPath);
request.setAttribute("_OFBIZ_URL_BUILDER_", builder);
}
return builder;
@@ -95,14 +96,16 @@ public static OfbizUrlBuilder from(WebappInfo webAppInfo, Delegator delegator) t
if (webSiteProps == null) {
webSiteProps = WebSiteProperties.defaults(delegator);
}
- return new OfbizUrlBuilder(config, webSiteProps, servletPath);
+ return new OfbizUrlBuilder(delegator, config, webSiteProps, servletPath);
}
+ private final Delegator delegator;
private final ControllerConfig config;
private final WebSiteProperties webSiteProps;
private final String servletPath;
- private OfbizUrlBuilder(ControllerConfig config, WebSiteProperties webSiteProps, String servletPath) {
+ private OfbizUrlBuilder(Delegator delegator, ControllerConfig config, WebSiteProperties webSiteProps, String servletPath) {
+ this.delegator = delegator;
this.config = config;
this.webSiteProps = webSiteProps;
this.servletPath = servletPath;
@@ -118,9 +121,26 @@ private OfbizUrlBuilder(ControllerConfig config, WebSiteProperties webSiteProps,
* @throws WebAppConfigurationException
* @throws IOException
*/
- public boolean buildFullUrl(Appendable buffer, String url, boolean useSSL) throws WebAppConfigurationException, IOException {
+ public boolean buildFullUrl(Appendable buffer, String url, boolean useSSL)
+ throws WebAppConfigurationException, IOException, GenericEntityException {
+ return buildFullUrl(buffer, url, useSSL, false);
+ }
+
+ /**
+ * Builds a full URL - including scheme, host, servlet path and resource.
+ * @param buffer
+ * @param url
+ * @param useSSL Default value to use - will be replaced by request-map setting
+ * if one is found.
+ * @param pathShortener
+ * @return true
if the URL uses https
+ * @throws WebAppConfigurationException
+ * @throws IOException
+ */
+ public boolean buildFullUrl(Appendable buffer, String url, boolean useSSL, boolean pathShortener)
+ throws WebAppConfigurationException, IOException, GenericEntityException {
boolean makeSecure = buildHostPart(buffer, url, useSSL);
- buildPathPart(buffer, url);
+ buildPathPart(buffer, url, pathShortener);
return makeSecure;
}
@@ -183,7 +203,20 @@ public boolean buildHostPart(Appendable buffer, String url, boolean useSSL) thro
* @throws WebAppConfigurationException
* @throws IOException
*/
- public void buildPathPart(Appendable buffer, String url) throws WebAppConfigurationException, IOException {
+ public void buildPathPart(Appendable buffer, String url)
+ throws WebAppConfigurationException, IOException, GenericEntityException {
+ buildPathPart(buffer, url, false);
+ }
+ /**
+ * Builds a partial URL - including the servlet path and resource, but not the scheme or host.
+ * @param buffer
+ * @param url
+ * @param pathShortener
+ * @throws WebAppConfigurationException
+ * @throws IOException
+ */
+ public void buildPathPart(Appendable buffer, String url, boolean pathShortener)
+ throws WebAppConfigurationException, IOException, GenericEntityException {
if (servletPath == null) {
throw new IllegalStateException("Servlet path is unknown");
}
@@ -191,6 +224,8 @@ public void buildPathPart(Appendable buffer, String url) throws WebAppConfigurat
if (!url.startsWith("/")) {
buffer.append("/");
}
- buffer.append(url);
+ buffer.append(pathShortener
+ ? OfbizPathShortener.shortenPath(delegator, url)
+ : url);
}
}
diff --git a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/RequestHandler.java b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/RequestHandler.java
index 020bc83f910..f02efae40ff 100644
--- a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/RequestHandler.java
+++ b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/RequestHandler.java
@@ -64,6 +64,7 @@
import org.apache.ofbiz.entity.util.EntityUtilProperties;
import org.apache.ofbiz.security.CsrfUtil;
import org.apache.ofbiz.webapp.OfbizUrlBuilder;
+import org.apache.ofbiz.webapp.OfbizPathShortener;
import org.apache.ofbiz.webapp.control.ConfigXMLReader.ControllerConfig;
import org.apache.ofbiz.webapp.control.ConfigXMLReader.RequestMap;
import org.apache.ofbiz.webapp.event.EventFactory;
@@ -901,6 +902,18 @@ public void doRequest(HttpServletRequest request, HttpServletResponse response,
}
String url = nextRequestResponse.getValue().startsWith("/") ? nextRequestResponse.getValue() : "/" + nextRequestResponse.getValue();
callRedirect(url + this.makeQueryString(request, nextRequestResponse), response, request, redirectSC);
+ } else if ("shortener".equals(nextRequestResponse.getType())) {
+ // check for a shortener
+ if (Debug.verboseOn()) {
+ Debug.logVerbose("[RequestHandler.doRequest]: Response is a shortener redirect." + showSessionId(request), MODULE);
+ }
+ String url = null;
+ try {
+ url = OfbizPathShortener.restoreOriginalPath(delegator, (String) request.getAttribute("shortener"));
+ } catch (GenericEntityException e) {
+ throw new RuntimeException(e);
+ }
+ callRedirect(url, response, request, redirectSC);
} else if ("request-redirect".equals(nextRequestResponse.getType())) {
if (Debug.verboseOn()) {
Debug.logVerbose("[RequestHandler.doRequest]: Response is a Request redirect." + showSessionId(request), MODULE);
@@ -1359,6 +1372,10 @@ public String makeLink(HttpServletRequest request, HttpServletResponse response,
public String makeLink(HttpServletRequest request, HttpServletResponse response, String url, boolean fullPath, boolean secure, boolean encode,
String targetControlPath) {
+ return makeLink(request, response, url, fullPath, secure, encode, "", false);
+ }
+ public String makeLink(HttpServletRequest request, HttpServletResponse response, String url, boolean fullPath, boolean secure, boolean encode,
+ String targetControlPath, boolean pathShortener) {
WebSiteProperties webSiteProps = null;
try {
webSiteProps = WebSiteProperties.from(request);
@@ -1458,8 +1475,19 @@ public String makeLink(HttpServletRequest request, HttpServletResponse response,
}
// now add the actual passed url, but if it doesn't start with a / add one first
- if (url != null && !url.startsWith("/")) {
- newURL.append("/");
+ if (url != null) {
+ if (!url.startsWith("/")) {
+ newURL.append("/");
+ }
+ if (pathShortener) {
+ try {
+ url = OfbizPathShortener.shortenPath(delegator, url);
+ } catch (GenericEntityException e) {
+ // If the entity engine is throwing exceptions, then there is no point in continuing.
+ Debug.logError(e, "Exception thrown while getting the path shortener: ", MODULE);
+ return null;
+ }
+ }
}
newURL.append(url == null ? "" : url);
diff --git a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/ftl/OfbizUrlTransform.java b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/ftl/OfbizUrlTransform.java
index 763b4f087fc..829a7392efc 100644
--- a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/ftl/OfbizUrlTransform.java
+++ b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/ftl/OfbizUrlTransform.java
@@ -47,6 +47,7 @@
*
fullPath (true/false) - generate a full URL including scheme and host, defaults to false.
* secure (true/false) - generate a secure (https) URL, defaults to false. Server settings will
* override this argument.
+ * pathShortener (true/false) - generate a shortened URL. Defaults to false.
* encode (true/false) - encode the URL, defaults to true. Encoding is UTF-8.
* webSiteId - generate a full URL using the web site settings found in the WebSite entity.
* controlPath - override the default control path.
@@ -96,6 +97,7 @@ public Writer getWriter(final Writer out, Map args) {
final StringBuilder buf = new StringBuilder();
final boolean fullPath = checkBooleanArg(args, "fullPath", false);
final boolean secure = checkBooleanArg(args, "secure", false);
+ final boolean pathShortener = checkBooleanArg(args, "pathShortener", false);
final boolean encode = checkBooleanArg(args, "encode", true);
final String webSiteId = convertToString(args.get("webSiteId"));
final String controlPath = convertToString(args.get("controlPath"));
@@ -133,7 +135,7 @@ public void close() throws IOException {
WebappInfo webAppInfo = WebAppUtil.getWebappInfoFromWebsiteId(webSiteId);
StringBuilder newUrlBuff = new StringBuilder(250);
OfbizUrlBuilder builder = OfbizUrlBuilder.from(webAppInfo, delegator);
- builder.buildFullUrl(newUrlBuff, buf.toString(), secure);
+ builder.buildFullUrl(newUrlBuff, buf.toString(), secure, pathShortener);
String newUrl = newUrlBuff.toString();
if (encode) {
newUrl = URLEncoder.encode(newUrl, "UTF-8");
@@ -145,7 +147,7 @@ public void close() throws IOException {
HttpServletResponse response = FreeMarkerWorker.unwrap(env.getVariable("response"));
String requestUrl = buf.toString();
RequestHandler rh = RequestHandler.from(request);
- String link = (rh.makeLink(request, response, requestUrl, fullPath, secure, encode, controlPath));
+ String link = (rh.makeLink(request, response, requestUrl, fullPath, secure, encode, controlPath, pathShortener));
out.write(link);
} else {
out.write(buf.toString());
diff --git a/framework/webapp/testdef/webapptests.xml b/framework/webapp/testdef/webapptests.xml
index f33f4989947..692e5640fa8 100644
--- a/framework/webapp/testdef/webapptests.xml
+++ b/framework/webapp/testdef/webapptests.xml
@@ -20,5 +20,5 @@
-
+