Skip to content

Commit ea182f0

Browse files
committed
[feature] Allow the redirect type (i.e. HTTP Response Status Code) to be specified in the URL Rewite Controller (i.e. controller.xq)
See eXist-db/existdb-saml#11
1 parent d0d511e commit ea182f0

File tree

1 file changed

+58
-3
lines changed

1 file changed

+58
-3
lines changed

exist-core/src/main/java/org/exist/http/urlrewrite/Redirect.java

+58-3
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,19 @@
2727
import jakarta.servlet.ServletException;
2828
import jakarta.servlet.http.HttpServletRequest;
2929
import jakarta.servlet.http.HttpServletResponse;
30+
31+
import javax.annotation.Nullable;
3032
import java.io.IOException;
3133

3234
public class Redirect extends URLRewrite {
3335

36+
private @Nullable RedirectType redirectType;
37+
3438
public Redirect(final Element config, final String uri) throws ServletException {
3539
super(config, uri);
40+
this.redirectType = parseRedirectType(config.getAttribute("type"));
3641
final String redirectTo = config.getAttribute("url");
37-
if (redirectTo.length() == 0) {
42+
if (redirectTo.isEmpty()) {
3843
throw new ServletException("<exist:redirect> needs an attribute 'url'.");
3944
}
4045
if (redirectTo.matches("^\\w+://.*")) {
@@ -47,16 +52,66 @@ public Redirect(final Element config, final String uri) throws ServletException
4752

4853
public Redirect(final Redirect other) {
4954
super(other);
55+
this.redirectType = other.redirectType;
5056
}
5157

5258
@Override
5359
public void doRewrite(final HttpServletRequest request, final HttpServletResponse response) throws IOException {
54-
setHeaders(new HttpResponseWrapper(response));
55-
response.sendRedirect(target);
60+
if (redirectType == null) {
61+
redirectType = "GET".equals(request.getMethod()) ? RedirectType.Found : RedirectType.SeeOther;
62+
}
63+
64+
final HttpResponseWrapper responseWrapper = new HttpResponseWrapper(response);
65+
setHeaders(responseWrapper);
66+
responseWrapper.setStatusCode(redirectType.httpStatusCode);
67+
responseWrapper.setHeader("Location", target);
68+
69+
// commit the response
70+
responseWrapper.flushBuffer();
5671
}
5772

5873
@Override
5974
protected URLRewrite copy() {
6075
return new Redirect(this);
6176
}
77+
78+
private static @Nullable RedirectType parseRedirectType(@Nullable final String strRedirectType) throws ServletException {
79+
// first, if no value use the default
80+
if (strRedirectType == null || strRedirectType.isEmpty()) {
81+
return null;
82+
}
83+
84+
// second, try to parse by number
85+
try {
86+
final int intRedirectType = Integer.valueOf(strRedirectType);
87+
for (final RedirectType redirectType : RedirectType.values()) {
88+
if (redirectType.httpStatusCode == intRedirectType) {
89+
return redirectType;
90+
}
91+
}
92+
} catch (final NumberFormatException e) {
93+
// ignore - no op
94+
}
95+
96+
// third, try to parse by name
97+
try {
98+
return RedirectType.valueOf(strRedirectType);
99+
} catch (final IllegalArgumentException e) {
100+
throw new ServletException("<exist:redirect type=\"" + strRedirectType + "\" is unsupported.");
101+
}
102+
}
103+
104+
private enum RedirectType {
105+
MovedPermanently(301),
106+
Found(302),
107+
SeeOther(303),
108+
TemporaryRedirect(307),
109+
PermanentRedirect(308);
110+
111+
public final int httpStatusCode;
112+
113+
RedirectType(final int httpStatusCode) {
114+
this.httpStatusCode = httpStatusCode;
115+
}
116+
}
62117
}

0 commit comments

Comments
 (0)