Skip to content
This repository has been archived by the owner on Mar 9, 2022. It is now read-only.

Commit

Permalink
Rename UriRedirect -> PathRedirect and add new UriRedirect functional…
Browse files Browse the repository at this point in the history
…ity.
  • Loading branch information
Brandon Beck committed Jul 25, 2014
1 parent 2259be9 commit 47e6531
Show file tree
Hide file tree
Showing 5 changed files with 247 additions and 61 deletions.
25 changes: 21 additions & 4 deletions README.md
Expand Up @@ -13,31 +13,31 @@ Just add this maven dependency:
- For Dropwizard 0.6.2: use version < 0.3.0
- For Dropwizard 0.7.0: use version >= 0.3.0

To redirect one URI to another URI:
To redirect one path to another path:
```java
public class MyApplication extends Application<...> {
// ...

@Override
public void initialize(Bootstrap<?> bootstrap) {
bootstrap.addBundle(new RedirectBundle(
new UriRedirect("/old", "/new")
new PathRedirect("/old", "/new")
));
}

// ...
}
```

To redirect many URIs at once:
To redirect many paths at once:
```java
public class MyApplication extends Application<...> {
// ...

@Override
public void initialize(Bootstrap<?> bootstrap) {
bootstrap.addBundle(new RedirectBundle(
new UriRedirect(ImmutableMap.<String, String>builder()
new PathRedirect(ImmutableMap.<String, String>builder()
.put("/old1", "/new1")
.put("/old2", "/new2")
.build())
Expand All @@ -64,3 +64,20 @@ public class MyApplication extends Application<...> {
}
```

For more advanced users, there is also a regular expression based redirector that has access to the full URI. This
operates in a similar fashion to the mod-rewrite module for Apache:
```java
public class MyApplication extends Application<...> {
// ...

@Override
public void initialize(Bootstrap<?> bootstrap) {
bootstrap.addBundle(new RedirectBundle(
new UriRedirect("(.*)/welcome.html$", "$1/index.html")
));
}

// ...
}
```

@@ -0,0 +1,57 @@
package com.bazaarvoice.dropwizard.redirect;

import com.google.common.collect.ImmutableMap;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

import static com.google.common.base.Preconditions.checkNotNull;

/** Redirects requests coming on a specific source path to a target path. */
public class PathRedirect implements Redirect {
private final Map<String, String> pathMapping;
private final boolean keepParameters;

public PathRedirect(String sourceUri, String targetUri) {
this(sourceUri, targetUri, true);
}

public PathRedirect(String sourceUri, String targetUri, boolean keepParameters) {
checkNotNull(sourceUri);
checkNotNull(targetUri);

pathMapping = ImmutableMap.of(sourceUri, targetUri);
this.keepParameters = keepParameters;
}

public PathRedirect(Map<String, String> uriMap) {
this(uriMap, true);
}

public PathRedirect(Map<String, String> uriMap, boolean keepParameters) {
checkNotNull(uriMap);

pathMapping = ImmutableMap.copyOf(uriMap);
this.keepParameters = keepParameters;
}

/** {@inheritDoc} */
@Override
public String getRedirect(HttpServletRequest request) {
String uri = pathMapping.get(request.getRequestURI());
if (uri == null) {
return null;
}

StringBuilder redirect = new StringBuilder(uri);
if (keepParameters) {
String query = request.getQueryString();
if (query != null) {
redirect.append('?');
redirect.append(query);
}
}

return redirect.toString();
}
}
81 changes: 51 additions & 30 deletions src/main/java/com/bazaarvoice/dropwizard/redirect/UriRedirect.java
@@ -1,57 +1,78 @@
package com.bazaarvoice.dropwizard.redirect;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.google.common.base.Preconditions.checkNotNull;

