博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
聊聊spring cloud gateway的RemoveHopByHopHeadersFilter
阅读量:6262 次
发布时间:2019-06-22

本文共 7020 字,大约阅读时间需要 23 分钟。

本文主要研究一下spring cloud gateway的RemoveHopByHopHeadersFilter

GatewayAutoConfiguration

spring-cloud-gateway-core-2.0.0.RC1-sources.jar!/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java

@Configuration@ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true)@EnableConfigurationProperties@AutoConfigureBefore(HttpHandlerAutoConfiguration.class)@AutoConfigureAfter({GatewayLoadBalancerClientAutoConfiguration.class, GatewayClassPathWarningAutoConfiguration.class})@ConditionalOnClass(DispatcherHandler.class)public class GatewayAutoConfiguration {    //......    @Bean	public RemoveHopByHopHeadersFilter removeHopByHopHeadersFilter() {		return new RemoveHopByHopHeadersFilter();	}    //......}复制代码

可以看到这里自动new了一个RemoveHopByHopHeadersFilter

RemoveHopByHopHeadersFilter

spring-cloud-gateway-core-2.0.0.RC1-sources.jar!/org/springframework/cloud/gateway/filter/headers/RemoveHopByHopHeadersFilter.java

@ConfigurationProperties("spring.cloud.gateway.filter.remove-hop-by-hop")public class RemoveHopByHopHeadersFilter implements HttpHeadersFilter, Ordered {	public static final Set
HEADERS_REMOVED_ON_REQUEST = new HashSet<>(Arrays.asList( "connection", "keep-alive", "transfer-encoding", "te", "trailer", "proxy-authorization", "proxy-authenticate", "x-application-context", "upgrade" // these two are not listed in https://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-14#section-7.1.3 //"proxy-connection", // "content-length", )); private int order = Ordered.LOWEST_PRECEDENCE; private Set
headers = HEADERS_REMOVED_ON_REQUEST; public Set
getHeaders() { return headers; } public void setHeaders(Set
headers) { this.headers = headers; } @Override public int getOrder() { return order; } public void setOrder(int order) { this.order = order; } @Override public HttpHeaders filter(HttpHeaders input, ServerWebExchange exchange) { HttpHeaders filtered = new HttpHeaders(); input.entrySet().stream() .filter(entry -> !this.headers.contains(entry.getKey().toLowerCase())) .forEach(entry -> filtered.addAll(entry.getKey(), entry.getValue())); return filtered; } @Override public boolean supports(Type type) { return type.equals(Type.REQUEST) || type.equals(Type.RESPONSE); }}复制代码

可以看到这个filter是移除request或response中指定的header,默认移除的header包括"connection","keep-alive", "transfer-encoding","te","trailer","proxy-authorization","proxy-authenticate","x-application-context","upgrade"。 也可以自己在配置文件指定要移除的header

配置

spring-cloud-gateway-core-2.0.0.RC1.jar!/META-INF/spring-configuration-metadata.json

{      "sourceType": "org.springframework.cloud.gateway.filter.headers.RemoveHopByHopHeadersFilter",      "name": "spring.cloud.gateway.filter.remove-hop-by-hop.headers",      "type": "java.util.Set
" }, { "sourceType": "org.springframework.cloud.gateway.filter.headers.RemoveHopByHopHeadersFilter", "name": "spring.cloud.gateway.filter.remove-hop-by-hop.order", "type": "java.lang.Integer" }复制代码

可以看到,有个order属性用来指定该filter的优先级,默认是Ordered.LOWEST_PRECEDENCE 还有另外一个属性headers,用来指定要移除的header

实例

spring:  cloud:    gateway:      filter:        remove-hop-by-hop:          headers:            - x-route            - x-auth-id复制代码

使用

spring-cloud-gateway-core-2.0.0.RC1-sources.jar!/org/springframework/cloud/gateway/filter/NettyRoutingFilter.java

public class NettyRoutingFilter implements GlobalFilter, Ordered {	private final HttpClient httpClient;	private final ObjectProvider
> headersFilters; public NettyRoutingFilter(HttpClient httpClient, ObjectProvider
> headersFilters) { this.httpClient = httpClient; this.headersFilters = headersFilters; } @Override public int getOrder() { return Ordered.LOWEST_PRECEDENCE; } @Override public Mono
filter(ServerWebExchange exchange, GatewayFilterChain chain) { URI requestUrl = exchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR); String scheme = requestUrl.getScheme(); if (isAlreadyRouted(exchange) || (!"http".equals(scheme) && !"https".equals(scheme))) { return chain.filter(exchange); } setAlreadyRouted(exchange); ServerHttpRequest request = exchange.getRequest(); final HttpMethod method = HttpMethod.valueOf(request.getMethod().toString()); final String url = requestUrl.toString(); HttpHeaders filtered = filterRequest(this.headersFilters.getIfAvailable(), exchange); final DefaultHttpHeaders httpHeaders = new DefaultHttpHeaders(); filtered.forEach(httpHeaders::set); String transferEncoding = request.getHeaders().getFirst(HttpHeaders.TRANSFER_ENCODING); boolean chunkedTransfer = "chunked".equalsIgnoreCase(transferEncoding); boolean preserveHost = exchange.getAttributeOrDefault(PRESERVE_HOST_HEADER_ATTRIBUTE, false); return this.httpClient.request(method, url, req -> { final HttpClientRequest proxyRequest = req.options(NettyPipeline.SendOptions::flushOnEach) .headers(httpHeaders) .chunkedTransfer(chunkedTransfer) .failOnServerError(false) .failOnClientError(false); if (preserveHost) { String host = request.getHeaders().getFirst(HttpHeaders.HOST); proxyRequest.header(HttpHeaders.HOST, host); } return proxyRequest.sendHeaders() //I shouldn't need this .send(request.getBody().map(dataBuffer -> ((NettyDataBuffer)dataBuffer).getNativeBuffer())); }).doOnNext(res -> { ServerHttpResponse response = exchange.getResponse(); // put headers and status so filters can modify the response HttpHeaders headers = new HttpHeaders(); res.responseHeaders().forEach(entry -> headers.add(entry.getKey(), entry.getValue())); HttpHeaders filteredResponseHeaders = HttpHeadersFilter.filter( this.headersFilters.getIfAvailable(), headers, exchange, Type.RESPONSE); response.getHeaders().putAll(filteredResponseHeaders); HttpStatus status = HttpStatus.resolve(res.status().code()); if (status != null) { response.setStatusCode(status); } else if (response instanceof AbstractServerHttpResponse) { // https://jira.spring.io/browse/SPR-16748 ((AbstractServerHttpResponse) response).setStatusCodeValue(res.status().code()); } else { throw new IllegalStateException("Unable to set status code on response: " +res.status().code()+", "+response.getClass()); } // Defer committing the response until all route filters have run // Put client response as ServerWebExchange attribute and write response later NettyWriteResponseFilter exchange.getAttributes().put(CLIENT_RESPONSE_ATTR, res); }).then(chain.filter(exchange)); }}复制代码

这里头对于request,调用的是

HttpHeaders filtered = filterRequest(this.headersFilters.getIfAvailable(),				exchange);复制代码

对于response调用的是

HttpHeaders filteredResponseHeaders = HttpHeadersFilter.filter(					this.headersFilters.getIfAvailable(), headers, exchange, Type.RESPONSE);复制代码

小结

RemoveHopByHopHeadersFilter可以用来移除指定的header,其作用于request及response。

doc

转载地址:http://eykpa.baihongyu.com/

你可能感兴趣的文章
大白话说Java反射:入门、使用、原理
查看>>
Dockerfile 中的 multi-stage(多阶段构建)
查看>>
nodejs中的cron
查看>>
Failed to import package with error: Couldn't decompress package的解决方案
查看>>
[日常] Go语言圣经-WEB服务与习题
查看>>
javax.websocket.Session的一个close异常记录
查看>>
I2C 12864OLED的工作机制
查看>>
在Unity场景中更改天空盒的步骤
查看>>
hibernate联合主键注解方式
查看>>
JNotify的监测文件变化的简单测试例子
查看>>
ALINX公众号
查看>>
Oracle 分区表的新增、修改、删除、合并。普通表转分区表方法
查看>>
RedisHelper帮助类
查看>>
js进阶 10-1 JQuery是什么
查看>>
Hadoop生态圈-Flume的组件之自定义拦截器(interceptor)
查看>>
orcale查询表之间的关联关系
查看>>
关于pythoh面向过程开发人员三步转面向对象的补充,再加一步,四步走战略。转面向对象也可以有固定公式。...
查看>>
SVN设置必须锁定
查看>>
(Apache)ab 压力测试 简单使用
查看>>
程序包com.sun.image.codec.jpeg不存在解决方法
查看>>