文档章节

聊聊spring cloud的PreserveHostHeaderGatewayFilter

go4it
 go4it
发布于 06/14 22:11
字数 440
阅读 18
收藏 0
点赞 0
评论 0

本文主要研究下spring cloud gateway的PreserveHostHeaderGatewayFilter

GatewayAutoConfiguration

spring-cloud-gateway-core-2.0.0.RC2-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 PreserveHostHeaderGatewayFilterFactory preserveHostHeaderGatewayFilterFactory() {
		return new PreserveHostHeaderGatewayFilterFactory();
	}
    //......
}

PreserveHostHeaderGatewayFilterFactory

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

public class PreserveHostHeaderGatewayFilterFactory extends AbstractGatewayFilterFactory {

	public GatewayFilter apply() {
		return apply(o -> {});
	}

    public GatewayFilter apply(Object config) {
		return (exchange, chain) -> {
			exchange.getAttributes().put(PRESERVE_HOST_HEADER_ATTRIBUTE, true);
			return chain.filter(exchange);
		};
	}
}

这个filter超级简单,就往exchange添加PRESERVE_HOST_HEADER_ATTRIBUTE,设置为true

NettyRoutingFilter

spring-cloud-gateway-core-2.0.0.RC2-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));
	}
}

这里从读取PRESERVE_HOST_HEADER_ATTRIBUTE属性,没有则默认false。如果为true,则proxyRequest.header(HttpHeaders.HOST, host),传递host头部。

小结

PreserveHostHeaderGatewayFilter就是在gateway转发请求的时候把原始请求的host头部带上,转发给目标服务。默认该filter是启用的。

doc

© 著作权归作者所有

共有 人打赏支持
go4it
粉丝 51
博文 668
码字总数 465432
作品 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 netflix的HystrixCommands

序 本文主要研究一下spring cloud netflix的HystrixCommands。 maven 这个组件对hystrix进行了封装了,2.0.0.RELEASE全面支持了Reactor的Reactive Streams。 spring-cloud-starter-netflix-h...

go4it
06/22
0
0
聊聊eureka client的shutdown

序 本文主要研究一下eureka client的shutdown EurekaRegistration spring-cloud-netflix-eureka-client-2.0.0.RC1-sources.jar!/org/springframework/cloud/netflix/eureka/EurekaClientAuto......

go4it
05/04
0
0
聊聊WebClient的LoadBalance支持

序 本文主要研究一下WebClient的LoadBalance支持 代码实例 配置 请求department-service controller /flux/departments?orgId=1 异常情况 Connection refused instance can not be null 源码......

go4it
04/29
0
0
聊聊springcloud的serviceRegistryEndpoint

序 本文主要研究一下springcloud的serviceRegistryEndpoint 实例 GET /actuator/service-registry 如果eureka挂了,则返回 后台日志 POST /actuator/service-registry 在查看则返回 再去eur...

go4it
04/28
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
聊聊spring cloud gateway的RemoveHopByHopHeadersFilter

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

go4it
05/30
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

自定义OkHttp的UA

背景 上次的问题很明显 由于我们的ua清一色OkHttp导致快速定位到内部应用。 既然如此我们是否考虑可以在UA上做点手脚。 自定义我们的UA呢??? 分析 首先UA在 均为okhttp/3.2.0 大概率是由于...

Mr_Qi
17分钟前
0
0
【scikit-learn】01:使用案例对sklearn库进行简单介绍

sklearn学习笔记:Quick Start 源地址:http://scikit-learn.org/stable/tutorial/basic/tutorial.html # -*-coding:utf-8-*-''' Author:kevinelstri Datetime:2017.2.16'''......

wangxuwei
21分钟前
0
0
Linux Kernel 4.16 系列停止维护,用户应升级至 4.17

知名 Linux 内核维护人员兼开发人员 Greg Kroah-Hartman 近日在发布 4.16.18 版本的同时,宣布这是 4.16 系列的最后一个维护版本,强烈建议用户立即升级至 4.17 系列。 Linux 4.16 于 2018 年...

问题终结者
23分钟前
0
0
Apache配置时.htaccess失效不起作用的原因分析

.htaccess 失效的原因 1. 重写规则有问题,检查自己的重写规则 2.Apache配置问题,配置中没有配置启用 rewrite a2enmod rewrite 3.网站配置文件没有启用配置需要配置 000-default.conf <Dire...

TU-DESGIN
43分钟前
1
0
两个求最大公约数C/C++算法实现

#include<stdio.h> #include<time.h> #include <iostream>using namespace std;//求最大公约数 LCD(Largest Common Division)//短除法 //m=8251, n=6105; int LCD_ShortDiv(int m, ......

失落的艺术
49分钟前
1
0
QueryPerformanceCounter

windows的Sleep函数,睡眠线程指定毫秒数,可以用来做毫秒延时。 对于微秒延时,没有一个现成的函数,但是可以通过 QueryPerformanceFrequency QueryPerformanceCounter 来间接实现。原理就是...

开飞色
今天
1
0
log4j2使用AsyncRoot不显示行号问题处理

<AsyncRoot level="info" includeLocation="true"> <AppenderRef ref="File"/></AsyncRoot><!--1.异步logger,还需要在pom.xml中添加disruptor的依赖。2.includeLocation结合异......

小翔
今天
3
0
安卓手机上 K 歌,声音延迟怎么解决?

这篇文章可以为你提供一个解决录音和播放同步问题的思路,而且解决了声音从手机传输到耳机上有延时的问题。 初识音频 在开始之前,我先简单介绍一下音频相关的基础知识,方便下文理解。 我们...

编辑部的故事
今天
2
0
使用token实现在有效期内APP自动登录功能

使用token实现在有效期内APP自动登录功能 http://sevennight.cc/2016/07/19/auto_login_impl.html

风云海滩
今天
2
0
Spring Boot集成RabbitMQ发送接收JSON

默认情况下RabbitMQ发送的消息是转换为字节码,这里介绍一下如何发送JSON数据。 ObjectMapper 最简单发送JSON数据的方式是把对象使用ObjectMapper等JSON工具类把对象转换为JSON格式,然后发送...

小致dad
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部