Move many zuul strings to FilterConstants.

Also adds minimal javadoc to classes.

See gh-1435
This commit is contained in:
Spencer Gibb
2017-02-08 12:09:53 -07:00
parent 10e8634d38
commit 506a9a44af
16 changed files with 425 additions and 113 deletions

View File

@@ -20,24 +20,29 @@ import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.netflix.zuul.exception.ZuulException;
import lombok.extern.apachecommons.CommonsLog;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.netflix.zuul.util.ZuulRuntimeException;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.springframework.util.StringUtils;
import com.netflix.zuul.exception.ZuulException;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.ERROR_TYPE;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SEND_ERROR_FILTER_ORDER;
/**
* Error {@link ZuulFilter} that forwards to /error (by default) if {@link RequestContext#getThrowable()} is not null.
*
* @author Spencer Gibb
*/
//TODO: move to error package in Edgware
@CommonsLog
public class SendErrorFilter extends ZuulFilter {
private static final Log log = LogFactory.getLog(SendErrorFilter.class);
protected static final String SEND_ERROR_FILTER_RAN = "sendErrorFilter.ran";
@Value("${error.path:/error}")
@@ -45,12 +50,12 @@ public class SendErrorFilter extends ZuulFilter {
@Override
public String filterType() {
return "error";
return ERROR_TYPE;
}
@Override
public int filterOrder() {
return 0;
return SEND_ERROR_FILTER_ORDER;
}
@Override

View File

@@ -16,16 +16,19 @@
package org.springframework.cloud.netflix.zuul.filters.post;
import lombok.extern.apachecommons.CommonsLog;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.zip.GZIPInputStream;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.ReflectionUtils;
import com.netflix.config.DynamicBooleanProperty;
import com.netflix.config.DynamicIntProperty;
import com.netflix.config.DynamicPropertyFactory;
@@ -36,12 +39,22 @@ import com.netflix.zuul.constants.ZuulHeaders;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.util.HTTPRequestUtils;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.POST_TYPE;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.ROUTING_DEBUG_KEY;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SEND_RESPONSE_FILTER_ORDER;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.X_ZUUL_DEBUG_HEADER;
/**
* Post {@link ZuulFilter} that writes responses from proxied requests to the current response.
*
* @author Spencer Gibb
* @author Dave Syer
* @author Ryan Baxter
*/
@CommonsLog
public class SendResponseFilter extends ZuulFilter {
private static final Log log = LogFactory.getLog(SendResponseFilter.class);
private static DynamicBooleanProperty INCLUDE_DEBUG_HEADER = DynamicPropertyFactory
.getInstance()
.getBooleanProperty(ZuulConstants.ZUUL_INCLUDE_DEBUG_HEADER, false);
@@ -74,12 +87,12 @@ public class SendResponseFilter extends ZuulFilter {
@Override
public String filterType() {
return "post";
return POST_TYPE;
}
@Override
public int filterOrder() {
return 1000;
return SEND_RESPONSE_FILTER_ORDER;
}
@Override
@@ -201,13 +214,13 @@ public class SendResponseFilter extends ZuulFilter {
HttpServletResponse servletResponse = context.getResponse();
if (INCLUDE_DEBUG_HEADER.get()) {
@SuppressWarnings("unchecked")
List<String> rd = (List<String>) context.get("routingDebug");
List<String> rd = (List<String>) context.get(ROUTING_DEBUG_KEY);
if (rd != null) {
StringBuilder debugHeader = new StringBuilder();
for (String it : rd) {
debugHeader.append("[[[" + it + "]]]");
}
servletResponse.addHeader("X-Zuul-Debug-Header", debugHeader.toString());
servletResponse.addHeader(X_ZUUL_DEBUG_HEADER, debugHeader.toString());
}
}
List<Pair<String, String>> zuulResponseHeaders = context.getZuulResponseHeaders();
@@ -237,4 +250,4 @@ public class SendResponseFilter extends ZuulFilter {
return value <= Integer.MAX_VALUE && value >= Integer.MIN_VALUE;
}
}
}

View File

@@ -25,7 +25,13 @@ import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.constants.ZuulConstants;
import com.netflix.zuul.context.RequestContext;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.DEBUG_FILTER_ORDER;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
/**
* Pre {@link ZuulFilter} that sets {@link RequestContext} debug attributes to true if
* the "debug" request parameter is set.
*
* @author Spencer Gibb
*/
public class DebugFilter extends ZuulFilter {
@@ -38,12 +44,12 @@ public class DebugFilter extends ZuulFilter {
@Override
public String filterType() {
return "pre";
return PRE_TYPE;
}
@Override
public int filterOrder() {
return 1;
return DEBUG_FILTER_ORDER;
}
@Override

View File

@@ -20,10 +20,6 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Map.Entry;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
@@ -46,8 +42,13 @@ import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.http.HttpServletRequestWrapper;
import com.netflix.zuul.http.ServletInputStreamWrapper;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.FORM_BODY_WRAPPER_FILTER_ORDER;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
/**
* @author Spencer Gibb
* Pre {@link ZuulFilter} that parses form data and reencodes it for downstream services
*
* @author Dave Syer
*/
public class FormBodyWrapperFilter extends ZuulFilter {
@@ -69,12 +70,12 @@ public class FormBodyWrapperFilter extends ZuulFilter {
@Override
public String filterType() {
return "pre";
return PRE_TYPE;
}
@Override
public int filterOrder() {
return -1;
return FORM_BODY_WRAPPER_FILTER_ORDER;
}
@Override

View File

@@ -21,24 +21,50 @@ import java.net.URL;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelper;
import org.springframework.cloud.netflix.zuul.filters.Route;
import org.springframework.cloud.netflix.zuul.filters.RouteLocator;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.cloud.netflix.zuul.util.RequestUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.util.StringUtils;
import org.springframework.web.util.UrlPathHelper;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.constants.ZuulHeaders;
import com.netflix.zuul.context.RequestContext;
import lombok.extern.apachecommons.CommonsLog;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.FORWARD_LOCATION_PREFIX;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.FORWARD_TO_KEY;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.HTTPS_PORT;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.HTTPS_SCHEME;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.HTTP_PORT;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.HTTP_SCHEME;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_DECORATION_FILTER_ORDER;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PROXY_KEY;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.REQUEST_URI_KEY;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.RETRYABLE_KEY;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVICE_HEADER;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVICE_ID_HEADER;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVICE_ID_KEY;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.X_FORWARDED_FOR_HEADER;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.X_FORWARDED_HOST_HEADER;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.X_FORWARDED_PORT_HEADER;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.X_FORWARDED_PREFIX_HEADER;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.X_FORWARDED_PROTO_HEADER;
@CommonsLog
public class PreDecorationFilter extends ZuulFilter {
public static final int FILTER_ORDER = 5;
private static final Log log = LogFactory.getLog(PreDecorationFilter.class);
/**
* @deprecated use {@link FilterConstants#PRE_DECORATION_FILTER_ORDER}
*/
@Deprecated
public static final int FILTER_ORDER = PRE_DECORATION_FILTER_ORDER;
private RouteLocator routeLocator;
@@ -61,20 +87,19 @@ public class PreDecorationFilter extends ZuulFilter {
@Override
public int filterOrder() {
return FILTER_ORDER;
return PRE_DECORATION_FILTER_ORDER;
}
@Override
public String filterType() {
return "pre";
return PRE_TYPE;
}
@Override
public boolean shouldFilter() {
RequestContext ctx = RequestContext.getCurrentContext();
return !ctx.containsKey("forward.to") // a filter has already forwarded
&& !ctx.containsKey("serviceId"); // a filter has already determined
// serviceId
return !ctx.containsKey(FORWARD_TO_KEY) // a filter has already forwarded
&& !ctx.containsKey(SERVICE_ID_KEY); // a filter has already determined serviceId
}
@Override
@@ -85,8 +110,8 @@ public class PreDecorationFilter extends ZuulFilter {
if (route != null) {
String location = route.getLocation();
if (location != null) {
ctx.put("requestURI", route.getPath());
ctx.put("proxy", route.getId());
ctx.put(REQUEST_URI_KEY, route.getPath());
ctx.put(PROXY_KEY, route.getId());
if (!route.isCustomSensitiveHeaders()) {
this.proxyRequestHelper
.addIgnoredHeaders(this.properties.getSensitiveHeaders().toArray(new String[0]));
@@ -96,28 +121,28 @@ public class PreDecorationFilter extends ZuulFilter {
}
if (route.getRetryable() != null) {
ctx.put("retryable", route.getRetryable());
ctx.put(RETRYABLE_KEY, route.getRetryable());
}
if (location.startsWith("http:") || location.startsWith("https:")) {
if (location.startsWith(HTTP_SCHEME+":") || location.startsWith(HTTPS_SCHEME+":")) {
ctx.setRouteHost(getUrl(location));
ctx.addOriginResponseHeader("X-Zuul-Service", location);
ctx.addOriginResponseHeader(SERVICE_HEADER, location);
}
else if (location.startsWith("forward:")) {
ctx.set("forward.to",
StringUtils.cleanPath(location.substring("forward:".length()) + route.getPath()));
else if (location.startsWith(FORWARD_LOCATION_PREFIX)) {
ctx.set(FORWARD_TO_KEY,
StringUtils.cleanPath(location.substring(FORWARD_LOCATION_PREFIX.length()) + route.getPath()));
ctx.setRouteHost(null);
return null;
}
else {
// set serviceId for use in filters.route.RibbonRequest
ctx.set("serviceId", location);
ctx.set(SERVICE_ID_KEY, location);
ctx.setRouteHost(null);
ctx.addOriginResponseHeader("X-Zuul-ServiceId", location);
ctx.addOriginResponseHeader(SERVICE_ID_HEADER, location);
}
if (this.properties.isAddProxyHeaders()) {
addProxyHeaders(ctx, route);
String xforwardedfor = ctx.getRequest().getHeader("X-Forwarded-For");
String xforwardedfor = ctx.getRequest().getHeader(X_FORWARDED_FOR_HEADER);
String remoteAddr = ctx.getRequest().getRemoteAddr();
if (xforwardedfor == null) {
xforwardedfor = remoteAddr;
@@ -125,10 +150,10 @@ public class PreDecorationFilter extends ZuulFilter {
else if (!xforwardedfor.contains(remoteAddr)) { // Prevent duplicates
xforwardedfor += ", " + remoteAddr;
}
ctx.addZuulRequestHeader("X-Forwarded-For", xforwardedfor);
ctx.addZuulRequestHeader(X_FORWARDED_FOR_HEADER, xforwardedfor);
}
if (this.properties.isAddHostHeader()) {
ctx.addZuulRequestHeader("Host", toHostHeader(ctx.getRequest()));
ctx.addZuulRequestHeader(HttpHeaders.HOST, toHostHeader(ctx.getRequest()));
}
}
}
@@ -157,7 +182,7 @@ public class PreDecorationFilter extends ZuulFilter {
}
String forwardURI = fallbackPrefix + fallBackUri;
forwardURI = forwardURI.replaceAll("//", "/");
ctx.set("forward.to", forwardURI);
ctx.set(FORWARD_TO_KEY, forwardURI);
}
return null;
}
@@ -167,30 +192,30 @@ public class PreDecorationFilter extends ZuulFilter {
String host = toHostHeader(request);
String port = String.valueOf(request.getServerPort());
String proto = request.getScheme();
if (hasHeader(request, "X-Forwarded-Host")) {
host = request.getHeader("X-Forwarded-Host") + "," + host;
if (!hasHeader(request, "X-Forwarded-Port")) {
if (hasHeader(request, "X-Forwarded-Proto")) {
if (hasHeader(request, X_FORWARDED_HOST_HEADER)) {
host = request.getHeader(X_FORWARDED_HOST_HEADER) + "," + host;
if (!hasHeader(request, X_FORWARDED_PORT_HEADER)) {
if (hasHeader(request, X_FORWARDED_PROTO_HEADER)) {
StringBuilder builder = new StringBuilder();
for (String previous : StringUtils.commaDelimitedListToStringArray(request.getHeader("X-Forwarded-Proto"))) {
for (String previous : StringUtils.commaDelimitedListToStringArray(request.getHeader(X_FORWARDED_PROTO_HEADER))) {
if (builder.length()>0) {
builder.append(",");
}
builder.append("https".equals(previous) ? "443" : "80");
builder.append(HTTPS_SCHEME.equals(previous) ? HTTPS_PORT : HTTP_PORT);
}
builder.append(",").append(port);
port = builder.toString();
}
} else {
port = request.getHeader("X-Forwarded-Port") + "," + port;
port = request.getHeader(X_FORWARDED_PORT_HEADER) + "," + port;
}
}
if (hasHeader(request, "X-Forwarded-Proto")) {
proto = request.getHeader("X-Forwarded-Proto") + "," + proto;
if (hasHeader(request, X_FORWARDED_PROTO_HEADER)) {
proto = request.getHeader(X_FORWARDED_PROTO_HEADER) + "," + proto;
}
ctx.addZuulRequestHeader("X-Forwarded-Host", host);
ctx.addZuulRequestHeader("X-Forwarded-Port", port);
ctx.addZuulRequestHeader(ZuulHeaders.X_FORWARDED_PROTO, proto);
ctx.addZuulRequestHeader(X_FORWARDED_HOST_HEADER, host);
ctx.addZuulRequestHeader(X_FORWARDED_PORT_HEADER, port);
ctx.addZuulRequestHeader(X_FORWARDED_PROTO_HEADER, proto);
addProxyPrefix(ctx, route);
}
@@ -199,7 +224,7 @@ public class PreDecorationFilter extends ZuulFilter {
}
private void addProxyPrefix(RequestContext ctx, Route route) {
String forwardedPrefix = ctx.getRequest().getHeader("X-Forwarded-Prefix");
String forwardedPrefix = ctx.getRequest().getHeader(X_FORWARDED_PREFIX_HEADER);
String contextPath = ctx.getRequest().getContextPath();
String prefix = StringUtils.hasLength(forwardedPrefix) ? forwardedPrefix
: (StringUtils.hasLength(contextPath) ? contextPath : null);
@@ -217,14 +242,14 @@ public class PreDecorationFilter extends ZuulFilter {
prefix = newPrefixBuilder.toString();
}
if (prefix != null) {
ctx.addZuulRequestHeader("X-Forwarded-Prefix", prefix);
ctx.addZuulRequestHeader(X_FORWARDED_PREFIX_HEADER, prefix);
}
}
private String toHostHeader(HttpServletRequest request) {
int port = request.getServerPort();
if ((port == 80 && "http".equals(request.getScheme()))
|| (port == 443 && "https".equals(request.getScheme()))) {
if ((port == HTTP_PORT && HTTP_SCHEME.equals(request.getScheme()))
|| (port == HTTPS_PORT && HTTPS_SCHEME.equals(request.getScheme()))) {
return request.getServerName();
}
else {

View File

@@ -20,6 +20,9 @@ import com.netflix.zuul.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletRequest;
/**
* A Servlet 3.0 compliant wrapper.
*/
class Servlet30RequestWrapper extends HttpServletRequestWrapper {
private HttpServletRequest request;

View File

@@ -28,7 +28,12 @@ import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.http.HttpServletRequestWrapper;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVLET_30_WRAPPER_FILTER_ORDER;
/**
* Pre {@link ZuulFilter} that wraps requests in a Servlet 3.0 compliant wrapper.
* Zuul's default wrapper is only Servlet 2.5 compliant.
* @author Spencer Gibb
*/
public class Servlet30WrapperFilter extends ZuulFilter {
@@ -49,12 +54,12 @@ public class Servlet30WrapperFilter extends ZuulFilter {
@Override
public String filterType() {
return "pre";
return PRE_TYPE;
}
@Override
public int filterOrder() {
return -2;
return SERVLET_30_WRAPPER_FILTER_ORDER;
}
@Override

View File

@@ -26,6 +26,9 @@ import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.http.HttpServletRequestWrapper;
import com.netflix.zuul.http.ZuulServlet;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVLET_DETECTION_FILTER_ORDER;
/**
* Detects whether a request is ran through the {@link DispatcherServlet} or {@link ZuulServlet}.
* The purpose was to detect this up-front at the very beginning of Zuul filter processing
@@ -41,7 +44,7 @@ public class ServletDetectionFilter extends ZuulFilter {
@Override
public String filterType() {
return "pre";
return PRE_TYPE;
}
/**
@@ -50,7 +53,7 @@ public class ServletDetectionFilter extends ZuulFilter {
*/
@Override
public int filterOrder() {
return -3;
return SERVLET_DETECTION_FILTER_ORDER;
}
@Override

View File

@@ -22,6 +22,7 @@ import java.net.URI;
import java.util.List;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.cloud.netflix.zuul.filters.route.support.AbstractRibbonCommand;
import org.springframework.http.HttpMethod;
import org.springframework.util.MultiValueMap;
import com.netflix.client.config.IClientConfig;
import com.netflix.client.http.HttpRequest;
@@ -68,7 +69,7 @@ public class RestClientRibbonCommand extends AbstractRibbonCommand<RestClient, H
protected HttpRequest createRequest() throws Exception {
final InputStream requestEntity;
// ApacheHttpClient4Handler does not support body in delete requests
if (getContext().getMethod().equalsIgnoreCase("DELETE")) {
if (getContext().getMethod().equalsIgnoreCase(HttpMethod.DELETE.toString())) {
requestEntity = null;
} else {
requestEntity = this.context.getRequestEntity();

View File

@@ -24,6 +24,8 @@ import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.netflix.ribbon.support.RibbonRequestCustomizer;
import org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelper;
import org.springframework.cloud.netflix.zuul.util.ZuulRuntimeException;
@@ -37,11 +39,24 @@ import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import lombok.extern.apachecommons.CommonsLog;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.REQUEST_ENTITY_KEY;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.RETRYABLE_KEY;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.RIBBON_ROUTING_FILTER_ORDER;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.ROUTE_TYPE;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVICE_ID_KEY;
@CommonsLog
/**
* Route {@link ZuulFilter} that uses Ribbon, Hystrix and pluggable http clients to send requests.
* ServiceIds are found in the {@link RequestContext} attribute {@link org.springframework.cloud.netflix.zuul.filters.support.FilterConstants#SERVICE_ID_KEY}.
*
* @author Spencer Gibb
* @author Dave Syer
* @author Ryan Baxter
*/
public class RibbonRoutingFilter extends ZuulFilter {
private static final Log log = LogFactory.getLog(RibbonRoutingFilter.class);
protected ProxyRequestHelper helper;
protected RibbonCommandFactory<?> ribbonCommandFactory;
protected List<RibbonRequestCustomizer> requestCustomizers;
@@ -67,18 +82,18 @@ public class RibbonRoutingFilter extends ZuulFilter {
@Override
public String filterType() {
return "route";
return ROUTE_TYPE;
}
@Override
public int filterOrder() {
return 10;
return RIBBON_ROUTING_FILTER_ORDER;
}
@Override
public boolean shouldFilter() {
RequestContext ctx = RequestContext.getCurrentContext();
return (ctx.getRouteHost() == null && ctx.get("serviceId") != null
return (ctx.getRouteHost() == null && ctx.get(SERVICE_ID_KEY) != null
&& ctx.sendZuulResponse());
}
@@ -113,8 +128,8 @@ public class RibbonRoutingFilter extends ZuulFilter {
context.setChunkedRequestBody();
}
String serviceId = (String) context.get("serviceId");
Boolean retryable = (Boolean) context.get("retryable");
String serviceId = (String) context.get(SERVICE_ID_KEY);
Boolean retryable = (Boolean) context.get(RETRYABLE_KEY);
String uri = this.helper.buildZuulRequestURI(request);
@@ -182,7 +197,7 @@ public class RibbonRoutingFilter extends ZuulFilter {
InputStream requestEntity = null;
try {
requestEntity = (InputStream) RequestContext.getCurrentContext()
.get("requestEntity");
.get(REQUEST_ENTITY_KEY);
if (requestEntity == null) {
requestEntity = request.getInputStream();
}

View File

@@ -23,7 +23,15 @@ import org.springframework.util.ReflectionUtils;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.FORWARD_TO_KEY;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.ROUTE_TYPE;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SEND_FORWARD_FILTER_ORDER;
/**
* Route {@link ZuulFilter} that forwards requests using the {@link RequestDispatcher}.
* Forwarding location is located in the {@link RequestContext} attribute {@link org.springframework.cloud.netflix.zuul.filters.support.FilterConstants#FORWARD_TO_KEY}.
* Useful for forwarding to endpoints in the current application.
*
* @author Dave Syer
*/
public class SendForwardFilter extends ZuulFilter {
@@ -32,18 +40,18 @@ public class SendForwardFilter extends ZuulFilter {
@Override
public String filterType() {
return "route";
return ROUTE_TYPE;
}
@Override
public int filterOrder() {
return 500;
return SEND_FORWARD_FILTER_ORDER;
}
@Override
public boolean shouldFilter() {
RequestContext ctx = RequestContext.getCurrentContext();
return ctx.containsKey("forward.to")
return ctx.containsKey(FORWARD_TO_KEY)
&& !ctx.getBoolean(SEND_FORWARD_FILTER_RAN, false);
}
@@ -51,7 +59,7 @@ public class SendForwardFilter extends ZuulFilter {
public Object run() {
try {
RequestContext ctx = RequestContext.getCurrentContext();
String path = (String) ctx.get("forward.to");
String path = (String) ctx.get(FORWARD_TO_KEY);
RequestDispatcher dispatcher = ctx.getRequest().getRequestDispatcher(path);
if (dispatcher != null) {
ctx.set(SEND_FORWARD_FILTER_RAN, true);

View File

@@ -19,7 +19,6 @@ package org.springframework.cloud.netflix.zuul.filters.route;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.charset.Charset;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
@@ -36,6 +35,8 @@ import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.Header;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
@@ -80,11 +81,22 @@ import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.constants.ZuulConstants;
import com.netflix.zuul.context.RequestContext;
import lombok.extern.apachecommons.CommonsLog;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.HTTPS_SCHEME;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.HTTP_SCHEME;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.ROUTE_TYPE;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SIMPLE_HOST_ROUTING_FILTER_ORDER;
@CommonsLog
/**
* Route {@link ZuulFilter} that sends requests to predetermined URLs via apache {@link HttpClient}.
* URLs are found in {@link RequestContext#getRouteHost()}.
*
* @author Spencer Gibb
* @author Dave Syer
*/
public class SimpleHostRoutingFilter extends ZuulFilter {
private static final Log log = LogFactory.getLog(SimpleHostRoutingFilter.class);
private static final DynamicIntProperty SOCKET_TIMEOUT = DynamicPropertyFactory
.getInstance()
.getIntProperty(ZuulConstants.ZUUL_HOST_SOCKET_TIMEOUT_MILLIS, 10000);
@@ -148,12 +160,12 @@ public class SimpleHostRoutingFilter extends ZuulFilter {
@Override
public String filterType() {
return "route";
return ROUTE_TYPE;
}
@Override
public int filterOrder() {
return 100;
return SIMPLE_HOST_ROUTING_FILTER_ORDER;
}
@Override
@@ -212,13 +224,13 @@ public class SimpleHostRoutingFilter extends ZuulFilter {
RegistryBuilder<ConnectionSocketFactory> registryBuilder = RegistryBuilder
.<ConnectionSocketFactory> create()
.register("http", PlainConnectionSocketFactory.INSTANCE);
.register(HTTP_SCHEME, PlainConnectionSocketFactory.INSTANCE);
if (this.sslHostnameValidationEnabled) {
registryBuilder.register("https",
registryBuilder.register(HTTPS_SCHEME,
new SSLConnectionSocketFactory(sslContext));
}
else {
registryBuilder.register("https", new SSLConnectionSocketFactory(
registryBuilder.register(HTTPS_SCHEME, new SSLConnectionSocketFactory(
sslContext, NoopHostnameVerifier.INSTANCE));
}
final Registry<ConnectionSocketFactory> registry = registryBuilder.build();

View File

@@ -0,0 +1,209 @@
/*
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.springframework.cloud.netflix.zuul.filters.support;
import com.netflix.zuul.ZuulFilter;
import org.springframework.cloud.netflix.zuul.filters.pre.DebugFilter;
import org.springframework.cloud.netflix.zuul.filters.pre.Servlet30WrapperFilter;
import org.springframework.cloud.netflix.zuul.filters.route.SendForwardFilter;
/**
* @author Spencer Gibb
*/
public interface FilterConstants {
// KEY constants -----------------------------------
/**
* Zuul {@link com.netflix.zuul.context.RequestContext} key for use in {@link org.springframework.cloud.netflix.zuul.filters.route.SendForwardFilter}
*/
String FORWARD_TO_KEY = "forward.to";
/**
* Zuul {@link com.netflix.zuul.context.RequestContext} key for use in TODO: determine use
*/
String PROXY_KEY = "proxy";
/**
* Zuul {@link com.netflix.zuul.context.RequestContext} key for use in {@link org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter}
*/
String REQUEST_ENTITY_KEY = "requestEntity";
/**
* Zuul {@link com.netflix.zuul.context.RequestContext} key for use in TODO: determine use
*/
String REQUEST_URI_KEY = "requestURI";
/**
* Zuul {@link com.netflix.zuul.context.RequestContext} key for use in {@link org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter}
*/
String RETRYABLE_KEY = "retryable";
/**
* Zuul {@link com.netflix.zuul.context.RequestContext} key for use in {@link org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter}
*/
String ROUTING_DEBUG_KEY = "routingDebug";
/**
* Zuul {@link com.netflix.zuul.context.RequestContext} key for use in {@link org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter}
*/
String SERVICE_ID_KEY = "serviceId";
// ORDER constants -----------------------------------
/**
* Filter Order for {@link DebugFilter#filterOrder()}
*/
int DEBUG_FILTER_ORDER = 1;
/**
* Filter Order for {@link org.springframework.cloud.netflix.zuul.filters.pre.FormBodyWrapperFilter#filterOrder()}
*/
int FORM_BODY_WRAPPER_FILTER_ORDER = -1;
/**
* Filter Order for {@link org.springframework.cloud.netflix.zuul.filters.pre.PreDecorationFilter}
*/
int PRE_DECORATION_FILTER_ORDER = 5;
/**
* Filter Order for {@link org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter#filterOrder()}
*/
int RIBBON_ROUTING_FILTER_ORDER = 10;
/**
* Filter Order for {@link org.springframework.cloud.netflix.zuul.filters.post.SendErrorFilter#filterOrder()}
*/
int SEND_ERROR_FILTER_ORDER = 0;
/**
* Filter Order for {@link SendForwardFilter#filterOrder()}
*/
int SEND_FORWARD_FILTER_ORDER = 500;
/**
* Filter Order for {@link org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter#filterOrder()}
*/
int SEND_RESPONSE_FILTER_ORDER = 1000;
/**
* Filter Order for {@link org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilter#filterOrder()}
*/
int SIMPLE_HOST_ROUTING_FILTER_ORDER = 100;
/**
* filter order for {@link Servlet30WrapperFilter#filterOrder()}
*/
int SERVLET_30_WRAPPER_FILTER_ORDER = -2;
/**
* filter order for {@link org.springframework.cloud.netflix.zuul.filters.pre.ServletDetectionFilter#filterOrder()}
*/
int SERVLET_DETECTION_FILTER_ORDER = -3;
// Zuul Filter TYPE constants -----------------------------------
/**
* {@link ZuulFilter#filterType()} error type.
*/
String ERROR_TYPE = "error";
/**
* {@link ZuulFilter#filterType()} post type.
*/
String POST_TYPE = "post";
/**
* {@link ZuulFilter#filterType()} pre type.
*/
String PRE_TYPE = "pre";
/**
* {@link ZuulFilter#filterType()} route type.
*/
String ROUTE_TYPE = "route";
// OTHER constants -----------------------------------
/**
* Zuul {@link com.netflix.zuul.context.RequestContext} key for use in {@link org.springframework.cloud.netflix.zuul.filters.route.SendForwardFilter}
*/
String FORWARD_LOCATION_PREFIX = "forward:";
/**
* default http port
*/
int HTTP_PORT = 80;
/**
* default https port
*/
int HTTPS_PORT = 443;
/**
* http url scheme
*/
String HTTP_SCHEME = "http";
/**
* https url scheme
*/
String HTTPS_SCHEME = "https";
// HEADER constants -----------------------------------
/**
* X-* Header for the matching url. Used when routes use a url rather than serviceId
*/
String SERVICE_HEADER = "X-Zuul-Service";
/**
* X-* Header for the matching serviceId
*/
String SERVICE_ID_HEADER = "X-Zuul-ServiceId";
/**
* X-Forwarded-For Header
*/
String X_FORWARDED_FOR_HEADER = "X-Forwarded-For";
/**
* X-Forwarded-Host Header
*/
String X_FORWARDED_HOST_HEADER = "X-Forwarded-Host";
/**
* X-Forwarded-Prefix Header
*/
String X_FORWARDED_PREFIX_HEADER = "X-Forwarded-Prefix";
/**
* X-Forwarded-Port Header
*/
String X_FORWARDED_PORT_HEADER = "X-Forwarded-Port";
/**
* X-Forwarded-Proto Header
*/
String X_FORWARDED_PROTO_HEADER = "X-Forwarded-Proto";
/**
* X-Zuul-Debug Header
*/
String X_ZUUL_DEBUG_HEADER = "X-Zuul-Debug-Header";
}

View File

@@ -17,12 +17,8 @@
package org.springframework.cloud.netflix.zuul.filters.post;
import java.io.ByteArrayInputStream;
import javax.servlet.http.HttpServletRequest;
import com.netflix.config.ConfigurationManager;
import com.netflix.zuul.constants.ZuulConstants;
import com.netflix.zuul.context.Debug;
import com.netflix.zuul.context.RequestContext;
import javax.servlet.http.HttpServletRequest;
import org.junit.After;
import org.junit.Before;
@@ -33,9 +29,15 @@ import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.web.util.WebUtils;
import com.netflix.config.ConfigurationManager;
import com.netflix.zuul.constants.ZuulConstants;
import com.netflix.zuul.context.Debug;
import com.netflix.zuul.context.RequestContext;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.X_ZUUL_DEBUG_HEADER;
/**
* @author Spencer Gibb
@@ -76,7 +78,7 @@ public class SendResponseFilterTests {
filter.run();
String debugHeader = RequestContext.getCurrentContext().getResponse()
.getHeader("X-Zuul-Debug-Header");
.getHeader(X_ZUUL_DEBUG_HEADER);
assertThat("wrong debug header", debugHeader, equalTo("[[[test]]]"));
}
@@ -129,4 +131,4 @@ public class SendResponseFilterTests {
return filter;
}
}
}

View File

@@ -39,6 +39,9 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.MockitoAnnotations.initMocks;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.FORWARD_TO_KEY;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.REQUEST_URI_KEY;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVICE_ID_KEY;
/**
* @author Dave Syer
@@ -80,13 +83,13 @@ public class PreDecorationFilterTests {
@Test
public void skippedIfServiceIdSet() throws Exception {
RequestContext.getCurrentContext().set("serviceId", "myservice");
RequestContext.getCurrentContext().set(SERVICE_ID_KEY, "myservice");
assertEquals(false, this.filter.shouldFilter());
}
@Test
public void skippedIfForwardToSet() throws Exception {
RequestContext.getCurrentContext().set("forward.to", "myconteext");
RequestContext.getCurrentContext().set(FORWARD_TO_KEY, "myconteext");
assertEquals(false, this.filter.shouldFilter());
}
@@ -179,7 +182,7 @@ public class PreDecorationFilterTests {
new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null));
this.filter.run();
RequestContext ctx = RequestContext.getCurrentContext();
assertEquals("/foo/1", ctx.get("requestURI"));
assertEquals("/foo/1", ctx.get(REQUEST_URI_KEY));
assertEquals("localhost", ctx.getZuulRequestHeaders().get("x-forwarded-host"));
assertEquals("80", ctx.getZuulRequestHeaders().get("x-forwarded-port"));
assertEquals("http", ctx.getZuulRequestHeaders().get("x-forwarded-proto"));
@@ -202,7 +205,7 @@ public class PreDecorationFilterTests {
new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null));
this.filter.run();
RequestContext ctx = RequestContext.getCurrentContext();
assertEquals("/foo/1", ctx.get("requestURI"));
assertEquals("/foo/1", ctx.get(REQUEST_URI_KEY));
assertEquals("localhost", ctx.getZuulRequestHeaders().get("x-forwarded-host"));
assertEquals("80", ctx.getZuulRequestHeaders().get("x-forwarded-port"));
assertEquals("http", ctx.getZuulRequestHeaders().get("x-forwarded-proto"));
@@ -223,7 +226,7 @@ public class PreDecorationFilterTests {
new ZuulRoute("foo", "/api/foo/**", "foo", null, false, null, null));
this.filter.run();
RequestContext ctx = RequestContext.getCurrentContext();
assertEquals("/api/foo/1", ctx.get("requestURI"));
assertEquals("/api/foo/1", ctx.get(REQUEST_URI_KEY));
assertEquals("localhost", ctx.getZuulRequestHeaders().get("x-forwarded-host"));
assertEquals("80", ctx.getZuulRequestHeaders().get("x-forwarded-port"));
assertEquals("http", ctx.getZuulRequestHeaders().get("x-forwarded-proto"));
@@ -243,7 +246,7 @@ public class PreDecorationFilterTests {
new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null));
this.filter.run();
RequestContext ctx = RequestContext.getCurrentContext();
assertEquals("/foo/1", ctx.get("requestURI"));
assertEquals("/foo/1", ctx.get(REQUEST_URI_KEY));
assertEquals("localhost", ctx.getZuulRequestHeaders().get("x-forwarded-host"));
assertEquals("80", ctx.getZuulRequestHeaders().get("x-forwarded-port"));
assertEquals("http", ctx.getZuulRequestHeaders().get("x-forwarded-proto"));
@@ -263,7 +266,7 @@ public class PreDecorationFilterTests {
new ZuulRoute("foo", "/api/foo/**", "foo", null, false, null, null));
this.filter.run();
RequestContext ctx = RequestContext.getCurrentContext();
assertEquals("/api/foo/1", ctx.get("requestURI"));
assertEquals("/api/foo/1", ctx.get(REQUEST_URI_KEY));
assertEquals("localhost", ctx.getZuulRequestHeaders().get("x-forwarded-host"));
assertEquals("80", ctx.getZuulRequestHeaders().get("x-forwarded-port"));
assertEquals("http", ctx.getZuulRequestHeaders().get("x-forwarded-proto"));
@@ -284,7 +287,7 @@ public class PreDecorationFilterTests {
new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null));
this.filter.run();
RequestContext ctx = RequestContext.getCurrentContext();
assertEquals("/foo/1", ctx.get("requestURI"));
assertEquals("/foo/1", ctx.get(REQUEST_URI_KEY));
assertEquals("localhost", ctx.getZuulRequestHeaders().get("x-forwarded-host"));
assertEquals("80", ctx.getZuulRequestHeaders().get("x-forwarded-port"));
assertEquals("http", ctx.getZuulRequestHeaders().get("x-forwarded-proto"));
@@ -303,7 +306,7 @@ public class PreDecorationFilterTests {
new ZuulRoute("foo", "/foo/**", null, "forward:/foo", true, null, null));
this.filter.run();
RequestContext ctx = RequestContext.getCurrentContext();
assertEquals("/foo/1", ctx.get("forward.to"));
assertEquals("/foo/1", ctx.get(FORWARD_TO_KEY));
}
@Test
@@ -313,7 +316,7 @@ public class PreDecorationFilterTests {
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"));
assertEquals("/bar/foo/1", ctx.get(FORWARD_TO_KEY));
}
@Test
@@ -324,7 +327,7 @@ public class PreDecorationFilterTests {
this.routeLocator.addRoute("/foo/**", "foo");
this.filter.run();
RequestContext ctx = RequestContext.getCurrentContext();
assertEquals("/1", ctx.get("requestURI"));
assertEquals("/1", ctx.get(REQUEST_URI_KEY));
assertEquals("localhost", ctx.getZuulRequestHeaders().get("x-forwarded-host"));
assertEquals("http", ctx.getZuulRequestHeaders().get("x-forwarded-proto"));
assertEquals("/api/foo", ctx.getZuulRequestHeaders().get("x-forwarded-prefix"));
@@ -343,7 +346,7 @@ public class PreDecorationFilterTests {
this.filter.run();
RequestContext ctx = RequestContext.getCurrentContext();
assertEquals("/api/bar/1", ctx.get("forward.to"));
assertEquals("/api/bar/1", ctx.get(FORWARD_TO_KEY));
}
@Test
@@ -361,7 +364,7 @@ public class PreDecorationFilterTests {
this.filter.run();
RequestContext ctx = RequestContext.getCurrentContext();
assertEquals("/special/api/bar/1", ctx.get("forward.to"));
assertEquals("/special/api/bar/1", ctx.get(FORWARD_TO_KEY));
}
@Test
@@ -380,7 +383,7 @@ public class PreDecorationFilterTests {
this.filter.run();
assertEquals("/api/bar/1", ctx.get("forward.to"));
assertEquals("/api/bar/1", ctx.get(FORWARD_TO_KEY));
}
@Test
@@ -402,7 +405,7 @@ public class PreDecorationFilterTests {
this.filter.run();
assertEquals("/special/api/bar/1", ctx.get("forward.to"));
assertEquals("/special/api/bar/1", ctx.get(FORWARD_TO_KEY));
}
@Test
@@ -425,7 +428,7 @@ public class PreDecorationFilterTests {
this.filter.run();
assertEquals("/special/api/bar/1", ctx.get("forward.to"));
assertEquals("/special/api/bar/1", ctx.get(FORWARD_TO_KEY));
}
@Test
@@ -545,7 +548,7 @@ public class PreDecorationFilterTests {
this.routeLocator.addRoute("/foo/**", "foo");
RequestContext ctx = RequestContext.getCurrentContext();
this.filter.run();
String decodedRequestURI = (String) ctx.get("requestURI");
String decodedRequestURI = (String) ctx.get(REQUEST_URI_KEY);
assertTrue(decodedRequestURI.equals("/oléדרעק"));
}

View File

@@ -28,6 +28,7 @@ import com.netflix.zuul.context.RequestContext;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.FORWARD_TO_KEY;
/**
* @author Dave Syer
@@ -56,7 +57,7 @@ public class SendForwardFilterTests {
RequestContext context = new RequestContext();
context.setRequest(request);
context.setResponse(new MockHttpServletResponse());
context.set("forward.to", "/foo");
context.set(FORWARD_TO_KEY, "/foo");
RequestContext.testSetCurrentContext(context);
SendForwardFilter filter = new SendForwardFilter();
return filter;