文档章节

聊聊spring cloud gateway的RemoveHopByHopHeadersFilter

go4it
 go4it
发布于 05/30 22:45
字数 635
阅读 65
收藏 2

本文主要研究一下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<String> 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<String> headers = HEADERS_REMOVED_ON_REQUEST;

	public Set<String> getHeaders() {
		return headers;
	}

	public void setHeaders(Set<String> 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<java.lang.String>"
    },
    {
      "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<List<HttpHeadersFilter>> headersFilters;

	public NettyRoutingFilter(HttpClient httpClient,
			ObjectProvider<List<HttpHeadersFilter>> headersFilters) {
		this.httpClient = httpClient;
		this.headersFilters = headersFilters;
	}

	@Override
	public int getOrder() {
		return Ordered.LOWEST_PRECEDENCE;
	}

	@Override
	public Mono<Void> 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

© 著作权归作者所有

共有 人打赏支持
go4it
粉丝 51
博文 699
码字总数 501216
作品 0
深圳
聊聊spring cloud gateway的GatewayFilter

序 本文主要研究一下spring cloud gateway的GatewayFilter GatewayFilter spring-cloud-gateway-core-2.0.0.RC2-sources.jar!/org/springframework/cloud/gateway/filter/GatewayFilter.jav......

go4it
06/09
0
0
聊聊spring.cloud.gateway.default-filters

序 本文主要研究下spring.cloud.gateway.default-filters 配置 default-filters,配置的是FilterDefinition对象 FilterDefinition spring-cloud-gateway-core-2.0.0.RC1-sources.jar!/org/sp......

go4it
06/01
0
0
聊聊spring cloud的RequestHeaderToRequestUri

序 本文主要研究一下spring cloud的RequestHeaderToRequestUriGatewayFilter GatewayAutoConfiguration spring-cloud-gateway-core-2.0.0.RC2-sources.jar!/org/springframework/cloud/gate......

go4it
06/16
0
0
聊聊spring cloud gateway的RedirectToGatewayFilter

序 本文主要研究下spring cloud gateway的RedirectToGatewayFilter GatewayAutoConfiguration spring-cloud-gateway-core-2.0.0.RC2-sources.jar!/org/springframework/cloud/gateway/confi......

go4it
06/13
0
0
聊聊spring cloud gateway的SetStatusGatewayFilter

序 本文主要研究下spring cloud gateway的SetStatusGatewayFilter GatewayAutoConfiguration spring-cloud-gateway-core-2.0.0.RC2-sources.jar!/org/springframework/cloud/gateway/config......

go4it
06/15
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

iOS开发用到的图片尺寸汇总

启动图 型号 竖屏 横屏 iPhone SE 640px × 1136px 1136px × 640px iPhone 6s 750px × 1334px 1334px × 750px iPhone 6s Plus 1242px × 2208px 2208px × 1242px iPhone 7 750px × 1334......

业界小白
32分钟前
0
0
浅谈redis

redis是一个开源,内存式的健值存储数据库,也被称为健值存储的字典服务器。健值类型有字符串,hash(哈希类型),set(集合),list(列表) 和有序集合 特征细节: 内存式:redis将健值存储在主...

拐美人
39分钟前
0
0
无限扩容,按需使用!ZStack推出基于阿里云NAS的文件存储服务

日前,ZStack发布2.6.0版本,正式宣布推出基于阿里云NAS的文件存储服务。得益于业界领先的阿里云分布式存储架构,融合NAS后的ZStack 2.6.0拥有高性能、高可靠、容量无限扩展、一键操作、按需...

ZStack社区版
42分钟前
1
0
崛起于Springboot2.X之Mongodb多数据源处理(35)

多数据源:4个mongodb库! 目录结构图: 1、添加pom依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId>......

木九天
48分钟前
0
0
如何获取显示器的EDID信息

Q1: 为什么要写这篇文章? A1:在最近的工作中遇到了不少问题,其中很多都是和EDID相关的。可以说,作为一家以“显示”为生的企业,我们时时刻刻在与EDID打交道。EDID这东西很简单,但是如果...

DB_Terrill
48分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部