Skip to content

Commit

Permalink
[feature] Allow the redirect type (i.e. HTTP Response Status Code) to…
Browse files Browse the repository at this point in the history
… be specified in the URL Rewite Controller (i.e. `controller.xq`)

See eXist-db/existdb-saml#11
  • Loading branch information
adamretter committed Sep 4, 2023
1 parent d0d511e commit ea182f0
Showing 1 changed file with 58 additions and 3 deletions.
61 changes: 58 additions & 3 deletions exist-core/src/main/java/org/exist/http/urlrewrite/Redirect.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,19 @@
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import javax.annotation.Nullable;
import java.io.IOException;

public class Redirect extends URLRewrite {

private @Nullable RedirectType redirectType;

public Redirect(final Element config, final String uri) throws ServletException {
super(config, uri);
this.redirectType = parseRedirectType(config.getAttribute("type"));
final String redirectTo = config.getAttribute("url");
if (redirectTo.length() == 0) {
if (redirectTo.isEmpty()) {
throw new ServletException("<exist:redirect> needs an attribute 'url'.");
}
if (redirectTo.matches("^\\w+://.*")) {
Expand All @@ -47,16 +52,66 @@ public Redirect(final Element config, final String uri) throws ServletException

public Redirect(final Redirect other) {
super(other);
this.redirectType = other.redirectType;
}

@Override
public void doRewrite(final HttpServletRequest request, final HttpServletResponse response) throws IOException {
setHeaders(new HttpResponseWrapper(response));
response.sendRedirect(target);
if (redirectType == null) {
redirectType = "GET".equals(request.getMethod()) ? RedirectType.Found : RedirectType.SeeOther;
}

final HttpResponseWrapper responseWrapper = new HttpResponseWrapper(response);
setHeaders(responseWrapper);
responseWrapper.setStatusCode(redirectType.httpStatusCode);
responseWrapper.setHeader("Location", target);

// commit the response
responseWrapper.flushBuffer();
}

@Override
protected URLRewrite copy() {
return new Redirect(this);
}

private static @Nullable RedirectType parseRedirectType(@Nullable final String strRedirectType) throws ServletException {
// first, if no value use the default
if (strRedirectType == null || strRedirectType.isEmpty()) {
return null;
}

// second, try to parse by number
try {
final int intRedirectType = Integer.valueOf(strRedirectType);
for (final RedirectType redirectType : RedirectType.values()) {
if (redirectType.httpStatusCode == intRedirectType) {
return redirectType;
}
}
} catch (final NumberFormatException e) {
// ignore - no op
}

// third, try to parse by name
try {
return RedirectType.valueOf(strRedirectType);
} catch (final IllegalArgumentException e) {
throw new ServletException("<exist:redirect type=\"" + strRedirectType + "\" is unsupported.");
}
}

private enum RedirectType {
MovedPermanently(301),
Found(302),
SeeOther(303),
TemporaryRedirect(307),
PermanentRedirect(308);

public final int httpStatusCode;

RedirectType(final int httpStatusCode) {
this.httpStatusCode = httpStatusCode;
}
}
}

0 comments on commit ea182f0

Please sign in to comment.