From 2995005162004524cee0a45bc0b0bc38ca0153a1 Mon Sep 17 00:00:00 2001 From: Spencer Gibb Date: Tue, 14 Feb 2017 21:13:39 -0700 Subject: [PATCH] add RemoveNonProxyHeaders filter --- .../config/GatewayAutoConfiguration.java | 6 ++ .../RemoveNonProxyHeadersRouteFilter.java | 64 +++++++++++++++++++ .../cloud/gateway/support/NameUtils.java | 18 ++++++ 3 files changed, 88 insertions(+) create mode 100644 src/main/java/org/springframework/cloud/gateway/filter/route/RemoveNonProxyHeadersRouteFilter.java create mode 100644 src/main/java/org/springframework/cloud/gateway/support/NameUtils.java diff --git a/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java b/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java index 1a7c7fb40..ee60eb0ec 100644 --- a/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java +++ b/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java @@ -22,6 +22,7 @@ import org.springframework.cloud.gateway.filter.route.AddRequestParameterRouteFi import org.springframework.cloud.gateway.filter.route.AddResponseHeaderRouteFilter; import org.springframework.cloud.gateway.filter.route.HystrixRouteFilter; import org.springframework.cloud.gateway.filter.route.RedirectToRouteFilter; +import org.springframework.cloud.gateway.filter.route.RemoveNonProxyHeadersRouteFilter; import org.springframework.cloud.gateway.filter.route.RemoveRequestHeaderRouteFilter; import org.springframework.cloud.gateway.filter.route.RemoveResponseHeaderRouteFilter; import org.springframework.cloud.gateway.filter.route.RewritePathRouteFilter; @@ -213,6 +214,11 @@ public class GatewayAutoConfiguration { return new RedirectToRouteFilter(); } + @Bean(name = "RemoveNonProxyHeadersRouteFilter") + public RemoveNonProxyHeadersRouteFilter removeNonProxyHeadersRouteFilter() { + return new RemoveNonProxyHeadersRouteFilter(); + } + @Bean(name = "RemoveRequestHeaderRouteFilter") public RemoveRequestHeaderRouteFilter removeRequestHeaderRouteFilter() { return new RemoveRequestHeaderRouteFilter(); diff --git a/src/main/java/org/springframework/cloud/gateway/filter/route/RemoveNonProxyHeadersRouteFilter.java b/src/main/java/org/springframework/cloud/gateway/filter/route/RemoveNonProxyHeadersRouteFilter.java new file mode 100644 index 000000000..4ac2e3078 --- /dev/null +++ b/src/main/java/org/springframework/cloud/gateway/filter/route/RemoveNonProxyHeadersRouteFilter.java @@ -0,0 +1,64 @@ +package org.springframework.cloud.gateway.filter.route; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.web.server.WebFilter; + +import java.util.Arrays; +import java.util.List; + +/** + * Hop-by-hop header fields, which are meaningful only for a single transport-level connection, + * and are not stored by caches or forwarded by proxies. The following HTTP/1.1 header fields + * are hop-by-hop header fields: + * + * + * See https://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-14#section-7.1.3 + * + * @author Spencer Gibb + */ +@ConfigurationProperties("spring.cloud.gateway.filter.removeNonProxyHeaders") +public class RemoveNonProxyHeadersRouteFilter implements RouteFilter { + + private static final String FAKE_HEADER = "_______force_______"; + public static final String[] DEFAULT_HEADERS_TO_REMOVE = new String[] {"Connection", "Keep-Alive", + "Proxy-Authenticate", "Proxy-Authorization", "TE", "Trailer", "Transfer-Encoding", "Upgrade"}; + + private List headers = Arrays.asList(DEFAULT_HEADERS_TO_REMOVE); + + public List getHeaders() { + return headers; + } + + public void setHeaders(List headers) { + this.headers = headers; + } + + @Override + public WebFilter apply(String... args) { + //TODO: support filter args + + return (exchange, chain) -> { + ServerHttpRequest request = exchange.getRequest().mutate() + .header(FAKE_HEADER, "mutable") //TODO: is there a better way? + .build(); + + request.getHeaders().remove(FAKE_HEADER); + + for (String header : this.headers) { + request.getHeaders().remove(header); + } + + return chain.filter(exchange.mutate().request(request).build()); + }; + } +} diff --git a/src/main/java/org/springframework/cloud/gateway/support/NameUtils.java b/src/main/java/org/springframework/cloud/gateway/support/NameUtils.java new file mode 100644 index 000000000..6945a2b91 --- /dev/null +++ b/src/main/java/org/springframework/cloud/gateway/support/NameUtils.java @@ -0,0 +1,18 @@ +package org.springframework.cloud.gateway.support; + +import org.springframework.cloud.gateway.filter.route.RouteFilter; +import org.springframework.cloud.gateway.handler.predicate.RoutePredicate; + +/** + * @author Spencer Gibb + */ +public class NameUtils { + + public static String normalizePredicateName(Class clazz) { + return clazz.getSimpleName().replace(RoutePredicate.class.getSimpleName(), ""); + } + + public static String normalizeFilterName(Class clazz) { + return clazz.getSimpleName().replace(RouteFilter.class.getSimpleName(), ""); + } +}