/** Redirects requests coming on a specific source URI to a target URI. */
/** Regular expression based redirect. Has access to the full URI. */
public class UriRedirect implements Redirect {
private final Map<String, String> uriMapping;
private final boolean keepParameters;
private final List<Entry> entries;

public UriRedirect(String sourceUri, String targetUri) {
this(sourceUri, targetUri, true);
}

public UriRedirect(String sourceUri, String targetUri, boolean keepParameters) {
checkNotNull(sourceUri);
checkNotNull(targetUri);
public UriRedirect(String regex, String replacement) {
checkNotNull(regex);
checkNotNull(replacement);

uriMapping = ImmutableMap.of(sourceUri, targetUri);
this.keepParameters = keepParameters;
entries = ImmutableList.of(new Entry(Pattern.compile(regex), replacement));
}

public UriRedirect(Map<String, String> uriMap) {
this(uriMap, true);
}

public UriRedirect(Map<String, String> uriMap, boolean keepParameters) {
checkNotNull(uriMap);

uriMapping = ImmutableMap.copyOf(uriMap);
this.keepParameters = keepParameters;
entries = Lists.newArrayList();
for (Map.Entry<String, String> entry : uriMap.entrySet()) {
String regex = entry.getKey();
String replacement = entry.getValue();
entries.add(new Entry(Pattern.compile(regex), replacement));
}
}

/** {@inheritDoc} */
@Override
public String getRedirect(HttpServletRequest request) {
String uri = uriMapping.get(request.getRequestURI());
if (uri == null) {
return null;
String uri = getFullURI(request);
for (Entry entry : entries) {
Matcher matcher = entry.getRegex().matcher(uri);
if (matcher.matches()) {
return matcher.replaceAll(entry.getReplacement());
}
}

StringBuilder redirect = new StringBuilder(uri);
if (keepParameters) {
String query = request.getQueryString();
if (query != null) {
redirect.append('?');
redirect.append(query);
}
return null;
}

private static String getFullURI(HttpServletRequest request) {
StringBuffer requestURL = request.getRequestURL();
String queryString = request.getQueryString();

if (queryString == null) {
return requestURL.toString();
} else {
return requestURL.append('?').append(queryString).toString();
}
}

private static final class Entry {
Pattern regex;
String replacement;

Entry(Pattern regex, String replacement) {
this.regex = regex;
this.replacement = replacement;
}

Pattern getRegex() {
return regex;
}

return redirect.toString();
String getReplacement() {
return replacement;
}
}
}
@@ -0,0 +1,74 @@
package com.bazaarvoice.dropwizard.redirect;

import com.google.common.collect.ImmutableMap;
import org.junit.Test;
import org.mockito.internal.stubbing.answers.ThrowsException;

import javax.servlet.http.HttpServletRequest;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;

public class PathRedirectTest {
private final PathRedirect redirect = new PathRedirect(ImmutableMap.<String, String>builder()
.put("/old1", "/new1")
.put("/old2", "/new2")
.build()
);

@Test
public void testMatchingUri() {
HttpServletRequest request = request("/old1");

String uri = redirect.getRedirect(request);
assertEquals("/new1", uri);
}

@Test
public void testMatchingUriWithKeepParameters() {
HttpServletRequest request = request("/old1?key=value");

String uri = redirect.getRedirect(request);
assertEquals("/new1?key=value", uri);
}

@Test
public void testMatchingUriWithoutKeepParameters() {
PathRedirect redirect = new PathRedirect("/old1", "/new1", false);
HttpServletRequest request = request("/old1?key=value");

String uri = redirect.getRedirect(request);
assertEquals("/new1", uri);
}

@Test
public void testNonMatchingUri() {
HttpServletRequest request = request("/new");

String uri = redirect.getRedirect(request);
assertNull(uri);
}

@Test
public void testSubstringUri() {
HttpServletRequest request = request("/old100");

String uri = redirect.getRedirect(request);
assertNull(uri);
}

private static HttpServletRequest request(String uri) {
int question = uri.indexOf('?');
String path = (question == -1) ? uri : uri.substring(0, question);
String params = (question == -1) ? null : uri.substring(question + 1);

// By default have the mock throw an exception when we've forgotten to mock a method that is called.
Exception exception = new RuntimeException("Forgot to mock a method");
HttpServletRequest request = mock(HttpServletRequest.class, new ThrowsException(exception));
doReturn(path).when(request).getRequestURI();
doReturn(params).when(request).getQueryString();
return request;
}
}

0 comments on commit 47e6531

Please sign in to comment.