文章26 | 阅读 10671 | 点赞0
本文主要分享 GatewayFilterFactory 的实现类。
GatewayFilterFactory 实现类较多,根据用途整理如下脑图 :
下面我们开始逐块解析源码实现。
本小节分享 Header 相关的 GatewayFilterFactory 实现类。
spring:
cloud:
gateway:
routes:
# =====================================
- id: add_request_header_route
uri: http://example.org
filters:
- AddRequestHeader=X-Request-Foo, Bar
1: public class AddRequestHeaderGatewayFilterFactory implements GatewayFilterFactory {
2:
3: @Override
4: public List<String> argNames() {
5: return Arrays.asList(NAME_KEY, VALUE_KEY);
6: }
7:
8: @Override
9: public GatewayFilter apply(Tuple args) {
10: String name = args.getString(NAME_KEY);
11: String value = args.getString(VALUE_KEY);
12:
13: return (exchange, chain) -> { // GatewayFilter
14: // 创建新的 ServerHttpRequest
15: ServerHttpRequest request = exchange.getRequest().mutate()
16: .header(name, value)
17: .build();
18:
19: // 创建新的 ServerWebExchange ,提交过滤器链继续过滤
20: return chain.filter(exchange.mutate().request(request).build());
21: };
22: }
23: }
name
/ value
。类似 AddRequestHeaderGatewayFilterFactory ,不重复分享,点击 《Spring Cloud Gateway —— RemoveRequestHeader GatewayFilter Factory》 查看官方文档。
类似 AddRequestHeaderGatewayFilterFactory ,不重复分享,点击 《Spring Cloud Gateway —— AddResponseHeader GatewayFilter Factory》 查看官方文档。
类似 AddRequestHeaderGatewayFilterFactory ,不重复分享,点击 《Spring Cloud Gateway —— RemoveResponseHeader GatewayFilter Factory》 查看官方文档。
类似 AddRequestHeaderGatewayFilterFactory ,不重复分享,点击 《Spring Cloud Gateway —— SetStatus GatewayFilter Factory》 查看官方文档。
[ "Connection", "Keep-Alive", "Proxy-Authenticate", "Proxy-Authorization", "TE", "Trailer", "Transfer-Encoding", "Upgrade" ]
( 参考自 :https://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-14#section-7.1.3 ) ,可以通过 spring.cloud.gateway.filter.remove-non-proxy-headers
配置。1: @ConfigurationProperties("spring.cloud.gateway.filter.remove-non-proxy-headers")
2: public class RemoveNonProxyHeadersGatewayFilterFactory implements GatewayFilterFactory {
3:
4: /**
5: * 默认
6: */
7: public static final String[] DEFAULT_HEADERS_TO_REMOVE = new String[] {"Connection", "Keep-Alive",
8: "Proxy-Authenticate", "Proxy-Authorization", "TE", "Trailer", "Transfer-Encoding", "Upgrade"};
9:
10: private List<String> headers = Arrays.asList(DEFAULT_HEADERS_TO_REMOVE);
11:
12: public List<String> getHeaders() {
13: return headers;
14: }
15:
16: public void setHeaders(List<String> headers) {
17: this.headers = headers;
18: }
19:
20: @Override
21: public GatewayFilter apply(Tuple args) {
22: //TODO: support filter args
23:
24: return (exchange, chain) -> {
25: // 创建新的 ServerHttpRequest
26: ServerHttpRequest request = exchange.getRequest().mutate()
27: .headers(httpHeaders -> {
28: for (String header : this.headers) {
29: httpHeaders.remove(header); // 移除
30: }
31: })
32: .build();
33:
34: // 创建新的 ServerWebExchange ,提交过滤器链继续过滤
35: return chain.filter(exchange.mutate().request(request).build());
36: };
37: }
38:
用途 :添加响应 Secure 相关的 Header 。默认值在 org.springframework.cloud.gateway.filter.factory.SecureHeadersProperties
,可以通过 spring.cloud.gateway.filter.secure-headers
配置。
推荐文章 :
代码 :
1: public class SecureHeadersGatewayFilterFactory implements GatewayFilterFactory {
2:
3: public static final String X_XSS_PROTECTION_HEADER = "X-Xss-Protection";
4: public static final String STRICT_TRANSPORT_SECURITY_HEADER = "Strict-Transport-Security";
5: public static final String X_FRAME_OPTIONS_HEADER = "X-Frame-Options";
6: public static final String X_CONTENT_TYPE_OPTIONS_HEADER = "X-Content-Type-Options";
7: public static final String REFERRER_POLICY_HEADER = "Referrer-Policy";
8: public static final String CONTENT_SECURITY_POLICY_HEADER = "Content-Security-Policy";
9: public static final String X_DOWNLOAD_OPTIONS_HEADER = "X-Download-Options";
10: public static final String X_PERMITTED_CROSS_DOMAIN_POLICIES_HEADER = "X-Permitted-Cross-Domain-Policies";
11:
12: private final SecureHeadersProperties properties;
13:
14: public SecureHeadersGatewayFilterFactory(SecureHeadersProperties properties) {
15: this.properties = properties;
16: }
17:
18: @Override
19: public GatewayFilter apply(Tuple args) {
20: //TODO: allow args to override properties
21:
22: return (exchange, chain) -> {
23: HttpHeaders headers = exchange.getResponse().getHeaders();
24:
25: //TODO: allow header to be disabled
26: headers.add(X_XSS_PROTECTION_HEADER, properties.getXssProtectionHeader());
27: headers.add(STRICT_TRANSPORT_SECURITY_HEADER, properties.getStrictTransportSecurity());
28: headers.add(X_FRAME_OPTIONS_HEADER, properties.getFrameOptions());
29: headers.add(X_CONTENT_TYPE_OPTIONS_HEADER, properties.getContentTypeOptions());
30: headers.add(REFERRER_POLICY_HEADER, properties.getReferrerPolicy());
31: headers.add(CONTENT_SECURITY_POLICY_HEADER, properties.getContentSecurityPolicy());
32: headers.add(X_DOWNLOAD_OPTIONS_HEADER, properties.getDownloadOptions());
33: headers.add(X_PERMITTED_CROSS_DOMAIN_POLICIES_HEADER, properties.getPermittedCrossDomainPolicies());
34:
35: return chain.filter(exchange);
36: };
37: }
38: }
本小节分享 Parameter 相关的 GatewayFilterFactory 实现类。
类似 AddRequestHeaderGatewayFilterFactory ,不重复分享,点击 《Spring Cloud Gateway —— AddRequestParameter GatewayFilter Factory》 查看官方文档。
本小节分享 Path 相关的 GatewayFilterFactory 实现类。
regexp
,使用配置的 replacement
重写请求 Path 。从功能目的上类似 《Module ngx_http_rewrite_module》 。spring:
cloud:
gateway:
routes:
# =====================================
- id: rewritepath_route
uri: http://example.org
predicates:
- Path=/foo/**
filters:
- RewritePath=/foo/(?<segment>.*), /$\{segment}
$\
用于替代 $
,避免和 YAML 语法冲突。1: public class RewritePathGatewayFilterFactory implements GatewayFilterFactory {
2:
3: public static final String REGEXP_KEY = "regexp";
4: public static final String REPLACEMENT_KEY = "replacement";
5:
6: @Override
7: public List<String> argNames() {
8: return Arrays.asList(REGEXP_KEY, REPLACEMENT_KEY);
9: }
10:
11: @Override
12: public GatewayFilter apply(Tuple args) {
13: final String regex = args.getString(REGEXP_KEY);
14: // `$\` 用于替代 `$` ,避免和 YAML 语法冲突。
15: String replacement = args.getString(REPLACEMENT_KEY).replace("$\\", "$");
16:
17: return (exchange, chain) -> {
18: ServerHttpRequest req = exchange.getRequest();
19: // 添加 原始请求URI 到 GATEWAY_ORIGINAL_REQUEST_URL_ATTR
20: addOriginalRequestUrl(exchange, req.getURI());
21: // 重写 Path
22: String path = req.getURI().getPath();
23: String newPath = path.replaceAll(regex, replacement);
24:
25: // 创建新的 ServerHttpRequest
26: ServerHttpRequest request = req.mutate()
27: .path(newPath) // 设置 Path
28: .build();
29:
30: // 添加 请求URI 到 GATEWAY_REQUEST_URL_ATTR
31: exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, request.getURI());
32:
33: // 创建新的 ServerWebExchange ,提交过滤器链继续过滤
34: return chain.filter(exchange.mutate().request(request).build());
35: };
36: }
37: }
regexp
/ replacement
。$\
用于替代 $
,避免和 YAML 语法冲突。ServerWebExchangeUtils#addOriginalRequestUrl(...)
添加原始请求 URI 到 GATEWAY_ORIGINAL_REQUEST_URL_ATTR
。代码如下 :public static void addOriginalRequestUrl(ServerWebExchange exchange, URI url) {
exchange.getAttributes().computeIfAbsent(GATEWAY_ORIGINAL_REQUEST_URL_ATTR, s -> new LinkedHashSet<>()); // 数组,考虑多次重写
LinkedHashSet<URI> uris = exchange.getRequiredAttribute(GATEWAY_ORIGINAL_REQUEST_URL_ATTR);
uris.add(url);
}
GATEWAY_REQUEST_URL_ATTR
。类似 RewritePathGatewayFilterFactory ,不重复分享,点击 《Spring Cloud Gateway —— PrefixPath GatewayFilter Factory》 查看官方文档。
类似 RewritePathGatewayFilterFactory ,不重复分享,点击 《Spring Cloud Gateway —— SetPath GatewayFilter Factory》 查看官方文档。
本小节分享 Status 相关的 GatewayFilterFactory 实现类。
类似 RedirectToGatewayFilterFactory ,不重复分享,点击 《Spring Cloud Gateway —— SetStatus GatewayFilter Factory》 查看官方文档。
本小节分享 Redirect 相关的 GatewayFilterFactory 实现类。
spring:
cloud:
gateway:
routes:
# =====================================
- id: prefixpath_route
uri: http://example.org
filters:
- RedirectTo=302, http://www.iocoder.cn
1: public class RedirectToGatewayFilterFactory implements GatewayFilterFactory {
2:
3: public static final String STATUS_KEY = "status";
4: public static final String URL_KEY = "url";
5:
6: @Override
7: public List<String> argNames() {
8: return Arrays.asList(STATUS_KEY, URL_KEY);
9: }
10:
11: @Override
12: public GatewayFilter apply(Tuple args) {
13: String statusString = args.getRawString(STATUS_KEY);
14: String urlString = args.getString(URL_KEY);
15:
16: // 解析 status ,并判断是否是 3XX 重定向状态
17: final HttpStatus httpStatus = parse(statusString);
18: Assert.isTrue(httpStatus.is3xxRedirection(), "status must be a 3xx code, but was " + statusString);
19: // 创建 URL
20: final URL url;
21: try {
22: url = URI.create(urlString).toURL();
23: } catch (MalformedURLException e) {
24: throw new IllegalArgumentException("Invalid url " + urlString, e);
25: }
26:
27: return (exchange, chain) ->
28: chain.filter(exchange).then(Mono.defer(() -> { // After Filter
29: if (!exchange.getResponse().isCommitted()) {
30: // 设置响应 Status
31: setResponseStatus(exchange, httpStatus);
32:
33: // 设置响应 Header
34: final ServerHttpResponse response = exchange.getResponse();
35: response.getHeaders().set(HttpHeaders.LOCATION, url.toString());
36: return response.setComplete();
37: }
38: return Mono.empty();
39: }));
40: }
41:
42: }
statusString
,并判断是否是 3XX 重定向状态码。urlString
,创建 URL 。#then(Mono)
方法,实现 After Filter 逻辑。这里和 AddRequestHeaderGatewayFilterFactory 实现的 Before Filter 【方式】不同。Location
) 。熔断相关 GatewayFilter,我们在 《Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.9) 之 HystrixGatewayFilterFactory 熔断》 详细解析。
限流相关 GatewayFilter,我们在 《Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.10) 之 RequestRateLimiterGatewayFilterFactory 请求限流》 详细解析。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/weixin_42073629/article/details/106934417
内容来源于网络,如有侵权,请联系作者删除!