Supplementing redirect rules with RedirectUtil
+ Redirect rules should produce full URI for "Location" header + Redirect rules should produce no response body content
This commit is contained in:
parent
e24cc3ee5e
commit
0476d4d28d
|
@ -73,8 +73,11 @@ public class RedirectPatternRule extends PatternRule
|
|||
@Override
|
||||
public String apply(String target, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
response.setHeader("Location",response.encodeRedirectURL(_location));
|
||||
response.sendError(_statusCode);
|
||||
String location = response.encodeRedirectURL(_location);
|
||||
response.setHeader("Location",RedirectUtil.toRedirectURL(request,location));
|
||||
response.setStatus(_statusCode);
|
||||
response.getOutputStream().flush(); // no output / content
|
||||
response.getOutputStream().close();
|
||||
return target;
|
||||
}
|
||||
|
||||
|
|
|
@ -83,9 +83,12 @@ public class RedirectRegexRule extends RegexRule
|
|||
String group = matcher.group(g);
|
||||
target=target.replaceAll("\\$"+g,group);
|
||||
}
|
||||
|
||||
response.setHeader("Location",response.encodeRedirectURL(target));
|
||||
response.sendError(_statusCode);
|
||||
|
||||
target = response.encodeRedirectURL(target);
|
||||
response.setHeader("Location",RedirectUtil.toRedirectURL(request,target));
|
||||
response.setStatus(_statusCode);
|
||||
response.getOutputStream().flush(); // no output / content
|
||||
response.getOutputStream().close();
|
||||
return target;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.rewrite.handler;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
|
||||
/**
|
||||
* Utility for managing redirect based rules
|
||||
*/
|
||||
public final class RedirectUtil
|
||||
{
|
||||
/**
|
||||
* Common point to generate a proper "Location" header for redirects.
|
||||
*
|
||||
* @param request
|
||||
* the request the redirect should be based on (needed when relative locations are provided, so that
|
||||
* server name, scheme, port can be built out properly)
|
||||
* @param location
|
||||
* the location URL to redirect to (can be a relative path)
|
||||
* @return the full redirect "Location" URL (including scheme, host, port, path, etc...)
|
||||
*/
|
||||
public static String toRedirectURL(final HttpServletRequest request, String location)
|
||||
{
|
||||
if (!URIUtil.hasScheme(location))
|
||||
{
|
||||
StringBuilder url = new StringBuilder(128);
|
||||
URIUtil.appendSchemeHostPort(url,request.getScheme(),request.getServerName(),request.getServerPort());
|
||||
|
||||
if (location.startsWith("/"))
|
||||
{
|
||||
// absolute in context
|
||||
location = URIUtil.canonicalPath(location);
|
||||
}
|
||||
else
|
||||
{
|
||||
// relative to request
|
||||
String path = request.getRequestURI();
|
||||
String parent = (path.endsWith("/")) ? path : URIUtil.parentPath(path);
|
||||
location = URIUtil.canonicalPath(URIUtil.addPaths(parent,location));
|
||||
if (!location.startsWith("/"))
|
||||
url.append('/');
|
||||
}
|
||||
|
||||
if (location == null)
|
||||
throw new IllegalStateException("path cannot be above root");
|
||||
url.append(location);
|
||||
|
||||
location = url.toString();
|
||||
}
|
||||
|
||||
return location;
|
||||
}
|
||||
}
|
|
@ -53,6 +53,18 @@ public class RedirectRegexRuleTest extends AbstractRuleTestCase
|
|||
rule.matchAndApply("/my/dir/file/", _request, _response);
|
||||
assertRedirectResponse(HttpStatus.FOUND_302,"http://www.mortbay.org/");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocationWithPathReplacement() throws IOException
|
||||
{
|
||||
RedirectRegexRule rule = new RedirectRegexRule();
|
||||
rule.setRegex("/documentation/(.*)$");
|
||||
rule.setReplacement("/docs/$1");
|
||||
|
||||
// Resource is dir
|
||||
rule.matchAndApply("/documentation/top.html", _request, _response);
|
||||
assertRedirectResponse(HttpStatus.FOUND_302,"http://0.0.0.0/docs/top.html");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocationWithReplacmentGroupSimple() throws IOException
|
||||
|
|
|
@ -18,10 +18,8 @@
|
|||
|
||||
package org.eclipse.jetty.test.rfcs;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.matchers.JUnitMatchers.containsString;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
@ -1159,12 +1157,12 @@ public abstract class RFC2616BaseTest
|
|||
req4.append("\n");
|
||||
|
||||
HttpTester.Response response = http.request(req4);
|
||||
|
||||
|
||||
String specId = "10.3 Redirection HTTP/1.1 w/content";
|
||||
assertEquals(specId,HttpStatus.FOUND_302, response.getStatus());
|
||||
assertEquals(specId,server.getScheme() + "://localhost/tests/R2.txt", response.get("Location"));
|
||||
assertEquals(specId,"close", response.get("Connection"));
|
||||
assertTrue(specId,response.get("Content-Length") == null);
|
||||
assertThat(specId + " [status]",response.getStatus(),is(HttpStatus.FOUND_302));
|
||||
assertThat(specId + " [location]",response.get("Location"),is(server.getScheme() + "://localhost/tests/R2.txt"));
|
||||
assertThat(specId + " [connection]",response.get("Connection"),is("close"));
|
||||
assertThat(specId + " [content-length]",response.get("Content-Length"), nullValue());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue