From ea182f0416432c5ce311499df230948d876edaaf Mon Sep 17 00:00:00 2001 From: Adam Retter Date: Tue, 5 Sep 2023 01:00:01 +0200 Subject: [PATCH] [feature] Allow the redirect type (i.e. HTTP Response Status Code) to be specified in the URL Rewite Controller (i.e. `controller.xq`) See https://github.com/eXist-db/existdb-saml/issues/11 --- .../org/exist/http/urlrewrite/Redirect.java | 61 ++++++++++++++++++- 1 file changed, 58 insertions(+), 3 deletions(-) diff --git a/exist-core/src/main/java/org/exist/http/urlrewrite/Redirect.java b/exist-core/src/main/java/org/exist/http/urlrewrite/Redirect.java index 432ea5e0715..c078c3d7300 100644 --- a/exist-core/src/main/java/org/exist/http/urlrewrite/Redirect.java +++ b/exist-core/src/main/java/org/exist/http/urlrewrite/Redirect.java @@ -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(" needs an attribute 'url'."); } if (redirectTo.matches("^\\w+://.*")) { @@ -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("