package dev.dinauer.oidcproxy.proxy; import dev.dinauer.oidcproxy.LogoutService; import dev.dinauer.oidcproxy.callback.CallbackService; import dev.dinauer.oidcproxy.proxy.exception.ProxyHttpException; import dev.dinauer.oidcproxy.proxy.exception.TokenNotFoundException; import dev.dinauer.oidcproxy.session.SessionCache; import dev.dinauer.oidcproxy.startup.PathConverter; import dev.dinauer.oidcproxy.startup.ProxyRoute; import dev.dinauer.oidcproxy.startup.RouteService; import io.quarkus.vertx.web.Route; import io.smallrye.common.annotation.Blocking; import io.vertx.core.http.Cookie; import io.vertx.core.http.HttpServerRequest; import io.vertx.core.http.HttpServerResponse; import io.vertx.ext.web.RoutingContext; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.ws.rs.core.Context; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.net.http.HttpResponse; import java.util.*; @ApplicationScoped public class ProxyResource { private static final Logger LOG = LoggerFactory.getLogger(ProxyResource.class); @Inject RouteService routeService; @Inject ForwardService forwardService; @Inject CallbackService callbackService; @Inject LogoutService logoutService; @Route(path = "/auth/callback", order = 0) @Blocking public void callback(@Context RoutingContext context) { callbackService.get(context.response(), context.request()); } @Route(path = "/auth/logout", order = 1) @Blocking public void logout(@Context HttpServerResponse response) { logoutService.logout(response); } @Route(path = "/*", order = 2) @Blocking public void proxy(@Context RoutingContext context) { HttpServerRequest request = context.request(); System.out.println(request.path()); List requestSegments = PathConverter.toSegments(request.path()); Optional routeOptional = routeService.match(requestSegments); if (routeOptional.isPresent()) { ProxyRoute route = routeOptional.get(); LOG.info("Matched route with target '{}'", route.target()); try { String targetURI = route.target() + PathConverter.toPath(requestSegments); HttpResponse response = forwardService.send(context, targetURI, route.strategy()); ResponseHandler.success(context, response); } catch (ProxyHttpException e) { LOG.error("Upstream returned error status {}.", e.getStatusCode(), e); ResponseHandler.error(context, e.getStatusCode()); } catch (TokenNotFoundException e) { LOG.error("Token not found.", e); ResponseHandler.error(context, 401); } catch (InterruptedException e) { LOG.error("Proxy request was interrupted, returning 503.", e); Thread.currentThread().interrupt(); ResponseHandler.error(context, 503); } catch (Exception e) { LOG.error("Error occurred on upstream.", e); ResponseHandler.error(context, 502); } } else { LOG.error("No route found for request path '{}'", context.request().path()); ResponseHandler.notFound(context); } } private List dropPrefix(List route, List request) { for (int i = 0; i < route.size(); i++) { request.removeFirst(); } return request; } }