After seeing discussion put in #18949,

Let's see the following case

Spring boot BOM version 2.5.6 Spring cloud 2020.0.4

  • spring gateway with default locator configuration exposed on http://my-gateway.url
  • a spring boot application with a server.servlet.context-path set to my-local-context-path and seen by first application as app-ui in its discovery client

The second application uses thymeleaf @{/js/script.js} in the template returned by the handler of /some-mvc-controller

When accessing on http://my-gateway.url/app-ui/my-local-context-path/some-mvc-controller

  • spring cloud gateway calls app-ui application on /my-local-context-path/some-mvc-controller with X-Forwarded-Prefix set to /app-ui
  • ForwardedHeaderFilter replaces http servlet request context path to /app-ui, request uri to /app-ui/some-mvc-controller
  • Thymeleaf resolves js url to http://my-gateway.url/app-ui/js/script.js that ends in 404 error as the correct url should have been http://my-gateway.url/app-ui/my-local-context-path/js/script.js

Unless I missed something, I think that it is sad that, using all default behaviour of spring tools (but context-path) is not possible.

I would like to provide a way to let application choose between a policy of REPLACEMENT or PREPEND. If none, something like setting inner classes of ForwardedHeaderFilter as protected instead of private in order to let application easily implement its own policy.

Before going directly to a pull request, I prefer discussing whether you're ok with that and which would be the prefered solution

  • moving inner classes to protected without any other change
  • allowing to switch between replacement and prepend based on server.framework-forward-header-policy valued to REPLACEMENT by default

Comment From: antechrestos

A workaround is the following filter put just after ForwardedHeaderFilter in the chain

Comment From: rstoyanchev

From the previous threads, it sounds like the expected approach is to not expose the contextPath of the app behind the proxy to external clients. So the incoming URL is http://my-gateway.url/app-ui/some-mvc-controller and the gateway forwards to /my-local-context-path/some-mvc-controller with X-Forwarded-Prefix set to /app-ui.

Comment From: antechrestos

@rstoyanchev yes I understood the approach; yet I am facing a scenario not pleasant:

  • a legacy exposing both ui and api under the context path
  • connected to system not imperatively going through the reverse proxy, ie knowing ui/api address with local context path
  • a ui allowing users to access to proxified ui/swagger

Hence in this scenario, using the default locator configuration of spring cloud gateway , resolution of ressource url by proxified thymeleaf fails.

I have a solution based on a home made solution, yet I am not very pleased implementing framework bypass.I would rather

  • either override framework filter, by being allowed to extend inner classes (moving them from private to protected, or providing a pattern allowing to modify the context path replacement behaviour)
  • provide a configuration based way of switching behaviour

My point is that it is sad to have a restrictive behaviour on a border component.

Comment From: rstoyanchev

I get that you're in this scenario, and thanks for the extra detail, but the previous issue is more than 5 years old, so this doesn't seem to be very common. Taking a look at ForwardedPrefixExtractor and thinking about making that open for extension or configurable, I think the filter you've come up with seems a more straight-forward alternative to me.

Comment From: rstoyanchev

Closing for now but can re-open if there is more demand.