Skip to content

Fix #3729: Support optional parameters in RewriteLocationResponseHeader filter #3886

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,14 @@ spring:
predicates:
- Path=/**
filters:
- RewriteLocationResponseHeader=AS_IN_REQUEST, Location, ,
# Minimal configuration - only stripVersion
- RewriteLocationResponseHeader=AS_IN_REQUEST
# Specify header name
- RewriteLocationResponseHeader=AS_IN_REQUEST, Location
# Specify custom host value
- RewriteLocationResponseHeader=AS_IN_REQUEST, Location, api.example.com
# Full configuration with protocols regex
- RewriteLocationResponseHeader=AS_IN_REQUEST, Location, api.example.com, https?|ftps?
----

.GatewaySampleApplication.java
Expand Down Expand Up @@ -62,3 +69,14 @@ The `protocolsRegex` parameter must be a valid regex `String`, against which the
If it is not matched, the filter does nothing.
The default is `http|https|ftp|ftps`.

== Multiple Configuration Options

The `RewriteLocationResponseHeader` filter supports multiple configuration formats for different use cases:

* **Minimal configuration**: `RewriteLocationResponseHeader=AS_IN_REQUEST` - Uses default values for all other parameters
* **With header name**: `RewriteLocationResponseHeader=AS_IN_REQUEST, Location` - Specifies custom header name (default is `Location`)
* **With host value**: `RewriteLocationResponseHeader=AS_IN_REQUEST, Location, api.example.com` - Uses custom host instead of request Host header
* **Full configuration**: `RewriteLocationResponseHeader=AS_IN_REQUEST, Location, api.example.com, https?|ftps?` - Specifies all parameters including protocols regex

All parameters after `stripVersionMode` are optional and use sensible defaults when not provided.

Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,35 @@ public static BiFunction<ServerRequest, ServerResponse, ServerResponse> rewriteL
});
}

public static BiFunction<ServerRequest, ServerResponse, ServerResponse> rewriteLocationResponseHeader(
String stripVersion) {
return RewriteLocationResponseHeaderFilterFunctions
.rewriteLocationResponseHeader(config -> config.setStripVersion(stripVersion));
}

public static BiFunction<ServerRequest, ServerResponse, ServerResponse> rewriteLocationResponseHeader(
String stripVersion, String locationHeaderName) {
return RewriteLocationResponseHeaderFilterFunctions.rewriteLocationResponseHeader(
config -> config.setStripVersion(stripVersion).setLocationHeaderName(locationHeaderName));
}

public static BiFunction<ServerRequest, ServerResponse, ServerResponse> rewriteLocationResponseHeader(
String stripVersion, String locationHeaderName, String hostValue) {
return RewriteLocationResponseHeaderFilterFunctions
.rewriteLocationResponseHeader(config -> config.setStripVersion(stripVersion)
.setLocationHeaderName(locationHeaderName)
.setHostValue(hostValue));
}

public static BiFunction<ServerRequest, ServerResponse, ServerResponse> rewriteLocationResponseHeader(
String stripVersion, String locationHeaderName, String hostValue, String protocolsRegex) {
return RewriteLocationResponseHeaderFilterFunctions
.rewriteLocationResponseHeader(config -> config.setStripVersion(stripVersion)
.setLocationHeaderName(locationHeaderName)
.setHostValue(hostValue)
.setProtocolsRegex(protocolsRegex));
}

public static BiFunction<ServerRequest, ServerResponse, ServerResponse> rewriteLocationResponseHeader(
Consumer<RewriteLocationResponseHeaderFilterFunctions.RewriteLocationResponseHeaderConfig> configConsumer) {
return RewriteLocationResponseHeaderFilterFunctions.rewriteLocationResponseHeader(configConsumer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,28 @@ static HandlerFilterFunction<ServerResponse, ServerResponse> requestSize(DataSiz
return ofRequestProcessor(BeforeFilterFunctions.requestSize(maxSize));
}

@Shortcut
static HandlerFilterFunction<ServerResponse, ServerResponse> rewriteLocationResponseHeader(String stripVersion) {
return ofResponseProcessor(RewriteLocationResponseHeaderFilterFunctions
.rewriteLocationResponseHeader(config -> config.setStripVersion(stripVersion)));
}

@Shortcut
static HandlerFilterFunction<ServerResponse, ServerResponse> rewriteLocationResponseHeader(String stripVersion,
String locationHeaderName) {
return ofResponseProcessor(RewriteLocationResponseHeaderFilterFunctions.rewriteLocationResponseHeader(
config -> config.setStripVersion(stripVersion).setLocationHeaderName(locationHeaderName)));
}

@Shortcut
static HandlerFilterFunction<ServerResponse, ServerResponse> rewriteLocationResponseHeader(String stripVersion,
String locationHeaderName, String hostValue) {
return ofResponseProcessor(RewriteLocationResponseHeaderFilterFunctions
.rewriteLocationResponseHeader(config -> config.setStripVersion(stripVersion)
.setLocationHeaderName(locationHeaderName)
.setHostValue(hostValue)));
}

@Shortcut
static HandlerFilterFunction<ServerResponse, ServerResponse> rewriteLocationResponseHeader(String stripVersion,
String locationHeaderName, String hostValue, String protocolsRegex) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -899,6 +899,42 @@ public void rewriteLocationResponseHeaderWorks() {
.valueEquals("Location", "https://test1.rewritelocationresponseheader.org/some/object/id");
}

@Test
public void rewriteLocationResponseHeaderWithMinimalArgsWorks() {
restClient.get()
.uri("/anything/rewritelocationresponseheader-minimal")
.header("Host", "test2.rewritelocationresponseheader.org")
.exchange()
.expectStatus()
.isOk()
.expectHeader()
.valueEquals("Location", "https://test2.rewritelocationresponseheader.org/some/object/id");
}

@Test
public void rewriteLocationResponseHeaderWithTwoArgsWorks() {
restClient.get()
.uri("/anything/rewritelocationresponseheader-twoargs")
.header("Host", "test3.rewritelocationresponseheader.org")
.exchange()
.expectStatus()
.isOk()
.expectHeader()
.valueEquals("Location", "https://test3.rewritelocationresponseheader.org/some/object/id");
}

@Test
public void rewriteLocationResponseHeaderWithThreeArgsWorks() {
restClient.get()
.uri("/anything/rewritelocationresponseheader-threeargs")
.header("Host", "test4.rewritelocationresponseheader.org")
.exchange()
.expectStatus()
.isOk()
.expectHeader()
.valueEquals("Location", "https://custom.host.example.com/some/object/id");
}

@Test
public void readBodyWorks() {
Event messageEvent = new Event("message", "bar");
Expand Down Expand Up @@ -1578,6 +1614,45 @@ public RouterFunction<ServerResponse> gatewayRouterFunctionsRewriteLocationRespo
// @formatter:on
}

@Bean
public RouterFunction<ServerResponse> gatewayRouterFunctionsRewriteLocationResponseHeaderMinimal() {
// @formatter:off
return route("testrewritelocationresponseheaderminimal")
.GET("/anything/rewritelocationresponseheader-minimal", host("**.rewritelocationresponseheader.org"), http())
.before(new HttpbinUriResolver())
// reverse order for "post" filters
.after(rewriteLocationResponseHeader("AS_IN_REQUEST"))
.after(addResponseHeader("Location", "https://backend.org:443/v1/some/object/id"))
.build();
// @formatter:on
}

@Bean
public RouterFunction<ServerResponse> gatewayRouterFunctionsRewriteLocationResponseHeaderTwoArgs() {
// @formatter:off
return route("testrewritelocationresponseheadertwoargs")
.GET("/anything/rewritelocationresponseheader-twoargs", host("**.rewritelocationresponseheader.org"), http())
.before(new HttpbinUriResolver())
// reverse order for "post" filters
.after(rewriteLocationResponseHeader("AS_IN_REQUEST", "Location"))
.after(addResponseHeader("Location", "https://backend.org:443/v1/some/object/id"))
.build();
// @formatter:on
}

@Bean
public RouterFunction<ServerResponse> gatewayRouterFunctionsRewriteLocationResponseHeaderThreeArgs() {
// @formatter:off
return route("testrewritelocationresponseheaderthreeargs")
.GET("/anything/rewritelocationresponseheader-threeargs", host("**.rewritelocationresponseheader.org"), http())
.before(new HttpbinUriResolver())
// reverse order for "post" filters
.after(rewriteLocationResponseHeader("AS_IN_REQUEST", "Location", "custom.host.example.com"))
.after(addResponseHeader("Location", "https://backend.org:443/v1/some/object/id"))
.build();
// @formatter:on
}

@Bean
public RouterFunction<ServerResponse> gatewayRouterFunctionsReadBodyPredicate() {
// @formatter:off
Expand Down