本文主要研究spring cloud gateway的XForwardedHeadersFilterhtml
spring-cloud-gateway-core-2.0.0.RC1-sources.jar!/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.javajava
@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 @ConditionalOnProperty(name = "spring.cloud.gateway.x-forwarded.enabled", matchIfMissing = true) public XForwardedHeadersFilter xForwardedHeadersFilter() { return new XForwardedHeadersFilter(); } //...... }
默認註冊了XForwardedHeadersFilter
spring-cloud-gateway-core-2.0.0.RC1-sources.jar!/org/springframework/cloud/gateway/filter/headers/XForwardedHeadersFilter.javaspring
@ConfigurationProperties("spring.cloud.gateway.x-forwarded") public class XForwardedHeadersFilter implements HttpHeadersFilter, Ordered { //...... @Override public HttpHeaders filter(HttpHeaders input, ServerWebExchange exchange) { ServerHttpRequest request = exchange.getRequest(); HttpHeaders original = input; HttpHeaders updated = new HttpHeaders(); original.entrySet().stream() .forEach(entry -> updated.addAll(entry.getKey(), entry.getValue())); if (isForEnabled()) { String remoteAddr = request.getRemoteAddress().getAddress().getHostAddress(); List<String> xforwarded = original.get(X_FORWARDED_FOR_HEADER); // prevent duplicates if (remoteAddr != null && (xforwarded == null || !xforwarded.contains(remoteAddr))) { write(updated, X_FORWARDED_FOR_HEADER, remoteAddr, isForAppend()); } } String proto = request.getURI().getScheme(); if (isProtoEnabled()) { write(updated, X_FORWARDED_PROTO_HEADER, proto, isProtoAppend()); } if (isPortEnabled()) { String port = String.valueOf(request.getURI().getPort()); if (request.getURI().getPort() < 0) { port = String.valueOf(getDefaultPort(proto)); } write(updated, X_FORWARDED_PORT_HEADER, port, isPortAppend()); } if (isHostEnabled()) { String host = toHostHeader(request); write(updated, X_FORWARDED_HOST_HEADER, host, isHostAppend()); } return updated; } //...... }
每一個enable屬性都有一個append屬性,用來決定是不是添加仍是追加app
private void write(HttpHeaders headers, String name, String value, boolean append) { if (append) { headers.add(name, value); // these headers should be treated as a single comma separated header List<String> values = headers.get(name); String delimitedValue = StringUtils.collectionToCommaDelimitedString(values); headers.set(name, delimitedValue); } else { headers.set(name, value); } }
若是是append,則逗號分隔寫入headers,若是不是則是採起set操做。
{ "sourceType": "org.springframework.cloud.gateway.filter.headers.XForwardedHeadersFilter", "defaultValue": true, "name": "spring.cloud.gateway.x-forwarded.enabled", "description": "If the XForwardedHeadersFilter is enabled.", "type": "java.lang.Boolean" }, { "sourceType": "org.springframework.cloud.gateway.filter.headers.XForwardedHeadersFilter", "defaultValue": true, "name": "spring.cloud.gateway.x-forwarded.for-append", "description": "If appending X-Forwarded-For as a list is enabled.", "type": "java.lang.Boolean" }, { "sourceType": "org.springframework.cloud.gateway.filter.headers.XForwardedHeadersFilter", "defaultValue": true, "name": "spring.cloud.gateway.x-forwarded.for-enabled", "description": "If X-Forwarded-For is enabled.", "type": "java.lang.Boolean" }, { "sourceType": "org.springframework.cloud.gateway.filter.headers.XForwardedHeadersFilter", "defaultValue": true, "name": "spring.cloud.gateway.x-forwarded.host-append", "description": "If appending X-Forwarded-Host as a list is enabled.", "type": "java.lang.Boolean" }, { "sourceType": "org.springframework.cloud.gateway.filter.headers.XForwardedHeadersFilter", "defaultValue": true, "name": "spring.cloud.gateway.x-forwarded.host-enabled", "description": "If X-Forwarded-Host is enabled.", "type": "java.lang.Boolean" }, { "sourceType": "org.springframework.cloud.gateway.filter.headers.XForwardedHeadersFilter", "defaultValue": 0, "name": "spring.cloud.gateway.x-forwarded.order", "description": "The order of the XForwardedHeadersFilter.", "type": "java.lang.Integer" }, { "sourceType": "org.springframework.cloud.gateway.filter.headers.XForwardedHeadersFilter", "defaultValue": true, "name": "spring.cloud.gateway.x-forwarded.port-append", "description": "If appending X-Forwarded-Port as a list is enabled.", "type": "java.lang.Boolean" }, { "sourceType": "org.springframework.cloud.gateway.filter.headers.XForwardedHeadersFilter", "defaultValue": true, "name": "spring.cloud.gateway.x-forwarded.port-enabled", "description": "If X-Forwarded-Port is enabled.", "type": "java.lang.Boolean" }, { "sourceType": "org.springframework.cloud.gateway.filter.headers.XForwardedHeadersFilter", "defaultValue": true, "name": "spring.cloud.gateway.x-forwarded.proto-append", "description": "If appending X-Forwarded-Proto as a list is enabled.", "type": "java.lang.Boolean" }, { "sourceType": "org.springframework.cloud.gateway.filter.headers.XForwardedHeadersFilter", "defaultValue": true, "name": "spring.cloud.gateway.x-forwarded.proto-enabled", "description": "If X-Forwarded-Proto is enabled.", "type": "java.lang.Boolean" }
spring cloud gateway提供了XForwardedHeadersFilter,用來決定進行路由轉發的時候轉發哪些X-Forwarded相關的header,同時提供append選項,用來控制是不是追加仍是覆蓋到header中。ide