Last active
January 14, 2022 09:29
-
-
Save qb20nh/e4e8b87cf15f14cbaa6fe779c0b87d60 to your computer and use it in GitHub Desktop.
Intercept Redirect
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package kr.co.benew.iddle_admin.servlet; | |
import java.io.IOException; | |
import java.util.ArrayList; | |
import java.util.List; | |
import java.util.function.BiFunction; | |
import java.util.function.UnaryOperator; | |
import javax.servlet.ServletResponse; | |
import javax.servlet.http.HttpServletResponse; | |
import javax.servlet.http.HttpServletResponseWrapper; | |
import kr.co.benew.util.Values; | |
import lombok.AllArgsConstructor; | |
import lombok.Getter; | |
import lombok.NonNull; | |
import lombok.RequiredArgsConstructor; | |
import lombok.Setter; | |
public class HttpRedirectInterceptor extends HttpServletResponseWrapper { | |
public enum InterceptionReplacementRule { | |
APPLY_FIRST, | |
APPLY_ALL, | |
APPLY_LAST, | |
} | |
private @Setter InterceptionReplacementRule replacementRule = InterceptionReplacementRule.APPLY_FIRST; | |
public static interface Matcher extends BiFunction<String, String, Boolean> { | |
} | |
@AllArgsConstructor | |
@RequiredArgsConstructor | |
public enum InterceptionMatchRule { | |
STARTS_WITH("NOT_STARTS_WITH", (a, b) -> a.startsWith(b)), | |
INCLUDES("NOT_INCLUDES", (a, b) -> a.contains(b)), | |
ENDS_WITH("NOT_ENDS_WITH", (a, b) -> a.endsWith(b)), | |
MATCHES("NOT_MATCHES", (a, b) -> a.matches(b)), | |
EQUALS("NOT_EQUALS", (a, b) -> a.equals(b)), | |
EQUALS_IGNORE_CASE("NOT_EQUALS_IGNORE_CASE", (a, b) -> a.equalsIgnoreCase(b)), | |
EMPTY("NOT_EMPTY", (a, b) -> a != null && a.isEmpty()), | |
NOT_STARTS_WITH("STARTS_WITH"), | |
NOT_INCLUDES("INCLUDES"), | |
NOT_ENDS_WITH("ENDS_WITH"), | |
NOT_MATCHES("MATCHES"), | |
NOT_EQUALS("EQUALS"), | |
NOT_EQUALS_IGNORE_CASE("EQUALS_IGNORE_CASE"), | |
NOT_EMPTY("EMPTY"); | |
@NonNull private final String opposite; | |
private Matcher matcher; | |
public InterceptionMatchRule not() { | |
return InterceptionMatchRule.valueOf(opposite); | |
} | |
public Matcher getMatcher() { | |
return Values.firstNonNull(matcher, (a, b) -> !not().getMatcher().apply(a, b)); | |
} | |
} | |
public static interface Replacer extends UnaryOperator<String> { | |
} | |
@RequiredArgsConstructor | |
@AllArgsConstructor | |
@Getter | |
public static class InterceptionRule { | |
@NonNull private InterceptionMatchRule type; | |
@NonNull private String pattern; | |
private @Setter Replacer replacer; | |
public boolean matches(@NonNull String self) { | |
Boolean bool = type.getMatcher().apply(self, pattern); | |
return Boolean.TRUE.equals(bool); | |
} | |
@SuppressWarnings("unused") | |
public String replace(@NonNull String self) { | |
return replace(self, this.replacer); | |
} | |
public String replace(@NonNull String self, @NonNull Replacer replacer) { | |
return Values.firstNonNull(replacer, this.replacer, s->s).apply(self); | |
} | |
@SuppressWarnings("unused") | |
public String matchAndReplace(@NonNull String self, Replacer replacer) { | |
if (matches(self)) { | |
return replace(self, replacer); | |
} | |
return self; | |
} | |
} | |
private List<InterceptionRule> rules = new ArrayList<>(); | |
public HttpRedirectInterceptor addRule(@NonNull InterceptionRule rule) { | |
rules.add(rule); | |
return this; | |
} | |
public void setRules(@NonNull List<InterceptionRule> rules) { | |
this.rules = rules; | |
} | |
public HttpRedirectInterceptor(HttpServletResponse response) { | |
super(response); | |
} | |
public HttpRedirectInterceptor(ServletResponse response) { | |
this((HttpServletResponse) response); | |
} | |
@Override | |
public void sendRedirect(String location) throws IOException { | |
InterceptionRule firstMatch = null; | |
InterceptionRule lastMatch = null; | |
for (InterceptionRule rule : rules) { | |
if (firstMatch != null) break; | |
if (rule.matches(location)) { | |
switch (replacementRule) { | |
case APPLY_FIRST: | |
firstMatch = rule; | |
location = rule.replace(location); | |
break; | |
case APPLY_ALL: | |
location = rule.replace(location); | |
break; | |
case APPLY_LAST: | |
lastMatch = rule; | |
break; | |
default: | |
break; | |
} | |
} | |
} | |
if (lastMatch != null) { | |
location = lastMatch.replace(location); | |
} | |
super.sendRedirect(location); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package kr.co.benew.iddle_admin.servlet.filter; | |
import java.io.IOException; | |
import java.util.ArrayList; | |
import java.util.List; | |
import javax.servlet.Filter; | |
import javax.servlet.FilterChain; | |
import javax.servlet.FilterConfig; | |
import javax.servlet.ServletException; | |
import javax.servlet.ServletRequest; | |
import javax.servlet.ServletResponse; | |
import javax.servlet.annotation.WebFilter; | |
import kr.co.benew.iddle_admin.servlet.HttpRedirectInterceptor; | |
import kr.co.benew.iddle_admin.servlet.HttpRedirectInterceptor.InterceptionMatchRule; | |
import kr.co.benew.iddle_admin.servlet.HttpRedirectInterceptor.InterceptionRule; | |
@WebFilter("/*") | |
public class RedirectRewriteFilter implements Filter { | |
List<InterceptionRule> rules; | |
@Override | |
public void init(FilterConfig filterConfig) throws ServletException { | |
rules = new ArrayList<>(); | |
rules.add(new InterceptionRule(InterceptionMatchRule.STARTS_WITH, "https://", s -> "http"+s.substring(5))); | |
} | |
@Override | |
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) | |
throws IOException, ServletException { | |
HttpRedirectInterceptor wrapped = new HttpRedirectInterceptor(response); | |
wrapped.setRules(rules); | |
chain.doFilter(request, wrapped); | |
} | |
@Override | |
public void destroy() { | |
rules.clear(); | |
rules = null; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Updated to fix rules not being applied