jhipster / generator-jhipster

JHipster is a development platform to quickly generate, develop, & deploy modern web applications & microservice architectures.
https://www.jhipster.tech
Apache License 2.0
21.54k stars 4.02k forks source link

Gateway and context-path not working #21534

Closed mheidt closed 9 months ago

mheidt commented 1 year ago
Overview of the issue

I generated a gateway project which was starting without any issues. When I tried to change the context-path by setting server.servlet.context-path, it is shown in the output of logApplicationStartup(). But when I try to call a Rest call, it only works, if I don't apply the context-path.

Suggest a Fix

I made it work by a fix in SpaWebFilter:

public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        String contextPath = exchange.getApplicationContext().getEnvironment()
               .getProperty("server.servlet.context-path");
        if (
            contextPath!=null?!path.startsWith(contextPath):true &&
            !path.startsWith("/api") &&
            !path.startsWith("/management") &&
            !path.startsWith("/services") &&
            !path.startsWith("/v3/api-docs") &&
            path.matches("[^\\\\.]*")
        ) {
            return chain.filter(exchange.mutate().request(exchange.getRequest().mutate().path("/index.html").build()).build());
        }
        if (contextPath != null && exchange.getRequest().getURI().getPath().startsWith(contextPath)) {
            return chain.filter(
                exchange.mutate()
                    .request(exchange.getRequest().mutate().contextPath(contextPath).build())
                    .build());
        }
        return chain.filter(exchange);
    }

I don't know how spring will evolve in the future, but generally I would suggest that for a webflux application, spring.webflux.base-path is used instead of server.servlet.context-path

JHipster Version(s)

7.9.3

mheidt commented 1 year ago

What I mentioned is not enough. The cloud-gateway mechanism wouldn't work out of the box with context-path either.

If you use a context-path you probably get an error like Invalid contextPath '/your-context-path': must match the start of requestPath: '/api/bla'

Thanks to https://github.com/spring-cloud/spring-cloud-gateway/issues/1935 I finally found the solution. You need this one:

@Component
public class ContextPathRewritePathGatewayFilterFactory extends RewritePathGatewayFilterFactory {

    @Override
    public GatewayFilter apply(Config config) {
        String replacement = config.getReplacement().replace("$\\", "$");
        return new GatewayFilter() {
            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                ServerHttpRequest req = exchange.getRequest();

                addOriginalRequestUrl(exchange, req.getURI());
                String path = req.getURI().getRawPath();

                String newPath = path.replaceAll(config.getRegexp(), replacement);
                ServerHttpRequest request = req.mutate().path(newPath).contextPath("/").build();

                exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, request.getURI());

                return chain.filter(exchange.mutate().request(request).build());
            }
        };
    }

}

And need to change RewritePath in application.yml to: filters:

TheRealHaui commented 1 year ago

Thank you for your investigation but this did not solve the problem.

Among some changes in Javascript/Typescript files to overtake the servlet context setting we had to remove the preceding servlet context path from the Swagger configuration in the application.yaml file as can be seen in the attached screenshot.

image

github-actions[bot] commented 9 months ago

This issue is stale because it has been open for too long without any activity. Due to the moving nature of jhipster generated application, bugs can become invalid. If this issue still applies please comment otherwise it will be closed in 7 days