org/springframework/cloud/netflix/zuul/filters/java
filter | type | order | desc |
---|---|---|---|
ServletDetectionFilter | pre | -3 | 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 and rely on this information in all filters.RequestContext is used such that the information is accessible to classes which do not have a request reference. |
Servlet30WrapperFilter | pre | -2 | zuul適配servlet request |
FormBodyWrapperFilter | pre | -1 | 將上下文中ZuulRequestHeaders的content-type設置成了帶文件類型+boundary的形式. |
DebugFilter | pre | 1 | debug路由標識 |
PreDecorationFilter | pre | 5 | 補充頭信息,好比是有路由配置的,則添加proxy標識爲路由id,對於非http,https以及不是forward的標識serviceId |
filter | type | order | desc |
---|---|---|---|
SendErrorFilter | post | 0 | 當上下文內含error.status_code且沒通過本filter時生效,補充上下文內error信息 |
SendResponseFilter | post | 1000 | 返回內容 |
filter | type | order | desc |
---|---|---|---|
RibbonRoutingFilter | route | 10 | 在上下文中沒有routeHost且sendZuulResponse爲true,並且serviceId值不爲空時生效. |
SimpleHostRoutingFilter | route | 100 | 在上下文中存在routeHost且sendZuulResponse爲true時生效 |
SendForwardFilter | route | 500 | 存在forward.to以及sendForwardFilter.ran爲false時生效 |
spring-cloud-netflix-core-1.2.6.RELEASE-sources.jar!/org/springframework/cloud/netflix/zuul/filters/pre/PreDecorationFilter.javaspring
public class PreDecorationFilter extends ZuulFilter { public static final int FILTER_ORDER = 5; private RouteLocator routeLocator; private String dispatcherServletPath; private ZuulProperties properties; private UrlPathHelper urlPathHelper = new UrlPathHelper(); private ProxyRequestHelper proxyRequestHelper; public PreDecorationFilter(RouteLocator routeLocator, String dispatcherServletPath, ZuulProperties properties, ProxyRequestHelper proxyRequestHelper) { this.routeLocator = routeLocator; this.properties = properties; this.urlPathHelper.setRemoveSemicolonContent(properties.isRemoveSemicolonContent()); this.dispatcherServletPath = dispatcherServletPath; this.proxyRequestHelper = proxyRequestHelper; } @Override public int filterOrder() { return FILTER_ORDER; } @Override public String filterType() { return "pre"; } @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 } @Override public Object run() { RequestContext ctx = RequestContext.getCurrentContext(); final String requestURI = this.urlPathHelper.getPathWithinApplication(ctx.getRequest()); Route route = this.routeLocator.getMatchingRoute(requestURI); if (route != null) { String location = route.getLocation(); if (location != null) { ctx.put("requestURI", route.getPath()); ctx.put("proxy", route.getId()); if (!route.isCustomSensitiveHeaders()) { this.proxyRequestHelper .addIgnoredHeaders(this.properties.getSensitiveHeaders().toArray(new String[0])); } else { this.proxyRequestHelper.addIgnoredHeaders(route.getSensitiveHeaders().toArray(new String[0])); } if (route.getRetryable() != null) { ctx.put("retryable", route.getRetryable()); } if (location.startsWith("http:") || location.startsWith("https:")) { ctx.setRouteHost(getUrl(location)); ctx.addOriginResponseHeader("X-Zuul-Service", location); } else if (location.startsWith("forward:")) { ctx.set("forward.to", StringUtils.cleanPath(location.substring("forward:".length()) + route.getPath())); ctx.setRouteHost(null); return null; } else { // set serviceId for use in filters.route.RibbonRequest ctx.set("serviceId", location); ctx.setRouteHost(null); ctx.addOriginResponseHeader("X-Zuul-ServiceId", location); } if (this.properties.isAddProxyHeaders()) { addProxyHeaders(ctx, route); String xforwardedfor = ctx.getRequest().getHeader("X-Forwarded-For"); String remoteAddr = ctx.getRequest().getRemoteAddr(); if (xforwardedfor == null) { xforwardedfor = remoteAddr; } else if (!xforwardedfor.contains(remoteAddr)) { // Prevent duplicates xforwardedfor += ", " + remoteAddr; } ctx.addZuulRequestHeader("X-Forwarded-For", xforwardedfor); } if (this.properties.isAddHostHeader()) { ctx.addZuulRequestHeader("Host", toHostHeader(ctx.getRequest())); } } } else { log.warn("No route found for uri: " + requestURI); String fallBackUri = requestURI; String fallbackPrefix = this.dispatcherServletPath; // default fallback // servlet is // DispatcherServlet if (RequestUtils.isZuulServletRequest()) { // remove the Zuul servletPath from the requestUri log.debug("zuulServletPath=" + this.properties.getServletPath()); fallBackUri = fallBackUri.replaceFirst(this.properties.getServletPath(), ""); log.debug("Replaced Zuul servlet path:" + fallBackUri); } else { // remove the DispatcherServlet servletPath from the requestUri log.debug("dispatcherServletPath=" + this.dispatcherServletPath); fallBackUri = fallBackUri.replaceFirst(this.dispatcherServletPath, ""); log.debug("Replaced DispatcherServlet servlet path:" + fallBackUri); } if (!fallBackUri.startsWith("/")) { fallBackUri = "/" + fallBackUri; } String forwardURI = fallbackPrefix + fallBackUri; forwardURI = forwardURI.replaceAll("//", "/"); ctx.set("forward.to", forwardURI); } return null; } private void addProxyHeaders(RequestContext ctx, Route route) { HttpServletRequest request = ctx.getRequest(); 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")) { StringBuilder builder = new StringBuilder(); for (String previous : StringUtils.commaDelimitedListToStringArray(request.getHeader("X-Forwarded-Proto"))) { if (builder.length()>0) { builder.append(","); } builder.append("https".equals(previous) ? "443" : "80"); } builder.append(",").append(port); port = builder.toString(); } } else { port = request.getHeader("X-Forwarded-Port") + "," + port; } proto = request.getHeader("X-Forwarded-Proto") + "," + proto; } ctx.addZuulRequestHeader("X-Forwarded-Host", host); ctx.addZuulRequestHeader("X-Forwarded-Port", port); ctx.addZuulRequestHeader(ZuulHeaders.X_FORWARDED_PROTO, proto); addProxyPrefix(ctx, route); } private boolean hasHeader(HttpServletRequest request, String name) { return StringUtils.hasLength(request.getHeader(name)); } private void addProxyPrefix(RequestContext ctx, Route route) { String forwardedPrefix = ctx.getRequest().getHeader("X-Forwarded-Prefix"); String contextPath = ctx.getRequest().getContextPath(); String prefix = StringUtils.hasLength(forwardedPrefix) ? forwardedPrefix : (StringUtils.hasLength(contextPath) ? contextPath : null); if (StringUtils.hasText(route.getPrefix())) { StringBuilder newPrefixBuilder = new StringBuilder(); if (prefix != null) { if (prefix.endsWith("/") && route.getPrefix().startsWith("/")) { newPrefixBuilder.append(prefix, 0, prefix.length() - 1); } else { newPrefixBuilder.append(prefix); } } newPrefixBuilder.append(route.getPrefix()); prefix = newPrefixBuilder.toString(); } if (prefix != null) { ctx.addZuulRequestHeader("X-Forwarded-Prefix", prefix); } } private String toHostHeader(HttpServletRequest request) { int port = request.getServerPort(); if ((port == 80 && "http".equals(request.getScheme())) || (port == 443 && "https".equals(request.getScheme()))) { return request.getServerName(); } else { return request.getServerName() + ":" + port; } } private URL getUrl(String target) { try { return new URL(target); } catch (MalformedURLException ex) { throw new IllegalStateException("Target URL is malformed", ex); } } }
想獲取最新內容,請關注微信公衆號app