Browse Source

Removes predicate path exchange attr for forwards.

This moves the removal of GATEWAY_PREDICATE_PATH_CONTAINER_ATTR to ServerWebExchangeUtils.handle() which is now used in SpringCloudCircuitBreakerFilterFactory and ForwardRoutingFilter.

Fixes gh-2950
pull/3068/head
sgibb 1 year ago
parent
commit
d8d5bc071b
No known key found for this signature in database
GPG Key ID: 7788A47380690861
  1. 3
      spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/ForwardRoutingFilter.java
  2. 6
      spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/SpringCloudCircuitBreakerFilterFactory.java
  3. 15
      spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/support/ServerWebExchangeUtils.java
  4. 50
      spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/ForwardRoutingFilterStaticIntegrationTests.java
  5. 8
      spring-cloud-gateway-server/src/test/resources/application-forwardstatic.yml
  6. 21
      spring-cloud-gateway-server/src/test/resources/static/httpbin/docs.html

3
spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/ForwardRoutingFilter.java

@ -28,6 +28,7 @@ import org.springframework.web.reactive.DispatcherHandler; @@ -28,6 +28,7 @@ import org.springframework.web.reactive.DispatcherHandler;
import org.springframework.web.server.ServerWebExchange;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.handle;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.isAlreadyRouted;
public class ForwardRoutingFilter implements GlobalFilter, Ordered {
@ -71,7 +72,7 @@ public class ForwardRoutingFilter implements GlobalFilter, Ordered { @@ -71,7 +72,7 @@ public class ForwardRoutingFilter implements GlobalFilter, Ordered {
log.trace("Forwarding to URI: " + requestUrl);
}
return this.getDispatcherHandler().handle(exchange);
return handle(this.getDispatcherHandler(), exchange);
}
}

6
spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/SpringCloudCircuitBreakerFilterFactory.java

@ -43,9 +43,9 @@ import static java.util.Collections.singletonList; @@ -43,9 +43,9 @@ import static java.util.Collections.singletonList;
import static java.util.Optional.ofNullable;
import static org.springframework.cloud.gateway.support.GatewayToStringStyler.filterToStringCreator;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_PREDICATE_PATH_CONTAINER_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.containsEncodedParts;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.handle;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.reset;
/**
@ -107,7 +107,6 @@ public abstract class SpringCloudCircuitBreakerFilterFactory @@ -107,7 +107,6 @@ public abstract class SpringCloudCircuitBreakerFilterFactory
}
exchange.getResponse().setStatusCode(null);
reset(exchange);
// TODO: copied from RouteToRequestUrlFilter
URI uri = exchange.getRequest().getURI();
@ -116,14 +115,13 @@ public abstract class SpringCloudCircuitBreakerFilterFactory @@ -116,14 +115,13 @@ public abstract class SpringCloudCircuitBreakerFilterFactory
URI requestUrl = UriComponentsBuilder.fromUri(uri).host(null).port(null)
.uri(config.getFallbackUri()).scheme(null).build(encoded).toUri();
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, requestUrl);
exchange.getAttributes().remove(GATEWAY_PREDICATE_PATH_CONTAINER_ATTR);
addExceptionDetails(t, exchange);
// Reset the exchange
reset(exchange);
ServerHttpRequest request = exchange.getRequest().mutate().uri(requestUrl).build();
return getDispatcherHandler().handle(exchange.mutate().request(request).build());
return handle(getDispatcherHandler(), exchange.mutate().request(request).build());
}).onErrorResume(t -> handleErrorWithoutFallback(t, config.isResumeWithoutError()));
}

15
spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/support/ServerWebExchangeUtils.java

@ -46,6 +46,7 @@ import org.springframework.http.server.reactive.ServerHttpRequest; @@ -46,6 +46,7 @@ import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.util.Assert;
import org.springframework.web.reactive.DispatcherHandler;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.util.UriComponentsBuilder;
@ -401,4 +402,18 @@ public final class ServerWebExchangeUtils { @@ -401,4 +402,18 @@ public final class ServerWebExchangeUtils {
return decorator;
}
/**
* One place to handle forwarding using DispatcherHandler. Allows for common code to
* be reused.
* @param handler The DispatcherHandler.
* @param exchange The ServerWebExchange.
* @return value from handler.
*/
public static Mono<Void> handle(DispatcherHandler handler, ServerWebExchange exchange) {
// remove attributes that may disrupt the forwarded request
exchange.getAttributes().remove(GATEWAY_PREDICATE_PATH_CONTAINER_ATTR);
return handler.handle(exchange);
}
}

50
spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/ForwardRoutingFilterStaticIntegrationTests.java

@ -0,0 +1,50 @@ @@ -0,0 +1,50 @@
/*
* Copyright 2013-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.gateway.filter;
import org.junit.jupiter.api.Test;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.gateway.test.BaseWebClientTests;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.ActiveProfiles;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
@SpringBootTest(webEnvironment = RANDOM_PORT)
@ActiveProfiles("forwardstatic")
public class ForwardRoutingFilterStaticIntegrationTests extends BaseWebClientTests {
@Test
public void gatewayRequestsMeterFilterHasTags() {
testClient.get().uri("/mydocs").exchange().expectStatus().isOk().expectBody(String.class)
.consumeWith(result -> {
assertThat(result.getResponseBody()).contains("Docs 123");
});
}
@EnableAutoConfiguration
@SpringBootConfiguration
@Import(DefaultTestConfig.class)
public static class CustomConfig {
}
}

8
spring-cloud-gateway-server/src/test/resources/application-forwardstatic.yml

@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
spring:
cloud:
gateway:
routes:
- uri: forward:/docs.html
id: static_docs_route
predicates:
- Path=/mydocs

21
spring-cloud-gateway-server/src/test/resources/static/httpbin/docs.html

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
<!--
~ Copyright 2013-2023 the original author or authors.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ https://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<html>
<body>
<h1>Docs 123</h1>
</body>
</html>
Loading…
Cancel
Save