spring-cloud / spring-cloud/spring-cloud-gateway
[Server MVC] XForwardedRequestHeadersFilter emits overlapping X-Forwarded-Prefix values for chained path filters
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 4.9k
- Forks
- 3.5k
- Avg merge
- 20h 57m
- Merged PRs (30d)
- 8
Description
Describe the bug
When a Server MVC route applies more than one StripPrefix filter, Spring Cloud Gateway sends overlapping X-Forwarded-Prefix values to the downstream service.
For a request to /tenant/api/blue that is stripped to /blue, the gateway sends:
X-Forwarded-Prefix: /tenant/api,/api
A downstream Spring application with forwarded-header processing enabled combines those values and reconstructs /tenant/api/api as the context path instead of /tenant/api.
The client request in this example does not contain an X-Forwarded-Prefix header. Both values are produced by a single gateway while processing one route.
How to reproduce
Run the gateway on port 8080 with this route:
server:
port: 8080
spring:
cloud:
gateway:
server:
webmvc:
trusted-proxies: ".*"
routes:
- id: chained-strip-prefix
uri: http://localhost:8081
predicates:
- Path=/tenant/api/**
filters:
- StripPrefix=1
- StripPrefix=1
Run a downstream Spring WebFlux application on port 8081 with forwarded-header processing enabled:
server:
port: 8081
forward-headers-strategy: framework
Add an endpoint that returns the path information seen by the downstream application:
@RestController
class PathController {
@GetMapping("/blue")
Map<String, String> path(ServerHttpRequest request) {
RequestPath path = request.getPath();
return Map.of(
"contextPath", path.contextPath().value(),
"pathWithinApplication", path.pathWithinApplication().value());
}
}
Send a request through the gateway:
curl http://localhost:8080/tenant/api/blue
The configured filters change the request path as follows:
/tenant/api/blue
-> /api/blue
-> /blue
Actual behavior
The downstream request contains overlapping prefix values:
X-Forwarded-Prefix: /tenant/api,/api
The downstream application reports a duplicated context-path segment:
{
"contextPath": "/tenant/api/api",
"pathWithinApplication": "/blue"
}
Expected behavior
The gateway should send the external prefix removed from the final routed path once:
X-Forwarded-Prefix: /tenant/api
The downstream application should therefore report:
{
"contextPath": "/tenant/api",
"pathWithinApplication": "/blue"
}
Version
spring-cloud-gateway-server-webmvc: 5.0.3-SNAPSHOT
Related
This is the Server MVC counterpart of #4236, which reports the same behavior in the WebFlux server.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the Server MVC XForwardedRequestHeadersFilter and reproduce the chained StripPrefix route described in the issue. Done means the downstream request contains only X-Forwarded-Prefix: /tenant/api and reports contextPath /tenant/api with pathWithinApplication /blue.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, spring, spring-boot
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100