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
|
@Override
|
||||||
public String apply(String target, HttpServletRequest request, HttpServletResponse response) throws IOException
|
public String apply(String target, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||||
{
|
{
|
||||||
response.setHeader("Location",response.encodeRedirectURL(_location));
|
String location = response.encodeRedirectURL(_location);
|
||||||
response.sendError(_statusCode);
|
response.setHeader("Location",RedirectUtil.toRedirectURL(request,location));
|
||||||
|
response.setStatus(_statusCode);
|
||||||
|
response.getOutputStream().flush(); // no output / content
|
||||||
|
response.getOutputStream().close();
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -83,9 +83,12 @@ public class RedirectRegexRule extends RegexRule
|
||||||
String group = matcher.group(g);
|
String group = matcher.group(g);
|
||||||
target=target.replaceAll("\\$"+g,group);
|
target=target.replaceAll("\\$"+g,group);
|
||||||
}
|
}
|
||||||
|
|
||||||
response.setHeader("Location",response.encodeRedirectURL(target));
|
target = response.encodeRedirectURL(target);
|
||||||
response.sendError(_statusCode);
|
response.setHeader("Location",RedirectUtil.toRedirectURL(request,target));
|
||||||
|
response.setStatus(_statusCode);
|
||||||
|
response.getOutputStream().flush(); // no output / content
|
||||||
|
response.getOutputStream().close();
|
||||||
return target;
|
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);
|
rule.matchAndApply("/my/dir/file/", _request, _response);
|
||||||
assertRedirectResponse(HttpStatus.FOUND_302,"http://www.mortbay.org/");
|
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
|
@Test
|
||||||
public void testLocationWithReplacmentGroupSimple() throws IOException
|
public void testLocationWithReplacmentGroupSimple() throws IOException
|
||||||
|
|
|
@ -18,10 +18,8 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.test.rfcs;
|
package org.eclipse.jetty.test.rfcs;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.hamcrest.Matchers.*;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.*;
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
import static org.junit.matchers.JUnitMatchers.containsString;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -1159,12 +1157,12 @@ public abstract class RFC2616BaseTest
|
||||||
req4.append("\n");
|
req4.append("\n");
|
||||||
|
|
||||||
HttpTester.Response response = http.request(req4);
|
HttpTester.Response response = http.request(req4);
|
||||||
|
|
||||||
String specId = "10.3 Redirection HTTP/1.1 w/content";
|
String specId = "10.3 Redirection HTTP/1.1 w/content";
|
||||||
assertEquals(specId,HttpStatus.FOUND_302, response.getStatus());
|
assertThat(specId + " [status]",response.getStatus(),is(HttpStatus.FOUND_302));
|
||||||
assertEquals(specId,server.getScheme() + "://localhost/tests/R2.txt", response.get("Location"));
|
assertThat(specId + " [location]",response.get("Location"),is(server.getScheme() + "://localhost/tests/R2.txt"));
|
||||||
assertEquals(specId,"close", response.get("Connection"));
|
assertThat(specId + " [connection]",response.get("Connection"),is("close"));
|
||||||
assertTrue(specId,response.get("Content-Length") == null);
|
assertThat(specId + " [content-length]",response.get("Content-Length"), nullValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue