Add docs
This commit is contained in:
@@ -534,6 +534,53 @@ spring:
|
||||
----
|
||||
====
|
||||
|
||||
=== The `AddRequestHeadersIfNotPresent` `GatewayFilter` Factory
|
||||
|
||||
The `AddRequestHeadersIfNotPresent` `GatewayFilter` factory takes a collection of `name` and `value` pairs separated by colon.
|
||||
The following example configures an `AddRequestHeadersIfNotPresent` `GatewayFilter`:
|
||||
|
||||
.application.yml
|
||||
====
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: add_request_headers_route
|
||||
uri: https://example.org
|
||||
filters:
|
||||
- AddRequestHeadersIfNotPresent=X-Request-Color-1:blue,X-Request-Color-2:green
|
||||
----
|
||||
====
|
||||
|
||||
This listing adds 2 headers `X-Request-Color-1:blue` and `X-Request-Color-2:green` to the downstream request's headers for all matching requests.
|
||||
This is similar to how `AddRequestHeader` works, but unlike `AddRequestHeader` it will do it only if the header is not already there.
|
||||
Otherwise, the original value in the client request is sent.
|
||||
|
||||
Additionally, to set a multi-valued header, use the header name multiple times like `AddRequestHeadersIfNotPresent=X-Request-Color-1:blue,X-Request-Color-1:green`.
|
||||
|
||||
`AddRequestHeadersIfNotPresent` also supports URI variables used to match a path or host.
|
||||
URI variables may be used in the value and are expanded at runtime.
|
||||
The following example configures an `AddRequestHeadersIfNotPresent` `GatewayFilter` that uses a variable:
|
||||
|
||||
.application.yml
|
||||
====
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: add_request_header_route
|
||||
uri: https://example.org
|
||||
predicates:
|
||||
- Path=/red/{segment}
|
||||
filters:
|
||||
- AddRequestHeadersIfNotPresent=X-Request-Red:Blue-{segment}
|
||||
----
|
||||
====
|
||||
|
||||
=== The `AddRequestParameter` `GatewayFilter` Factory
|
||||
|
||||
The `AddRequestParameter` `GatewayFilter` Factory takes a `name` and `value` parameter.
|
||||
|
||||
@@ -7,6 +7,8 @@ import org.springframework.util.StringUtils;
|
||||
|
||||
public class KeyValueConverter implements Converter<String, KeyValue> {
|
||||
|
||||
private static final String INVALID_CONFIGURATION_MESSAGE = "Invalid configuration, expected format is: 'key:value'";
|
||||
|
||||
@Override
|
||||
public KeyValue convert(String source) throws IllegalArgumentException {
|
||||
try {
|
||||
@@ -14,10 +16,10 @@ public class KeyValueConverter implements Converter<String, KeyValue> {
|
||||
if (source.contains(":") && StringUtils.hasText(split[0])) {
|
||||
return new KeyValue(split[0], split.length == 1 ? "" : split[1]);
|
||||
}
|
||||
throw new IllegalArgumentException("Invalid configuration, expected format is: 'key:value'");
|
||||
throw new IllegalArgumentException(INVALID_CONFIGURATION_MESSAGE);
|
||||
}
|
||||
catch (ArrayIndexOutOfBoundsException e) {
|
||||
throw new IllegalArgumentException("Invalid configuration, expected format is: 'key:value'");
|
||||
throw new IllegalArgumentException(INVALID_CONFIGURATION_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,127 +1,127 @@
|
||||
///*
|
||||
// * 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.route.builder
|
||||
//
|
||||
//import org.junit.Test
|
||||
//import org.junit.runner.RunWith
|
||||
//import org.springframework.beans.factory.annotation.Autowired
|
||||
//import org.springframework.boot.autoconfigure.EnableAutoConfiguration
|
||||
//import org.springframework.boot.test.context.SpringBootTest
|
||||
//import org.springframework.cloud.gateway.support.ServerWebExchangeUtils
|
||||
//import org.springframework.context.annotation.Configuration
|
||||
//import org.springframework.mock.http.server.reactive.MockServerHttpRequest
|
||||
//import org.springframework.mock.web.server.MockServerWebExchange
|
||||
//import org.springframework.test.context.junit4.SpringRunner
|
||||
//import org.springframework.web.server.ServerWebExchange
|
||||
//import reactor.core.publisher.toMono
|
||||
//import reactor.test.StepVerifier
|
||||
//import java.net.URI
|
||||
//
|
||||
//@RunWith(SpringRunner::class)
|
||||
//@SpringBootTest(classes = arrayOf(Config::class))
|
||||
//class RouteDslTests {
|
||||
//
|
||||
// @Autowired
|
||||
// lateinit var builder: RouteLocatorBuilder
|
||||
//
|
||||
// @Test
|
||||
// fun sampleRouteDsl() {
|
||||
// val routeLocator = builder.routes {
|
||||
// route(id = "test") {
|
||||
// host("**.abc.org") and path("/image/png")
|
||||
// filters {
|
||||
// addResponseHeader("X-TestHeader", "foobar")
|
||||
// }
|
||||
// uri("http://httpbin.org:80")
|
||||
// }
|
||||
//
|
||||
// route(id = "test2") {
|
||||
// path("/image/webp") or path("/image/anotherone")
|
||||
// filters {
|
||||
// addResponseHeader("X-AnotherHeader", "baz")
|
||||
// addResponseHeader("X-AnotherHeader-2", "baz-2")
|
||||
// }
|
||||
// uri("https://httpbin.org:443")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// StepVerifier
|
||||
// .create(routeLocator.routes)
|
||||
// .expectNextMatches({
|
||||
// it.id == "test" && it.filters.size == 1 && it.uri == URI.create("http://httpbin.org:80")
|
||||
// })
|
||||
// .expectNextMatches({
|
||||
// it.id == "test2" && it.filters.size == 2 && it.uri == URI.create("https://httpbin.org:443")
|
||||
// })
|
||||
// .expectComplete()
|
||||
// .verify()
|
||||
//
|
||||
// val sampleExchange: ServerWebExchange = MockServerWebExchange.from(MockServerHttpRequest.get("/image/webp")
|
||||
// .header("Host", "test.abc.org").build())
|
||||
//
|
||||
// val filteredRoutes = routeLocator.routes.filter({
|
||||
// sampleExchange.attributes.put(ServerWebExchangeUtils.GATEWAY_PREDICATE_ROUTE_ATTR, it.id)
|
||||
// it.predicate.apply(sampleExchange).toMono().block()
|
||||
// })
|
||||
//
|
||||
// StepVerifier.create(filteredRoutes)
|
||||
// .expectNextMatches({
|
||||
// it.id == "test2" && it.filters.size == 2 && it.uri == URI.create("https://httpbin.org:443")
|
||||
// })
|
||||
// .expectComplete()
|
||||
// .verify()
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// fun dslWithFunctionParameters() {
|
||||
// val routerLocator = builder.routes {
|
||||
// route(id = "test1", order = 10, uri = "http://httpbin.org") {
|
||||
// host("**.abc.org")
|
||||
// }
|
||||
// route(id = "test2", order = 10, uri = "http://someurl") {
|
||||
// host("**.abc.org")
|
||||
// uri("http://override-url")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// StepVerifier.create(routerLocator.routes)
|
||||
// .expectNextMatches({
|
||||
// it.id == "test1" &&
|
||||
// it.uri == URI.create("http://httpbin.org:80") &&
|
||||
// it.order == 10 &&
|
||||
// it.predicate.apply(MockServerWebExchange
|
||||
// .from(MockServerHttpRequest
|
||||
// .get("/someuri").header("Host", "test.abc.org")))
|
||||
// .toMono().block()
|
||||
// })
|
||||
// .expectNextMatches({
|
||||
// it.id == "test2" &&
|
||||
// it.uri == URI.create("http://override-url:80") &&
|
||||
// it.order == 10 &&
|
||||
// it.predicate.apply(MockServerWebExchange
|
||||
// .from(MockServerHttpRequest
|
||||
// .get("/someuri").header("Host", "test.abc.org")))
|
||||
// .toMono().block()
|
||||
// })
|
||||
// .expectComplete()
|
||||
// .verify()
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//@Configuration(proxyBeanMethods = false)
|
||||
//@EnableAutoConfiguration
|
||||
//open class Config {}
|
||||
/*
|
||||
* 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.route.builder
|
||||
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
|
||||
import org.springframework.boot.test.context.SpringBootTest
|
||||
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.mock.http.server.reactive.MockServerHttpRequest
|
||||
import org.springframework.mock.web.server.MockServerWebExchange
|
||||
import org.springframework.test.context.junit4.SpringRunner
|
||||
import org.springframework.web.server.ServerWebExchange
|
||||
import reactor.core.publisher.toMono
|
||||
import reactor.test.StepVerifier
|
||||
import java.net.URI
|
||||
|
||||
@RunWith(SpringRunner::class)
|
||||
@SpringBootTest(classes = arrayOf(Config::class))
|
||||
class RouteDslTests {
|
||||
|
||||
@Autowired
|
||||
lateinit var builder: RouteLocatorBuilder
|
||||
|
||||
@Test
|
||||
fun sampleRouteDsl() {
|
||||
val routeLocator = builder.routes {
|
||||
route(id = "test") {
|
||||
host("**.abc.org") and path("/image/png")
|
||||
filters {
|
||||
addResponseHeader("X-TestHeader", "foobar")
|
||||
}
|
||||
uri("http://httpbin.org:80")
|
||||
}
|
||||
|
||||
route(id = "test2") {
|
||||
path("/image/webp") or path("/image/anotherone")
|
||||
filters {
|
||||
addResponseHeader("X-AnotherHeader", "baz")
|
||||
addResponseHeader("X-AnotherHeader-2", "baz-2")
|
||||
}
|
||||
uri("https://httpbin.org:443")
|
||||
}
|
||||
}
|
||||
|
||||
StepVerifier
|
||||
.create(routeLocator.routes)
|
||||
.expectNextMatches({
|
||||
it.id == "test" && it.filters.size == 1 && it.uri == URI.create("http://httpbin.org:80")
|
||||
})
|
||||
.expectNextMatches({
|
||||
it.id == "test2" && it.filters.size == 2 && it.uri == URI.create("https://httpbin.org:443")
|
||||
})
|
||||
.expectComplete()
|
||||
.verify()
|
||||
|
||||
val sampleExchange: ServerWebExchange = MockServerWebExchange.from(MockServerHttpRequest.get("/image/webp")
|
||||
.header("Host", "test.abc.org").build())
|
||||
|
||||
val filteredRoutes = routeLocator.routes.filter({
|
||||
sampleExchange.attributes.put(ServerWebExchangeUtils.GATEWAY_PREDICATE_ROUTE_ATTR, it.id)
|
||||
it.predicate.apply(sampleExchange).toMono().block()
|
||||
})
|
||||
|
||||
StepVerifier.create(filteredRoutes)
|
||||
.expectNextMatches({
|
||||
it.id == "test2" && it.filters.size == 2 && it.uri == URI.create("https://httpbin.org:443")
|
||||
})
|
||||
.expectComplete()
|
||||
.verify()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun dslWithFunctionParameters() {
|
||||
val routerLocator = builder.routes {
|
||||
route(id = "test1", order = 10, uri = "http://httpbin.org") {
|
||||
host("**.abc.org")
|
||||
}
|
||||
route(id = "test2", order = 10, uri = "http://someurl") {
|
||||
host("**.abc.org")
|
||||
uri("http://override-url")
|
||||
}
|
||||
}
|
||||
|
||||
StepVerifier.create(routerLocator.routes)
|
||||
.expectNextMatches({
|
||||
it.id == "test1" &&
|
||||
it.uri == URI.create("http://httpbin.org:80") &&
|
||||
it.order == 10 &&
|
||||
it.predicate.apply(MockServerWebExchange
|
||||
.from(MockServerHttpRequest
|
||||
.get("/someuri").header("Host", "test.abc.org")))
|
||||
.toMono().block()
|
||||
})
|
||||
.expectNextMatches({
|
||||
it.id == "test2" &&
|
||||
it.uri == URI.create("http://override-url:80") &&
|
||||
it.order == 10 &&
|
||||
it.predicate.apply(MockServerWebExchange
|
||||
.from(MockServerHttpRequest
|
||||
.get("/someuri").header("Host", "test.abc.org")))
|
||||
.toMono().block()
|
||||
})
|
||||
.expectComplete()
|
||||
.verify()
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableAutoConfiguration
|
||||
open class Config {}
|
||||
Reference in New Issue
Block a user