Created
October 26, 2024 08:37
-
-
Save peter-mghendi/973be6cf4b133db2b91dddab7f8b4719 to your computer and use it in GitHub Desktop.
Poor man's multitenancy.
This file contains hidden or 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 com.example.app.interceptors; | |
| import static jakarta.servlet.http.HttpServletResponse.SC_NOT_FOUND; | |
| import com.example.app.config.RouteProperties; | |
| import jakarta.servlet.ServletException; | |
| import jakarta.servlet.http.HttpServletRequest; | |
| import jakarta.servlet.http.HttpServletResponse; | |
| import jakarta.validation.constraints.NotNull; | |
| import java.io.IOException; | |
| import java.util.Map; | |
| import lombok.extern.slf4j.Slf4j; | |
| import org.springframework.beans.factory.annotation.Autowired; | |
| import org.springframework.stereotype.Component; | |
| import org.springframework.web.servlet.HandlerInterceptor; | |
| @Slf4j | |
| @Component | |
| public class HostBasedRouteInterceptor implements HandlerInterceptor { | |
| // RouteConfig is an object that contains a prefix and port | |
| // The code below assumes prefix == "/${subdomain}" | |
| private final Map<String, RouteProperties.RouteConfig> routes; | |
| @Autowired | |
| public HostBasedRouteInterceptor(RouteProperties routeProperties) { | |
| this.routes = routeProperties.getRoutes(); | |
| } | |
| @Override | |
| public boolean preHandle( | |
| HttpServletRequest request, | |
| @NotNull HttpServletResponse response, | |
| @NotNull Object handler) | |
| throws ServletException, IOException { | |
| var host = request.getHeader("Host"); | |
| var port = request.getLocalPort(); | |
| var path = request.getRequestURI().substring(1); | |
| var subdomain = subdomain(host); | |
| log.info("host %s, subdomain %s, port %s, path %s".formatted(host, subdomain, port, path)); | |
| // Do not rewrite unregistered routes | |
| var config = routes.get(subdomain); | |
| if (config != null && config.getPort() != port) { | |
| response.setStatus(SC_NOT_FOUND); | |
| return false; | |
| } | |
| // Rewrite api.example.com/api to api.example.com | |
| if (config != null && subdomain.equals("api")) { | |
| request.getRequestDispatcher("/%s/%s".formatted(subdomain, path)) | |
| .forward(request, response); | |
| return false; | |
| } | |
| return true; | |
| } | |
| private String subdomain(String host) { | |
| if (host != null && host.contains(".")) { | |
| return host.split("\\.")[0]; | |
| } | |
| return null; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment