You can use the ServerHttpRequest as a method parameter to get the uri:
@RestController public class GreetingController { @GetMapping("/greeting") public Mono<Greeting> getGreeting(ServerHttpRequest serverHttpRequest) { return Mono.just(new Greeting("greeting", serverHttpRequest.getURI().toString())); } }
Preferably linkToCurrentResource should understand X-Forwarded-??? headers if running behind a load balancer.
Then you can expose a ForwardedHeaderTransformer @Bean.
From its documentation:
Extract values from "Forwarded" and "X-Forwarded-*" headers to override the request URI (i.e. HttpRequest.getURI()) so it reflects the client-originated protocol and address.
@Configuration open class MvcConfig { @Bean open fun forwardedHeaderTransformer() = ForwardedHeaderTransformer() }
Here are some tests:
@ExtendWith(SpringExtension::class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, properties = ["server.port=4333"]) class GreetingController2Test { @Autowired private lateinit var restTemplate: TestRestTemplate @Test fun `should return uri`() { val responseEntity = restTemplate.getForEntity("/greeting", Greeting::class.java) val greeting = responseEntity.body!! assertEquals("http://localhost:4333/greeting", greeting.uri) } @Test fun `should return uri composed from forwarded-??? headers`() { val headers = HttpHeaders() headers["X-Forwarded-Host"] = "external-uri.com" headers["X-Forwarded-Proto"] = "https" headers["X-Forwarded-Prefix"] = "/prefix" val httpEntity = HttpEntity(null, headers) val responseEntity = restTemplate.exchange("/greeting", HttpMethod.GET, httpEntity, Greeting::class.java) val greeting = responseEntity.body!! assertEquals("https://external-uri.com/prefix/greeting", greeting.uri) } }
And the Greeting.kt:
data class Greeting( val g: String? = null, val uri: String? = null )