Add support for "sensitiveHeaders" in zuul.routes
By default we now discard all Set-Cookie and Cookie headers. User can manipulate it per route via zuul.routes.*.sensitiveHeaders, or globally via zuul.ignoredHeaders.
This commit is contained in:
@@ -1227,14 +1227,59 @@ span all services and supersede any other route specification.
|
||||
This means that all calls such as "/myusers/101" will be forwarded to "/101" on the "users" service.
|
||||
But calls including "/admin/" will not resolve.
|
||||
|
||||
=== Sensitive Headers
|
||||
=== Cookies and Sensitive Headers
|
||||
|
||||
It's OK to share headers between services in the same system, but you
|
||||
probably don't want sensitive headers leaking downstream into external
|
||||
servers. Thus if you use an explicit URL in a route configuration (as
|
||||
opposed to a service id), then you can also specify a list of
|
||||
sensitive headers and a whitelist of host patterns to not receive
|
||||
those headers.
|
||||
servers. You can specify a list of ignored headers as part of the
|
||||
route configuration. Cookies play a special role because they have
|
||||
well-defined semantics in browsers, and they are always to be treated
|
||||
as sensitive. If the consumer of your proxy is a browser, then cookies
|
||||
for downstream services also cause problems for the user because they
|
||||
all get jumbled up (all downstream services look like they come from
|
||||
the same place).
|
||||
|
||||
If you are careful with the design of your services, for example if
|
||||
only one of the downstream services sets cookies, then you might be
|
||||
able to let them flow from the backend all the way up to the
|
||||
caller. Also, if your proxy sets cookies and all your back end
|
||||
services are part of the same system, it can be natural to simply
|
||||
share them (and for instance us Spring Session to link them up to some
|
||||
shared state). Other than that, any cookies that get set by downstream
|
||||
services are likely to be not very useful to the caller, so it is
|
||||
recommended that you make (at least) "Set-Cookie" and "Cookie" into
|
||||
sensitive headers for routes that are not part of your domain. Even
|
||||
for routes that *are* part of your domain, try to think carefully
|
||||
about what it means before allowing cookies to flow between them and
|
||||
the proxy.
|
||||
|
||||
The sensitive headers can be configured as a comma-separate list per
|
||||
route, e.g.
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
zuul:
|
||||
routes:
|
||||
users:
|
||||
path: /myusers/**
|
||||
sensitiveHeaders: Cookie,Set-Cookie
|
||||
url: https://dowstream
|
||||
----
|
||||
|
||||
NOTE: this is the default value for `sensitiveHeaders`, so you don't
|
||||
need to set it unless you want it to be different. N.B. this is new in
|
||||
Spring Cloud Netflix 1.1 (in 1.0 the user had no control over headers
|
||||
and all cookies flow in both directions).
|
||||
|
||||
In addition to the per-route sensitive headers, you can set a global
|
||||
value for `zuul.ignoredHeaders` for values that should be discarded
|
||||
(both request and response) during interactions with downstream
|
||||
services. By default these are empty, if Spring Security is not on the
|
||||
classpath, and otherwise they are initialized to a set of well-known
|
||||
"security" headers (e.g. involving caching) as specified by Spring
|
||||
Security. The assumption in this case is that the downstream services
|
||||
might add these headers too, and we want the values from the proxy.
|
||||
|
||||
=== Strangulation Patterns and Local Forwards
|
||||
|
||||
|
||||
@@ -19,10 +19,8 @@ package org.springframework.cloud.netflix.zuul.filters;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
@@ -39,7 +37,6 @@ import org.springframework.boot.actuate.trace.TraceRepository;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.util.PatternMatchUtils;
|
||||
import org.springframework.web.util.UriTemplate;
|
||||
import org.springframework.web.util.UriUtils;
|
||||
import org.springframework.web.util.WebUtils;
|
||||
@@ -197,28 +194,11 @@ public class ProxyRequestHelper {
|
||||
for (String name : this.ignoredHeaders) {
|
||||
set.add(name.toLowerCase());
|
||||
}
|
||||
for (String name : getSensitiveHeaders(ctx)) {
|
||||
set.add(name.toLowerCase());
|
||||
}
|
||||
for (String name : names) {
|
||||
set.add(name.toLowerCase());
|
||||
}
|
||||
}
|
||||
|
||||
private Collection<String> getSensitiveHeaders(RequestContext ctx) {
|
||||
URL uri = ctx.getRouteHost();
|
||||
if (uri == null) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
String host;
|
||||
host = uri.getHost();
|
||||
if (PatternMatchUtils.simpleMatch(this.whitelistHosts.toArray(new String[0]),
|
||||
host)) {
|
||||
return this.sensitiveHeaders;
|
||||
}
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
public boolean isIncludedHeader(String headerName) {
|
||||
String name = headerName.toLowerCase();
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
package org.springframework.cloud.netflix.zuul.filters;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import lombok.Data;
|
||||
@@ -24,14 +27,19 @@ import lombok.Data;
|
||||
public class Route {
|
||||
|
||||
public Route(String id, String path, String location, String prefix,
|
||||
Boolean retryable) {
|
||||
Boolean retryable, Set<String> ignoredHeaders) {
|
||||
this.id = id;
|
||||
this.prefix = StringUtils.hasText(prefix) ? prefix : "";
|
||||
this.path = path;
|
||||
this.fullPath = prefix + path;
|
||||
this.location = location;
|
||||
this.retryable = retryable;
|
||||
|
||||
this.sensitiveHeaders = new LinkedHashSet<>();
|
||||
if (ignoredHeaders != null) {
|
||||
for (String header : ignoredHeaders) {
|
||||
this.sensitiveHeaders.add(header.toLowerCase());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String id;
|
||||
@@ -46,4 +54,6 @@ public class Route {
|
||||
|
||||
private Boolean retryable;
|
||||
|
||||
private Set<String> sensitiveHeaders = new LinkedHashSet<>();
|
||||
|
||||
}
|
||||
@@ -24,15 +24,13 @@ import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import lombok.extern.apachecommons.CommonsLog;
|
||||
|
||||
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute;
|
||||
import org.springframework.cloud.netflix.zuul.util.RequestUtils;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
import org.springframework.util.PathMatcher;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.netflix.zuul.http.ZuulServlet;
|
||||
import lombok.extern.apachecommons.CommonsLog;
|
||||
|
||||
/**
|
||||
* Simple {@link RouteLocator} based on configuration data held in {@link ZuulProperties}.
|
||||
@@ -54,9 +52,9 @@ public class SimpleRouteLocator implements RouteLocator {
|
||||
public SimpleRouteLocator(String servletPath, ZuulProperties properties) {
|
||||
this.properties = properties;
|
||||
if (servletPath != null && StringUtils.hasText(servletPath)) {
|
||||
this.dispatcherServletPath = servletPath;
|
||||
this.dispatcherServletPath = servletPath;
|
||||
}
|
||||
|
||||
|
||||
this.zuulServletPath = properties.getServletPath();
|
||||
}
|
||||
|
||||
@@ -92,7 +90,7 @@ public class SimpleRouteLocator implements RouteLocator {
|
||||
|
||||
log.debug("servletPath=" + this.dispatcherServletPath);
|
||||
log.debug("zuulServletPath=" + this.zuulServletPath);
|
||||
|
||||
|
||||
String adjustedPath = adjustPath(path);
|
||||
|
||||
ZuulRoute route = null;
|
||||
@@ -107,7 +105,7 @@ public class SimpleRouteLocator implements RouteLocator {
|
||||
}
|
||||
}
|
||||
log.debug("route matched=" + route);
|
||||
|
||||
|
||||
return getRoute(route, adjustedPath);
|
||||
|
||||
}
|
||||
@@ -134,7 +132,7 @@ public class SimpleRouteLocator implements RouteLocator {
|
||||
retryable = route.getRetryable();
|
||||
}
|
||||
return new Route(route.getId(), targetPath, route.getLocation(), prefix,
|
||||
retryable);
|
||||
retryable, route.getSensitiveHeaders());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -167,27 +165,28 @@ public class SimpleRouteLocator implements RouteLocator {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private String adjustPath(final String path) {
|
||||
String adjustedPath = path;
|
||||
|
||||
if (RequestUtils.isDispatcherServletRequest()
|
||||
&& StringUtils.hasText(dispatcherServletPath)) {
|
||||
if (!dispatcherServletPath.equals("/")) {
|
||||
adjustedPath = path.substring(this.dispatcherServletPath.length());
|
||||
}
|
||||
} else if (RequestUtils.isZuulServletRequest()){
|
||||
if (StringUtils.hasText(zuulServletPath)
|
||||
&& !zuulServletPath.equals("/")) {
|
||||
adjustedPath = path.substring(this.zuulServletPath.length());
|
||||
}
|
||||
} else {
|
||||
//do nothing
|
||||
}
|
||||
|
||||
log.debug("adjustedPath=" + path);
|
||||
return adjustedPath;
|
||||
String adjustedPath = path;
|
||||
|
||||
if (RequestUtils.isDispatcherServletRequest()
|
||||
&& StringUtils.hasText(this.dispatcherServletPath)) {
|
||||
if (!this.dispatcherServletPath.equals("/")) {
|
||||
adjustedPath = path.substring(this.dispatcherServletPath.length());
|
||||
}
|
||||
}
|
||||
else if (RequestUtils.isZuulServletRequest()) {
|
||||
if (StringUtils.hasText(this.zuulServletPath)
|
||||
&& !this.zuulServletPath.equals("/")) {
|
||||
adjustedPath = path.substring(this.zuulServletPath.length());
|
||||
}
|
||||
}
|
||||
else {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
log.debug("adjustedPath=" + path);
|
||||
return adjustedPath;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -66,8 +66,6 @@ public class ZuulProperties {
|
||||
|
||||
private Set<String> ignoredHeaders = new LinkedHashSet<>();
|
||||
|
||||
private Sensitive sensitive = new Sensitive();
|
||||
|
||||
private String servletPath = "/zuul";
|
||||
|
||||
private boolean ignoreLocalService = true;
|
||||
@@ -105,21 +103,6 @@ public class ZuulProperties {
|
||||
}
|
||||
}
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public static class Sensitive {
|
||||
/**
|
||||
* Headers that are considered sensitive, and not passed on through a proxy.
|
||||
*/
|
||||
private Set<String> headers = new LinkedHashSet<>(Arrays.asList("Cookie"));
|
||||
/**
|
||||
* Hostname (patterns) that are considered safe and can receive sensitive headers
|
||||
* when a route is specified as a URL.
|
||||
*/
|
||||
private Set<String> whitelist = new LinkedHashSet<>(Arrays.asList("localhost"));
|
||||
}
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@@ -137,6 +120,9 @@ public class ZuulProperties {
|
||||
|
||||
private Boolean retryable;
|
||||
|
||||
private Set<String> sensitiveHeaders = new LinkedHashSet<>(
|
||||
Arrays.asList("Cookie", "Set-Cookie"));
|
||||
|
||||
public ZuulRoute(String text) {
|
||||
String location = null;
|
||||
String path = text;
|
||||
@@ -184,7 +170,8 @@ public class ZuulProperties {
|
||||
}
|
||||
|
||||
public Route getRoute(String prefix) {
|
||||
return new Route(this.id, this.path, getLocation(), prefix, this.retryable);
|
||||
return new Route(this.id, this.path, getLocation(), prefix, this.retryable,
|
||||
this.sensitiveHeaders);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -71,6 +71,7 @@ public class PreDecorationFilter extends ZuulFilter {
|
||||
if (location != null) {
|
||||
ctx.put("requestURI", route.getPath());
|
||||
ctx.put("proxy", route.getId());
|
||||
ctx.put("ignoredHeaders", route.getSensitiveHeaders());
|
||||
|
||||
if (route.getRetryable() != null) {
|
||||
ctx.put("retryable", route.getRetryable());
|
||||
@@ -81,9 +82,8 @@ public class PreDecorationFilter extends ZuulFilter {
|
||||
ctx.addOriginResponseHeader("X-Zuul-Service", location);
|
||||
}
|
||||
else if (location.startsWith("forward:")) {
|
||||
ctx.set("forward.to",
|
||||
StringUtils.cleanPath(location.substring("forward:".length())
|
||||
+ route.getPath()));
|
||||
ctx.set("forward.to", StringUtils.cleanPath(
|
||||
location.substring("forward:".length()) + route.getPath()));
|
||||
ctx.setRouteHost(null);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ public class ContextPathZuulProxyApplicationTests {
|
||||
@Test
|
||||
public void stripPrefixFalseAppendsPath() {
|
||||
this.routes.addRoute(new ZuulRoute("strip", "/strip/**", "strip",
|
||||
"http://localhost:" + this.port + "/app/local", false, false));
|
||||
"http://localhost:" + this.port + "/app/local", false, false, null));
|
||||
this.endpoint.reset();
|
||||
ResponseEntity<String> result = new TestRestTemplate().exchange(
|
||||
"http://localhost:" + this.port + "/app/strip", HttpMethod.GET,
|
||||
|
||||
@@ -81,7 +81,7 @@ public class ServletPathZuulProxyApplicationTests {
|
||||
@Test
|
||||
public void stripPrefixFalseAppendsPath() {
|
||||
this.routes.addRoute(new ZuulRoute("strip", "/strip/**", "strip",
|
||||
"http://localhost:" + this.port + "/app/local", false, false));
|
||||
"http://localhost:" + this.port + "/app/local", false, false, null));
|
||||
this.endpoint.reset();
|
||||
ResponseEntity<String> result = new TestRestTemplate().exchange(
|
||||
"http://localhost:" + this.port + "/app/strip", HttpMethod.GET,
|
||||
|
||||
@@ -100,7 +100,7 @@ public abstract class ZuulProxyTestBase {
|
||||
@Test
|
||||
public void stripPrefixFalseAppendsPath() {
|
||||
this.routes.addRoute(new ZuulProperties.ZuulRoute("strip", "/strip/**", "strip",
|
||||
"http://localhost:" + this.port + "/local", false, false));
|
||||
"http://localhost:" + this.port + "/local", false, false, null));
|
||||
this.endpoint.reset();
|
||||
ResponseEntity<String> result = new TestRestTemplate().exchange(
|
||||
"http://localhost:" + this.port + "/strip", HttpMethod.GET,
|
||||
|
||||
@@ -17,8 +17,6 @@
|
||||
package org.springframework.cloud.netflix.zuul.filters;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -181,35 +179,4 @@ public class ProxyRequestHelperTests {
|
||||
assertThat(queryString, is("?wsdl"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ignoreSensitiveHeadersMatchingHost() throws Exception {
|
||||
ProxyRequestHelper helper = new ProxyRequestHelper();
|
||||
helper.setSensitiveHeaders(Collections.singleton("Cookie"));
|
||||
helper.setWhitelistHosts(Collections.singleton("*"));
|
||||
RequestContext context = RequestContext.getCurrentContext();
|
||||
context.setRouteHost(new URL("http://example.com"));
|
||||
helper.addIgnoredHeaders();
|
||||
assertThat(helper.isIncludedHeader("Cookie"), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ignoreSensitiveHeadersNotMatching() throws Exception {
|
||||
ProxyRequestHelper helper = new ProxyRequestHelper();
|
||||
helper.setSensitiveHeaders(Collections.singleton("Cookie"));
|
||||
helper.setWhitelistHosts(Collections.singleton("foo.com"));
|
||||
RequestContext context = RequestContext.getCurrentContext();
|
||||
context.setRouteHost(new URL("http://example.com"));
|
||||
helper.addIgnoredHeaders();
|
||||
assertThat(helper.isIncludedHeader("Cookie"), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ignoreSensitiveHeadersWhenNoRoute() throws Exception {
|
||||
ProxyRequestHelper helper = new ProxyRequestHelper();
|
||||
helper.setSensitiveHeaders(Collections.singleton("Cookie"));
|
||||
helper.setWhitelistHosts(Collections.singleton("foo.com"));
|
||||
RequestContext context = RequestContext.getCurrentContext();
|
||||
helper.addIgnoredHeaders();
|
||||
assertThat(helper.isIncludedHeader("Cookie"), is(true));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,9 @@ package org.springframework.cloud.netflix.zuul.filters;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
@@ -35,9 +37,26 @@ public class ZuulPropertiesTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addtIgnoredHeaders() {
|
||||
public void addIgnoredHeaders() {
|
||||
this.zuul.setIgnoredHeaders(Collections.singleton("x-foo"));
|
||||
assertTrue(this.zuul.getIgnoredHeaders().contains("x-foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultSensitiveHeaders() {
|
||||
ZuulRoute route = new ZuulRoute("foo");
|
||||
this.zuul.getRoutes().put("foo", route);
|
||||
assertTrue(this.zuul.getRoutes().get("foo").getSensitiveHeaders()
|
||||
.contains("Cookie"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addSensitiveHeaders() {
|
||||
ZuulRoute route = new ZuulRoute("foo");
|
||||
route.setSensitiveHeaders(Collections.singleton("x-foo"));
|
||||
this.zuul.getRoutes().put("foo", route);
|
||||
assertFalse(this.zuul.getRoutes().get("foo").getSensitiveHeaders()
|
||||
.contains("Cookie"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -145,7 +145,7 @@ public class DiscoveryClientRouteLocatorTests {
|
||||
DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/",
|
||||
this.discovery, this.properties);
|
||||
this.properties.getRoutes().put("foo",
|
||||
new ZuulRoute("foo", "/foo/**", "foo", null, false, null));
|
||||
new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null));
|
||||
this.properties.setStripPrefix(false);
|
||||
this.properties.setPrefix("/proxy");
|
||||
routeLocator.getRoutes(); // force refresh
|
||||
@@ -172,7 +172,7 @@ public class DiscoveryClientRouteLocatorTests {
|
||||
DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/",
|
||||
this.discovery, this.properties);
|
||||
this.properties.getRoutes().put("foo",
|
||||
new ZuulRoute("foo", "/foo/**", "foo", null, false, null));
|
||||
new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null));
|
||||
this.properties.setPrefix("/proxy");
|
||||
routeLocator.getRoutes(); // force refresh
|
||||
Route route = routeLocator.getMatchingRoute("/proxy/foo/1");
|
||||
@@ -188,7 +188,7 @@ public class DiscoveryClientRouteLocatorTests {
|
||||
DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/app",
|
||||
this.discovery, this.properties);
|
||||
this.properties.getRoutes().put("foo",
|
||||
new ZuulRoute("foo", "/foo/**", "foo", null, false, null));
|
||||
new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null));
|
||||
this.properties.setPrefix("/proxy");
|
||||
routeLocator.getRoutes(); // force refresh
|
||||
Route route = routeLocator.getMatchingRoute("/app/proxy/foo/1");
|
||||
@@ -203,7 +203,7 @@ public class DiscoveryClientRouteLocatorTests {
|
||||
DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/",
|
||||
this.discovery, this.properties);
|
||||
this.properties.getRoutes().put("foo",
|
||||
new ZuulRoute("foo", "/foo/**", "foo", null, false, null));
|
||||
new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null));
|
||||
this.properties.setPrefix("/proxy");
|
||||
routeLocator.getRoutes(); // force refresh
|
||||
Route route = routeLocator.getMatchingRoute("/zuul/proxy/foo/1");
|
||||
@@ -285,7 +285,7 @@ public class DiscoveryClientRouteLocatorTests {
|
||||
this.discovery, this.properties);
|
||||
this.properties.setIgnoredPatterns(Collections.singleton(IGNOREDPATTERN));
|
||||
this.properties.getRoutes().put("foo",
|
||||
new ZuulRoute("foo", "/foo/**", "foo", null, false, null));
|
||||
new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null));
|
||||
this.properties.setStripPrefix(false);
|
||||
this.properties.setPrefix("/proxy");
|
||||
routeLocator.getRoutes(); // force refresh
|
||||
@@ -302,7 +302,7 @@ public class DiscoveryClientRouteLocatorTests {
|
||||
this.properties
|
||||
.setIgnoredPatterns(Collections.singleton("/proxy" + IGNOREDPATTERN));
|
||||
this.properties.getRoutes().put("foo",
|
||||
new ZuulRoute("foo", "/foo/**", "foo", null, false, null));
|
||||
new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null));
|
||||
this.properties.setStripPrefix(false);
|
||||
this.properties.setPrefix("/proxy");
|
||||
routeLocator.getRoutes(); // force refresh
|
||||
@@ -347,7 +347,7 @@ public class DiscoveryClientRouteLocatorTests {
|
||||
this.discovery, this.properties);
|
||||
this.properties.setIgnoredPatterns(Collections.singleton(IGNOREDPATTERN));
|
||||
this.properties.getRoutes().put("foo",
|
||||
new ZuulRoute("foo", "/foo/**", "foo", null, false, null));
|
||||
new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null));
|
||||
this.properties.setPrefix("/proxy");
|
||||
routeLocator.getRoutes(); // force refresh
|
||||
Route route = routeLocator.getMatchingRoute("/proxy/foo/1");
|
||||
@@ -363,7 +363,7 @@ public class DiscoveryClientRouteLocatorTests {
|
||||
this.properties
|
||||
.setIgnoredPatterns(Collections.singleton("/proxy" + IGNOREDPATTERN));
|
||||
this.properties.getRoutes().put("foo",
|
||||
new ZuulRoute("foo", "/foo/**", "foo", null, false, null));
|
||||
new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null));
|
||||
this.properties.setPrefix("/proxy");
|
||||
routeLocator.getRoutes(); // force refresh
|
||||
Route route = routeLocator.getMatchingRoute("/proxy/foo/1");
|
||||
|
||||
@@ -16,9 +16,6 @@
|
||||
|
||||
package org.springframework.cloud.netflix.zuul.filters.pre;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.MockitoAnnotations.initMocks;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -33,6 +30,9 @@ import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import com.netflix.util.Pair;
|
||||
import com.netflix.zuul.context.RequestContext;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.MockitoAnnotations.initMocks;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@@ -72,15 +72,16 @@ public class PreDecorationFilterTests {
|
||||
this.properties.setPrefix("/api");
|
||||
this.properties.setStripPrefix(true);
|
||||
this.request.setRequestURI("/api/foo/1");
|
||||
this.routeLocator.addRoute(new ZuulRoute("foo", "/foo/**", "foo", null, false,
|
||||
null));
|
||||
this.routeLocator.addRoute(
|
||||
new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null));
|
||||
this.filter.run();
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
assertEquals("/foo/1", ctx.get("requestURI"));
|
||||
assertEquals("localhost:80", ctx.getZuulRequestHeaders().get("x-forwarded-host"));
|
||||
assertEquals("http", ctx.getZuulRequestHeaders().get("x-forwarded-proto"));
|
||||
assertEquals("/api", ctx.getZuulRequestHeaders().get("x-forwarded-prefix"));
|
||||
assertEquals("foo", getHeader(ctx.getOriginResponseHeaders(), "x-zuul-serviceid"));
|
||||
assertEquals("foo",
|
||||
getHeader(ctx.getOriginResponseHeaders(), "x-zuul-serviceid"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -88,8 +89,8 @@ public class PreDecorationFilterTests {
|
||||
this.properties.setPrefix("/api");
|
||||
this.properties.setStripPrefix(true);
|
||||
this.request.setRequestURI("/api/foo/1");
|
||||
this.routeLocator.addRoute(new ZuulRoute("foo", "/foo/**", null, "forward:/foo", true,
|
||||
null));
|
||||
this.routeLocator.addRoute(
|
||||
new ZuulRoute("foo", "/foo/**", null, "forward:/foo", true, null, null));
|
||||
this.filter.run();
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
assertEquals("/foo/1", ctx.get("forward.to"));
|
||||
@@ -98,8 +99,8 @@ public class PreDecorationFilterTests {
|
||||
@Test
|
||||
public void forwardWithoutStripPrefixAppendsPath() throws Exception {
|
||||
this.request.setRequestURI("/foo/1");
|
||||
this.routeLocator.addRoute(new ZuulRoute("foo", "/foo/**", null, "forward:/bar", false,
|
||||
null));
|
||||
this.routeLocator.addRoute(
|
||||
new ZuulRoute("foo", "/foo/**", null, "forward:/bar", false, null, null));
|
||||
this.filter.run();
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
assertEquals("/bar/foo/1", ctx.get("forward.to"));
|
||||
@@ -117,7 +118,8 @@ public class PreDecorationFilterTests {
|
||||
assertEquals("localhost:80", ctx.getZuulRequestHeaders().get("x-forwarded-host"));
|
||||
assertEquals("http", ctx.getZuulRequestHeaders().get("x-forwarded-proto"));
|
||||
assertEquals("/api/foo", ctx.getZuulRequestHeaders().get("x-forwarded-prefix"));
|
||||
assertEquals("foo", getHeader(ctx.getOriginResponseHeaders(), "x-zuul-serviceid"));
|
||||
assertEquals("foo",
|
||||
getHeader(ctx.getOriginResponseHeaders(), "x-zuul-serviceid"));
|
||||
}
|
||||
|
||||
private Object getHeader(List<Pair<String, String>> headers, String key) {
|
||||
|
||||
@@ -54,8 +54,8 @@ public class ZuulHandlerMappingTests {
|
||||
|
||||
@Test
|
||||
public void mappedPath() throws Exception {
|
||||
Mockito.when(this.locator.getRoutes()).thenReturn(
|
||||
Collections.singletonList(new Route("foo", "/foo/**", "foo", "", null)));
|
||||
Mockito.when(this.locator.getRoutes()).thenReturn(Collections
|
||||
.singletonList(new Route("foo", "/foo/**", "foo", "", null, null)));
|
||||
this.request.setServletPath("/foo/");
|
||||
this.mapping.setDirty(true);
|
||||
assertNotNull(this.mapping.getHandler(this.request));
|
||||
@@ -63,8 +63,8 @@ public class ZuulHandlerMappingTests {
|
||||
|
||||
@Test
|
||||
public void defaultPath() throws Exception {
|
||||
Mockito.when(this.locator.getRoutes()).thenReturn(
|
||||
Collections.singletonList(new Route("default", "/**", "foo", "", null)));
|
||||
Mockito.when(this.locator.getRoutes()).thenReturn(Collections
|
||||
.singletonList(new Route("default", "/**", "foo", "", null, null)));
|
||||
;
|
||||
this.request.setServletPath("/");
|
||||
this.mapping.setDirty(true);
|
||||
@@ -73,8 +73,8 @@ public class ZuulHandlerMappingTests {
|
||||
|
||||
@Test
|
||||
public void errorPath() throws Exception {
|
||||
Mockito.when(this.locator.getRoutes()).thenReturn(
|
||||
Collections.singletonList(new Route("default", "/**", "foo", "", null)));
|
||||
Mockito.when(this.locator.getRoutes()).thenReturn(Collections
|
||||
.singletonList(new Route("default", "/**", "foo", "", null, null)));
|
||||
this.request.setServletPath("/error");
|
||||
this.mapping.setDirty(true);
|
||||
assertNull(this.mapping.getHandler(this.request));
|
||||
|
||||
Reference in New Issue
Block a user