diff --git a/config-prettyfaces-tests/src/test/java/org/ocpsoft/rewrite/prettyfaces/encoding/URLEncodingTest.java b/config-prettyfaces-tests/src/test/java/org/ocpsoft/rewrite/prettyfaces/encoding/URLEncodingTest.java index 80eb85741..7b3190016 100644 --- a/config-prettyfaces-tests/src/test/java/org/ocpsoft/rewrite/prettyfaces/encoding/URLEncodingTest.java +++ b/config-prettyfaces-tests/src/test/java/org/ocpsoft/rewrite/prettyfaces/encoding/URLEncodingTest.java @@ -72,7 +72,8 @@ public void testRewriteEncodingUrl() throws Exception HttpAction action = get(target); - Assert.assertTrue(action.getCurrentURL().endsWith(expected)); + Assert.assertTrue(action.getCurrentURL() + " should end with " + expected, + action.getCurrentURL().endsWith(expected)); Assert.assertTrue(action.getResponseContent().contains(expected)); } diff --git a/config-prettyfaces/src/main/java/org/ocpsoft/rewrite/prettyfaces/InboundRewriteRuleAdaptor.java b/config-prettyfaces/src/main/java/org/ocpsoft/rewrite/prettyfaces/InboundRewriteRuleAdaptor.java index c383151ec..5b4062647 100644 --- a/config-prettyfaces/src/main/java/org/ocpsoft/rewrite/prettyfaces/InboundRewriteRuleAdaptor.java +++ b/config-prettyfaces/src/main/java/org/ocpsoft/rewrite/prettyfaces/InboundRewriteRuleAdaptor.java @@ -21,12 +21,18 @@ */ package org.ocpsoft.rewrite.prettyfaces; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.regex.Pattern; + import org.ocpsoft.rewrite.config.Rule; import org.ocpsoft.rewrite.context.EvaluationContext; import org.ocpsoft.rewrite.event.Rewrite; import org.ocpsoft.rewrite.servlet.http.event.HttpInboundServletRewrite; import org.ocpsoft.rewrite.servlet.http.event.HttpServletRewrite; -import org.ocpsoft.rewrite.servlet.util.URLBuilder; +import org.ocpsoft.urlbuilder.Address; +import org.ocpsoft.urlbuilder.AddressBuilder; +import org.ocpsoft.urlbuilder.util.Encoder; import com.ocpsoft.pretty.faces.config.rewrite.Redirect; import com.ocpsoft.pretty.faces.config.rewrite.RewriteRule; @@ -87,12 +93,11 @@ public void perform(final Rewrite event, final EvaluationContext context) originalUrl = URL.build(originalUrl).decode().toURL() + QueryString.build(httpRewrite.getInboundAddress().getQuery()).toQueryString(); - String contextPath = ((HttpServletRewrite) event).getContextPath(); - if (!contextPath.equals("/") && originalUrl.startsWith(contextPath)) - originalUrl = originalUrl.substring(contextPath.length()); + String contextPath = httpRewrite.getContextPath(); + originalUrl = StringUtils.removePathPrefix(contextPath, originalUrl); - String newUrl = engine.processInbound(((HttpServletRewrite) event).getRequest(), - ((HttpServletRewrite) event).getResponse(), rule, originalUrl); + String newUrl = engine.processInbound(httpRewrite.getRequest(), + httpRewrite.getResponse(), rule, originalUrl); if (!Redirect.CHAIN.equals(rule.getRedirect())) { @@ -110,14 +115,14 @@ public void perform(final Rewrite event, final EvaluationContext context) { /* - * Add context path and encode request using encodeRedirectURL(). + * Add context path. */ redirectURL = contextPath + newUrl; } else if (StringUtils.isNotBlank(rule.getUrl())) { /* - * This is a custom location - don't call encodeRedirectURL() and don't add context path, just + * This is a custom location - don't add context path, just * redirect to the encoded URL */ redirectURL = newUrl.trim(); @@ -126,8 +131,56 @@ else if (StringUtils.isNotBlank(rule.getUrl())) if (redirectURL != null) { - URLBuilder encodedRedirectUrl = URLBuilder.createFrom(redirectURL).encode(); - redirectURL = encodedRedirectUrl.toString(); + if (redirectURL.contains(" ")) { + String[] parts = redirectURL.split(Pattern.quote("?"), 2); + String[] encodedParts = new String[parts.length]; + encodedParts[0] = Encoder.path(parts[0]); + + if (parts.length > 1) { + encodedParts[1] = Encoder.query(parts[1]); + + StringBuilder joiner = new StringBuilder(encodedParts[0]); + joiner.append("?").append(encodedParts[1]); + + redirectURL = joiner.toString(); + } + else + { + redirectURL = encodedParts[0]; + } + } + + try + { + URI uri = new URI(redirectURL); + if (uri.getScheme() == null && uri.getHost() != null) { + String path = uri.getPath(); + if (StringUtils.hasLeadingSlash(path)) + { + path = path.substring(1); + } + + Address encodedRedirectAddress + = AddressBuilder.begin() + .scheme(uri.getScheme()) + .domain(uri.getHost()) + .port(uri.getPort()) + .path("/{p}") + .setEncoded("p", path) + .queryLiteral(QueryString.build(uri.getQuery()).toQueryString()) + .anchor(uri.getRawFragment()) + .buildLiteral(); + redirectURL = encodedRedirectAddress.toString(); + } + } + catch (URISyntaxException e) + { + throw new IllegalArgumentException( + "[" + redirectURL + "] is not a valid URL fragment. Consider encoding relevant portions of the URL with [" + + Encoder.class + + "], or use the provided builder pattern to specify part encoding.", e); + } + if (Redirect.PERMANENT.equals(rule.getRedirect())) ((HttpInboundServletRewrite) event).redirectPermanent(redirectURL); if (Redirect.TEMPORARY.equals(rule.getRedirect())) diff --git a/integration-faces/src/main/java/org/ocpsoft/rewrite/faces/RewriteViewHandler.java b/integration-faces/src/main/java/org/ocpsoft/rewrite/faces/RewriteViewHandler.java index 5cb67773a..18f835447 100644 --- a/integration-faces/src/main/java/org/ocpsoft/rewrite/faces/RewriteViewHandler.java +++ b/integration-faces/src/main/java/org/ocpsoft/rewrite/faces/RewriteViewHandler.java @@ -16,6 +16,8 @@ package org.ocpsoft.rewrite.faces; import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; import java.util.Collections; import java.util.List; import java.util.Locale; @@ -32,7 +34,9 @@ import org.ocpsoft.common.services.ServiceLoader; import org.ocpsoft.common.util.Iterators; import org.ocpsoft.rewrite.faces.spi.FacesActionUrlProvider; -import org.ocpsoft.rewrite.servlet.util.URLBuilder; +import org.ocpsoft.urlbuilder.Address; +import org.ocpsoft.urlbuilder.AddressBuilder; +import org.ocpsoft.urlbuilder.util.Encoder; /** * @author Lincoln Baxter, III @@ -131,9 +135,37 @@ public String getActionURL(final FacesContext context, final String viewId) String parentActionURL = parent.getActionURL(context, viewId); if (parentActionURL.contains("?")) { - URLBuilder builder = URLBuilder.createFrom(result); - builder.getQueryStringBuilder().addParameters(parentActionURL); - result = builder.toURL(); + try + { + URI uri = new URI(result); + URI action = new URI(parentActionURL); + StringBuilder query = new StringBuilder(uri.getQuery()); + if (query.length() > 0 && action.getQuery() != null) { + query.append('&'); + } + query.append(action.getQuery()); + + if (uri.getScheme() == null && uri.getHost() != null) { + Address address + = AddressBuilder.begin() + .scheme(uri.getScheme()) + .domain(uri.getHost()) + .port(uri.getPort()) + .pathDecoded(uri.getPath()) + .queryLiteral(query.toString()) + .anchor(uri.getRawFragment()) + .buildLiteral(); + + result = address.toString(); + } + } + catch (URISyntaxException e) + { + throw new IllegalArgumentException( + "[" + result + "] is not a valid URL fragment. Consider encoding relevant portions of the URL with [" + + Encoder.class + + "], or use the provided builder pattern to specify part encoding.", e); + } } } }