Merge branch '4.0.x'

This commit is contained in:
sgibb
2023-06-19 14:12:40 -04:00
7 changed files with 100 additions and 7 deletions

View File

@@ -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 {
log.trace("Forwarding to URI: " + requestUrl);
}
return this.getDispatcherHandler().handle(exchange);
return handle(this.getDispatcherHandler(), exchange);
}
}

View File

@@ -45,9 +45,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;
/**
@@ -109,7 +109,6 @@ public abstract class SpringCloudCircuitBreakerFilterFactory
}
exchange.getResponse().setStatusCode(null);
reset(exchange);
// TODO: copied from RouteToRequestUrlFilter
URI uri = exchange.getRequest().getURI();
@@ -124,14 +123,13 @@ public abstract class SpringCloudCircuitBreakerFilterFactory
.uri(URI.create(fullFallbackUri)).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()));
}

View File

@@ -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;
@@ -411,4 +412,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);
}
}

View File

@@ -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 {
}
}

View File

@@ -31,8 +31,8 @@ public class RouteConstructionIntegrationTests {
@Test
public void routesWithVerificationShouldFail() {
assertThatThrownBy(() -> new SpringApplicationBuilder(TestConfig.class).profiles("verification-route").run())
.hasMessageContaining("Stop right now!");
assertThatThrownBy(() -> new SpringApplicationBuilder(TestConfig.class).profiles("verification-route")
.run("--server.port=0")).hasMessageContaining("Stop right now!");
}
@EnableAutoConfiguration

View File

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

View File

@@ -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>