Skip to content

Instantly share code, notes, and snippets.

@peter-mghendi
Created October 26, 2024 08:37
Show Gist options
  • Select an option

  • Save peter-mghendi/973be6cf4b133db2b91dddab7f8b4719 to your computer and use it in GitHub Desktop.

Select an option

Save peter-mghendi/973be6cf4b133db2b91dddab7f8b4719 to your computer and use it in GitHub Desktop.
Poor man's multitenancy.
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