Skip to content

[Server MVC] XForwardedRequestHeadersFilter emits overlapping X-Forwarded-Prefix values for chained path filters #4237

Description

@garvit-joshi

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions