Files
spring-cloud-gateway/docs/modules/ROOT/pages/spring-cloud-gateway-proxy-exchange.adoc
Joris Kuipers b435ce3575 Prevent Content-Length and Host headers from being copied by default (#3313)
Also remove the bogus spring.cloud.gateway.proxy.auto-forward setting from the tests.
Fixes gh-3154
2024-07-03 11:32:23 -04:00

81 lines
3.7 KiB
Plaintext

[[proxy-exchange-gateway]]
= Proxy Exchange Gateway with Spring MVC or Webflux
WARNING: The following describes an alternative style gateway. None of the Spring Cloud Gateway Server documentation applies to what follows.
== How to Include Spring Cloud Gateway Proxy Exchange
To include Spring Cloud Gateway Proxy Exchange in your project, use the artifact with a group ID of `org.springframework.cloud` and an artifact ID of `spring-cloud-gateway-mvc` for the MVC Proxy Exchange. For the WebFlux Proxy Exchange use artifact with a group ID of `org.springframework.cloud` and an artifact ID of `spring-cloud-gateway-webflux`.
See the https://projects.spring.io/spring-cloud/[Spring Cloud Project page] for details on setting up your build system with the current Spring Cloud Release Train.
== Using Proxy Exchange
Spring Cloud Gateway provides a utility object called `ProxyExchange`.
You can use it inside a regular Spring web handler as a method parameter.
It supports basic downstream HTTP exchanges through methods that mirror the HTTP verbs.
With MVC, it also supports forwarding to a local handler through the `forward()` method.
To use the `ProxyExchange`, include the right module in your classpath (either `spring-cloud-gateway-mvc` or `spring-cloud-gateway-webflux`).
The following MVC example proxies a request to `/test` downstream to a remote server:
[source,java]
----
@RestController
@SpringBootApplication
public class GatewaySampleApplication {
@Value("${remote.home}")
private URI home;
@GetMapping("/test")
public ResponseEntity<?> proxy(ProxyExchange<byte[]> proxy) throws Exception {
return proxy.uri(home.toString() + "/image/png").get();
}
}
----
The following example does the same thing with Webflux:
[source,java]
----
@RestController
@SpringBootApplication
public class GatewaySampleApplication {
@Value("${remote.home}")
private URI home;
@GetMapping("/test")
public Mono<ResponseEntity<?>> proxy(ProxyExchange<byte[]> proxy) throws Exception {
return proxy.uri(home.toString() + "/image/png").get();
}
}
----
Convenience methods on the `ProxyExchange` enable the handler method to discover and enhance the URI path of the incoming request.
For example, you might want to extract the trailing elements of a path to pass them downstream:
[source,java]
----
@GetMapping("/proxy/path/**")
public ResponseEntity<?> proxyPath(ProxyExchange<byte[]> proxy) throws Exception {
String path = proxy.path("/proxy/path/");
return proxy.uri(home.toString() + "/foos/" + path).get();
}
----
All the features of Spring MVC and Webflux are available to gateway handler methods.
As a result, you can inject request headers and query parameters, for instance, and you can constrain the incoming requests with declarations in the mapping annotation.
See the documentation for `@RequestMapping` in Spring MVC for more details of those features.
You can add headers to the downstream response by using the `header()` methods on `ProxyExchange`.
You can also manipulate response headers (and anything else you like in the response) by adding a mapper to the `get()` method (and other methods).
The mapper is a `Function` that takes the incoming `ResponseEntity` and converts it to an outgoing one.
First-class support is provided for "`sensitive`" headers (by default, `cookie` and `authorization`) and "`skipped`" headers (by default, `content-length` and `host`), which are not passed downstream, and for "`proxy`" (`x-forwarded-*`) headers. The idea behind "`skipped`" headers is that they may result in problems when copied over to the downstream request. For example: because of the way that the `ProxyExchange` calls the downstream endpoint the content's length might have changed or even use a `Transfer-Encoding: chunked` instead of a `Content-Length` header.