Merge branch '2.0.x' into 2.1.x
This commit is contained in:
@@ -40,7 +40,7 @@ function check_if_anything_to_sync() {
|
||||
|
||||
function retrieve_current_branch() {
|
||||
# Code getting the name of the current branch. For master we want to publish as we did until now
|
||||
# http://stackoverflow.com/questions/1593051/how-to-programmatically-determine-the-current-checked-out-git-branch
|
||||
# https://stackoverflow.com/questions/1593051/how-to-programmatically-determine-the-current-checked-out-git-branch
|
||||
# If there is a branch already passed will reuse it - otherwise will try to find it
|
||||
CURRENT_BRANCH=${BRANCH}
|
||||
if [[ -z "${CURRENT_BRANCH}" ]] ; then
|
||||
@@ -147,7 +147,7 @@ function copy_docs_for_current_version() {
|
||||
COMMIT_CHANGES="yes"
|
||||
else
|
||||
echo -e "Current branch is [${CURRENT_BRANCH}]"
|
||||
# http://stackoverflow.com/questions/29300806/a-bash-script-to-check-if-a-string-is-present-in-a-comma-separated-list-of-strin
|
||||
# https://stackoverflow.com/questions/29300806/a-bash-script-to-check-if-a-string-is-present-in-a-comma-separated-list-of-strin
|
||||
if [[ ",${WHITELISTED_BRANCHES_VALUE}," = *",${CURRENT_BRANCH},"* ]] ; then
|
||||
mkdir -p ${ROOT_FOLDER}/${CURRENT_BRANCH}
|
||||
echo -e "Branch [${CURRENT_BRANCH}] is whitelisted! Will copy the current docs to the [${CURRENT_BRANCH}] folder"
|
||||
|
||||
@@ -369,7 +369,7 @@ spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: add_request_header_route
|
||||
- id: add_response_header_route
|
||||
uri: http://example.org
|
||||
filters:
|
||||
- AddResponseHeader=X-Response-Foo, Bar
|
||||
@@ -377,6 +377,26 @@ spring:
|
||||
|
||||
This will add `X-Response-Foo:Bar` header to the downstream response's headers for all matching requests.
|
||||
|
||||
=== DedupeResponseHeader GatewayFilter Factory
|
||||
The DedupeResponseHeader GatewayFilter Factory takes a `name` parameter and an optional `strategy` parameter. `name` can contain a list of header names, space separated.
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: dedupe_response_header_route
|
||||
uri: http://example.org
|
||||
filters:
|
||||
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
|
||||
----
|
||||
|
||||
This will remove duplicate values of `Access-Control-Allow-Credentials` and `Access-Control-Allow-Origin` response headers in cases when both the gateway CORS logic and the downstream add them.
|
||||
|
||||
The DedupeResponseHeader filter also accepts an optional `strategy` parameter. The accepted values are `RETAIN_FIRST` (default), `RETAIN_LAST`, and `RETAIN_UNIQUE`.
|
||||
|
||||
[[hystrix]]
|
||||
=== Hystrix GatewayFilter Factory
|
||||
https://github.com/Netflix/Hystrix[Hystrix] is a library from Netflix that implements the https://martinfowler.com/bliki/CircuitBreaker.html[circuit breaker pattern].
|
||||
|
||||
2
mvnw
vendored
2
mvnw
vendored
@@ -8,7 +8,7 @@
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
# 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
|
||||
|
||||
2
mvnw.cmd
vendored
2
mvnw.cmd
vendored
@@ -7,7 +7,7 @@
|
||||
@REM "License"); you may not use this file except in compliance
|
||||
@REM with the License. You may obtain a copy of the License at
|
||||
@REM
|
||||
@REM http://www.apache.org/licenses/LICENSE-2.0
|
||||
@REM https://www.apache.org/licenses/LICENSE-2.0
|
||||
@REM
|
||||
@REM Unless required by applicable law or agreed to in writing,
|
||||
@REM software distributed under the License is distributed on an
|
||||
|
||||
4
pom.xml
4
pom.xml
@@ -32,7 +32,7 @@
|
||||
<licenses>
|
||||
<license>
|
||||
<name>Apache License, Version 2.0</name>
|
||||
<url>http://www.apache.org/licenses/LICENSE-2.0</url>
|
||||
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
|
||||
</license>
|
||||
</licenses>
|
||||
<developers>
|
||||
@@ -41,7 +41,7 @@
|
||||
<name>Spencer Gibb</name>
|
||||
<email>sgibb at pivotal.io</email>
|
||||
<organization>Pivotal Software, Inc.</organization>
|
||||
<organizationUrl>http://www.spring.io</organizationUrl>
|
||||
<organizationUrl>https://www.spring.io</organizationUrl>
|
||||
<roles>
|
||||
<role>Project lead</role>
|
||||
</roles>
|
||||
|
||||
@@ -56,6 +56,7 @@ import org.springframework.cloud.gateway.filter.WeightCalculatorWebFilter;
|
||||
import org.springframework.cloud.gateway.filter.factory.AddRequestHeaderGatewayFilterFactory;
|
||||
import org.springframework.cloud.gateway.filter.factory.AddRequestParameterGatewayFilterFactory;
|
||||
import org.springframework.cloud.gateway.filter.factory.AddResponseHeaderGatewayFilterFactory;
|
||||
import org.springframework.cloud.gateway.filter.factory.DedupeResponseHeaderGatewayFilterFactory;
|
||||
import org.springframework.cloud.gateway.filter.factory.FallbackHeadersGatewayFilterFactory;
|
||||
import org.springframework.cloud.gateway.filter.factory.GatewayFilterFactory;
|
||||
import org.springframework.cloud.gateway.filter.factory.HystrixGatewayFilterFactory;
|
||||
@@ -395,6 +396,11 @@ public class GatewayAutoConfiguration {
|
||||
return new ModifyRequestBodyGatewayFilterFactory(codecConfigurer);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DedupeResponseHeaderGatewayFilterFactory dedupeResponseHeaderGatewayFilterFactory() {
|
||||
return new DedupeResponseHeaderGatewayFilterFactory();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ModifyResponseBodyGatewayFilterFactory modifyResponseBodyGatewayFilterFactory(
|
||||
ServerCodecConfigurer codecConfigurer) {
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright 2013-2019 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
|
||||
*
|
||||
* http://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.factory;
|
||||
|
||||
import org.springframework.cloud.gateway.filter.GatewayFilter;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/*
|
||||
Use case: Both your legacy backend and your API gateway add CORS header values. So, your consumer ends up with
|
||||
Access-Control-Allow-Credentials: true, true
|
||||
Access-Control-Allow-Origin: https://musk.mars, https://musk.mars
|
||||
(The one from the gateway will be the first of the two.) To fix, add
|
||||
DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
|
||||
|
||||
Configuration parameters:
|
||||
- name
|
||||
String representing response header names, space separated. Required.
|
||||
- strategy
|
||||
RETAIN_FIRST - Default. Retain the first value only.
|
||||
RETAIN_LAST - Retain the last value only.
|
||||
RETAIN_UNIQUE - Retain all unique values in the order of their first encounter.
|
||||
|
||||
Example 1
|
||||
default-filters:
|
||||
- DedupeResponseHeader=Access-Control-Allow-Credentials
|
||||
|
||||
Response header Access-Control-Allow-Credentials: true, false
|
||||
Modified response header Access-Control-Allow-Credentials: true
|
||||
|
||||
Example 2
|
||||
default-filters:
|
||||
- DedupeResponseHeader=Access-Control-Allow-Credentials, RETAIN_LAST
|
||||
|
||||
Response header Access-Control-Allow-Credentials: true, false
|
||||
Modified response header Access-Control-Allow-Credentials: false
|
||||
|
||||
Example 3
|
||||
default-filters:
|
||||
- DedupeResponseHeader=Access-Control-Allow-Credentials, RETAIN_UNIQUE
|
||||
|
||||
Response header Access-Control-Allow-Credentials: true, true
|
||||
Modified response header Access-Control-Allow-Credentials: true
|
||||
*/
|
||||
|
||||
/**
|
||||
* @author Vitaliy Pavlyuk
|
||||
*/
|
||||
public class DedupeResponseHeaderGatewayFilterFactory
|
||||
extends AbstractGatewayFilterFactory<DedupeResponseHeaderGatewayFilterFactory.Config> {
|
||||
|
||||
private static final String STRATEGY_KEY = "strategy";
|
||||
|
||||
public DedupeResponseHeaderGatewayFilterFactory() {
|
||||
super(Config.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> shortcutFieldOrder() {
|
||||
return Arrays.asList(NAME_KEY, STRATEGY_KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GatewayFilter apply(Config config) {
|
||||
return (exchange, chain) -> chain.filter(exchange).then(Mono.fromRunnable(() -> {
|
||||
dedupe(exchange.getResponse().getHeaders(), config);
|
||||
}));
|
||||
}
|
||||
|
||||
public enum Strategy {
|
||||
/*
|
||||
Default: Retain the first value only.
|
||||
*/
|
||||
RETAIN_FIRST,
|
||||
|
||||
/*
|
||||
Retain the last value only.
|
||||
*/
|
||||
RETAIN_LAST,
|
||||
|
||||
/*
|
||||
Retain all unique values in the order of their first encounter.
|
||||
*/
|
||||
RETAIN_UNIQUE
|
||||
}
|
||||
|
||||
void dedupe(HttpHeaders headers, Config config) {
|
||||
String names = config.getName();
|
||||
Strategy strategy = config.getStrategy();
|
||||
if (headers == null || names == null || strategy == null) {
|
||||
return;
|
||||
}
|
||||
for (String name : names.split(" ")) {
|
||||
dedupe(headers, name.trim(), strategy);
|
||||
}
|
||||
}
|
||||
|
||||
private void dedupe(HttpHeaders headers, String name, Strategy strategy) {
|
||||
List<String> values = headers.get(name);
|
||||
if (values == null || values.size() <= 1) {
|
||||
return;
|
||||
}
|
||||
switch (strategy) {
|
||||
case RETAIN_FIRST:
|
||||
headers.set(name, values.get(0));
|
||||
break;
|
||||
case RETAIN_LAST:
|
||||
headers.set(name, values.get(values.size() - 1));
|
||||
break;
|
||||
case RETAIN_UNIQUE:
|
||||
headers.put(name, values.stream().distinct().collect(Collectors.toList()));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Config extends AbstractGatewayFilterFactory.NameConfig {
|
||||
private Strategy strategy = Strategy.RETAIN_FIRST;
|
||||
|
||||
public Strategy getStrategy() {
|
||||
return strategy;
|
||||
}
|
||||
|
||||
public Config setStrategy(Strategy strategy) {
|
||||
this.strategy = strategy;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -88,7 +88,7 @@ public class PathRoutePredicateFactory
|
||||
});
|
||||
}
|
||||
return exchange -> {
|
||||
PathContainer path = parsePath(exchange.getRequest().getURI().getPath());
|
||||
PathContainer path = parsePath(exchange.getRequest().getURI().getRawPath());
|
||||
|
||||
Optional<PathPattern> optionalPathPattern = pathPatterns.stream()
|
||||
.filter(pattern -> pattern.matches(path)).findFirst();
|
||||
|
||||
@@ -39,6 +39,8 @@ import org.springframework.cloud.gateway.filter.factory.AbstractChangeRequestUri
|
||||
import org.springframework.cloud.gateway.filter.factory.AddRequestHeaderGatewayFilterFactory;
|
||||
import org.springframework.cloud.gateway.filter.factory.AddRequestParameterGatewayFilterFactory;
|
||||
import org.springframework.cloud.gateway.filter.factory.AddResponseHeaderGatewayFilterFactory;
|
||||
import org.springframework.cloud.gateway.filter.factory.DedupeResponseHeaderGatewayFilterFactory;
|
||||
import org.springframework.cloud.gateway.filter.factory.DedupeResponseHeaderGatewayFilterFactory.Strategy;
|
||||
import org.springframework.cloud.gateway.filter.factory.FallbackHeadersGatewayFilterFactory;
|
||||
import org.springframework.cloud.gateway.filter.factory.HystrixGatewayFilterFactory;
|
||||
import org.springframework.cloud.gateway.filter.factory.PrefixPathGatewayFilterFactory;
|
||||
@@ -177,6 +179,17 @@ public class GatewayFilterSpec extends UriSpec {
|
||||
.apply(c -> c.setName(headerName).setValue(headerValue)));
|
||||
}
|
||||
|
||||
/**
|
||||
* A filter that removes duplication on a response header before it is returned to the client by the Gateway.
|
||||
* @param headerName the header name(s), space separated
|
||||
* @param strategy RETAIN_FIRST, RETAIN_LAST, or RETAIN_UNIQUE
|
||||
* @return a {@link GatewayFilterSpec} that can be used to apply additional filters
|
||||
*/
|
||||
public GatewayFilterSpec dedupeResponseHeader(String headerName, String strategy) {
|
||||
return filter(getBean(DedupeResponseHeaderGatewayFilterFactory.class)
|
||||
.apply(c -> c.setStrategy(Strategy.valueOf(strategy)).setName(headerName)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the route in a Hystrix command. Depends on @{code
|
||||
* org.springframework.cloud::spring-cloud-starter-netflix-hystrix} being on the
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2013-2018 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
|
||||
*
|
||||
* http://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.factory;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
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.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = RANDOM_PORT)
|
||||
@DirtiesContext
|
||||
public class DedupeResponseHeaderGatewayFilterFactoryTests extends BaseWebClientTests {
|
||||
|
||||
@Test
|
||||
public void dedupeResponseHeaderFilterWorks() {
|
||||
testClient.get()
|
||||
.uri("/headers")
|
||||
.header("Host", "www.deduperesponseheader.org")
|
||||
.exchange()
|
||||
.expectStatus().isOk()
|
||||
.expectHeader().valueEquals("Access-Control-Allow-Credentials", "true")
|
||||
.expectHeader().valueEquals("Access-Control-Allow-Origin", "https://musk.mars")
|
||||
.expectHeader().valueEquals("Scout-Cookie", "S'mores")
|
||||
.expectHeader().valueEquals("Next-Week-Lottery-Numbers", "4", "2", "42");
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration
|
||||
@SpringBootConfiguration
|
||||
@Import(DefaultTestConfig.class)
|
||||
public static class TestConfig { }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright 2013-2019 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
|
||||
*
|
||||
* http://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.factory;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class DedupeResponseHeaderGatewayFilterFactoryUnitTests {
|
||||
|
||||
private static final String NAME_1 = HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN;
|
||||
private static final String NAME_2 = HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS;
|
||||
|
||||
private HttpHeaders headers;
|
||||
private DedupeResponseHeaderGatewayFilterFactory.Config config;
|
||||
private DedupeResponseHeaderGatewayFilterFactory filter;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
headers = Mockito.mock(HttpHeaders.class);
|
||||
config = new DedupeResponseHeaderGatewayFilterFactory.Config();
|
||||
filter = new DedupeResponseHeaderGatewayFilterFactory();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dedupNullName() {
|
||||
filter.dedupe(headers, config);
|
||||
Mockito.verify(headers, Mockito.never()).get(Mockito.anyString());
|
||||
Mockito.verify(headers, Mockito.never()).set(Mockito.anyString(), Mockito.anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dedupNullValues() {
|
||||
config.setName(NAME_1);
|
||||
Mockito.when(headers.get(NAME_1)).thenReturn(null);
|
||||
filter.dedupe(headers, config);
|
||||
Mockito.verify(headers).get(NAME_1);
|
||||
Mockito.verify(headers, Mockito.never()).set(Mockito.anyString(), Mockito.anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dedupEmptyValues() {
|
||||
config.setName(NAME_1);
|
||||
Mockito.when(headers.get(NAME_1)).thenReturn(new ArrayList<>());
|
||||
filter.dedupe(headers, config);
|
||||
Mockito.verify(headers).get(NAME_1);
|
||||
Mockito.verify(headers, Mockito.never()).set(Mockito.anyString(), Mockito.anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dedupSingleValue() {
|
||||
config.setName(NAME_1);
|
||||
Mockito.when(headers.get(NAME_1)).thenReturn(Arrays.asList("1"));
|
||||
filter.dedupe(headers, config);
|
||||
Mockito.verify(headers).get(NAME_1);
|
||||
Mockito.verify(headers, Mockito.never()).set(Mockito.anyString(), Mockito.anyString());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void dedupMultipleValuesRetainFirst() {
|
||||
config.setName(NAME_1 + " " + NAME_2);
|
||||
Mockito.when(headers.get(NAME_1)).thenReturn(Arrays.asList("2", "3", "3", "4"));
|
||||
Mockito.when(headers.get(NAME_2)).thenReturn(Arrays.asList("true", "false"));
|
||||
filter.dedupe(headers, config);
|
||||
Mockito.verify(headers).get(NAME_1);
|
||||
Mockito.verify(headers).set(NAME_1, "2");
|
||||
Mockito.verify(headers).get(NAME_2);
|
||||
Mockito.verify(headers).set(NAME_2, "true");
|
||||
Mockito.verify(headers, Mockito.times(2)).set(Mockito.anyString(), Mockito.anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dedupMultipleValuesRetainLast() {
|
||||
config.setName(NAME_1);
|
||||
config.setStrategy(DedupeResponseHeaderGatewayFilterFactory.Strategy.RETAIN_LAST);
|
||||
Mockito.when(headers.get(NAME_1)).thenReturn(Arrays.asList("2", "3", "3", "4"));
|
||||
filter.dedupe(headers, config);
|
||||
Mockito.verify(headers).get(NAME_1);
|
||||
Mockito.verify(headers).set(NAME_1, "4");
|
||||
Mockito.verify(headers).set(Mockito.anyString(), Mockito.anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dedupMultipleValuesRetainUnique() {
|
||||
config.setName(NAME_1);
|
||||
config.setStrategy(DedupeResponseHeaderGatewayFilterFactory.Strategy.RETAIN_UNIQUE);
|
||||
Mockito.when(headers.get(NAME_1)).thenReturn(Arrays.asList("2", "3", "3", "4"));
|
||||
filter.dedupe(headers, config);
|
||||
Mockito.verify(headers).get(NAME_1);
|
||||
Mockito.verify(headers).put(Mockito.eq(NAME_1), Mockito.eq(Arrays.asList("2", "3", "4")));
|
||||
Mockito.verify(headers).put(Mockito.anyString(), Mockito.anyList());
|
||||
}
|
||||
}
|
||||
@@ -83,6 +83,16 @@ public class PathRoutePredicateFactoryTests extends BaseWebClientTests {
|
||||
expectPathRoute("/anything/multidsl3", "www.pathmultidsl.org", "path_multi_dsl");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pathRouteWorksWithPercent() {
|
||||
testClient.get().uri("/abc/123%/function")
|
||||
.header(HttpHeaders.HOST, "www.path.org")
|
||||
.exchange()
|
||||
.expectStatus().isOk()
|
||||
.expectHeader().valueEquals(HANDLER_MAPPER_HEADER, RoutePredicateHandlerMapping.class.getSimpleName())
|
||||
.expectHeader().valueEquals(ROUTE_ID_HEADER, "path_test");
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration
|
||||
@SpringBootConfiguration
|
||||
@Import(DefaultTestConfig.class)
|
||||
|
||||
@@ -69,6 +69,27 @@ spring:
|
||||
- AddResponseHeader=X-Request-Foo, Bar
|
||||
|
||||
# =====================================
|
||||
- id: dedupe_response_header_test
|
||||
uri: ${test.uri}
|
||||
predicates:
|
||||
- Host=**.deduperesponseheader.org
|
||||
- Path=/headers
|
||||
filters:
|
||||
- AddResponseHeader=Access-Control-Allow-Credentials, true
|
||||
- AddResponseHeader=Access-Control-Allow-Credentials, false
|
||||
- AddResponseHeader=Access-Control-Allow-Origin, https://musk.mars
|
||||
- AddResponseHeader=Access-Control-Allow-Origin, *
|
||||
- AddResponseHeader=Scout-Cookie, Thin Mints
|
||||
- AddResponseHeader=Scout-Cookie, S'mores
|
||||
- AddResponseHeader=Next-Week-Lottery-Numbers, 4
|
||||
- AddResponseHeader=Next-Week-Lottery-Numbers, 2
|
||||
- AddResponseHeader=Next-Week-Lottery-Numbers, 2
|
||||
- AddResponseHeader=Next-Week-Lottery-Numbers, 42
|
||||
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin, RETAIN_FIRST
|
||||
- DedupeResponseHeader=Scout-Cookie, RETAIN_LAST
|
||||
- DedupeResponseHeader=Next-Week-Lottery-Numbers, RETAIN_UNIQUE
|
||||
|
||||
# =====================================
|
||||
- id: rewrite_response_header_test
|
||||
uri: ${test.uri}
|
||||
predicates:
|
||||
|
||||
Reference in New Issue
Block a user