From e47c3ab6b8c271afcaaa23e81dfd59d86be08245 Mon Sep 17 00:00:00 2001 From: lym-ifae Date: Tue, 16 Jul 2019 17:54:27 +0800 Subject: [PATCH] Add support for excluding some URLs in Web Servlet CommonFilter (#914) (cherry picked from commit 7dd20dd2023d8e4edee13cc108a7d0373b157eed) --- .../sentinel-web-servlet/README.md | 2 ++ .../adapter/servlet/CommonFilter.java | 24 +++++++++---------- .../adapter/servlet/CommonFilterTest.java | 21 +++++++++++++++- .../adapter/servlet/TestController.java | 5 ++++ 4 files changed, 39 insertions(+), 13 deletions(-) diff --git a/sentinel-adapter/sentinel-web-servlet/README.md b/sentinel-adapter/sentinel-web-servlet/README.md index f73451a3c7..f3e1375125 100755 --- a/sentinel-adapter/sentinel-web-servlet/README.md +++ b/sentinel-adapter/sentinel-web-servlet/README.md @@ -51,6 +51,8 @@ block handler (the `UrlBlockHandler` interface) and register to `WebCallbackMana The `UrlCleaner` interface is designed for clean and unify the URL resource. For REST APIs, you have to clean the URL resource (e.g. `/foo/1` and `/foo/2` -> `/foo/:id`), or the amount of context and resources will exceed the threshold. +The `UrlCleaner` interface can also exclude unused URLs(e.g. `/exclude/1` -> `/exclude/:id` -> `""`). +The URLs will be filtered and not be resource in this way. `RequestOriginParser` interface is useful for extracting request origin (e.g. IP or appName from HTTP Header) from HTTP request. You can implement your own `RequestOriginParser` and register to `WebCallbackManager`. \ No newline at end of file diff --git a/sentinel-adapter/sentinel-web-servlet/src/main/java/com/alibaba/csp/sentinel/adapter/servlet/CommonFilter.java b/sentinel-adapter/sentinel-web-servlet/src/main/java/com/alibaba/csp/sentinel/adapter/servlet/CommonFilter.java index f24bbe55e2..8318f17500 100755 --- a/sentinel-adapter/sentinel-web-servlet/src/main/java/com/alibaba/csp/sentinel/adapter/servlet/CommonFilter.java +++ b/sentinel-adapter/sentinel-web-servlet/src/main/java/com/alibaba/csp/sentinel/adapter/servlet/CommonFilter.java @@ -73,19 +73,19 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha target = urlCleaner.clean(target); } - // Parse the request origin using registered origin parser. - String origin = parseOrigin(sRequest); - - ContextUtil.enter(target, origin); - entry = SphU.entry(target, EntryType.IN); - - - // Add method specification if necessary - if (httpMethodSpecify) { - methodEntry = SphU.entry(sRequest.getMethod().toUpperCase() + COLON + target, - EntryType.IN); + // If you intend to exclude some URLs, you can convert the URLs to the empty string "" + // in the UrlCleaner implementation. + if (!StringUtil.isEmpty(target)) { + // Parse the request origin using registered origin parser. + String origin = parseOrigin(sRequest); + ContextUtil.enter(target, origin); + entry = SphU.entry(target, EntryType.IN); + // Add method specification if necessary + if (httpMethodSpecify) { + methodEntry = SphU.entry(sRequest.getMethod().toUpperCase() + COLON + target, + EntryType.IN); + } } - chain.doFilter(request, response); } catch (BlockException e) { HttpServletResponse sResponse = (HttpServletResponse) response; diff --git a/sentinel-adapter/sentinel-web-servlet/src/test/java/com/alibaba/csp/sentinel/adapter/servlet/CommonFilterTest.java b/sentinel-adapter/sentinel-web-servlet/src/test/java/com/alibaba/csp/sentinel/adapter/servlet/CommonFilterTest.java index bd42a89b06..b271142ab7 100644 --- a/sentinel-adapter/sentinel-web-servlet/src/test/java/com/alibaba/csp/sentinel/adapter/servlet/CommonFilterTest.java +++ b/sentinel-adapter/sentinel-web-servlet/src/test/java/com/alibaba/csp/sentinel/adapter/servlet/CommonFilterTest.java @@ -89,7 +89,7 @@ public void testCommonFilterMiscellaneous() throws Exception { // Test for url cleaner. testUrlCleaner(); - + testUrlExclusion(); testCustomOriginParser(); } @@ -139,6 +139,25 @@ public String clean(String originUrl) { WebCallbackManager.setUrlCleaner(new DefaultUrlCleaner()); } + private void testUrlExclusion() throws Exception { + final String excludePrefix = "/exclude/"; + String url = excludePrefix + 1; + WebCallbackManager.setUrlCleaner(new UrlCleaner() { + @Override + public String clean(String originUrl) { + if(originUrl.startsWith(excludePrefix)) { + return ""; + } + return originUrl; + } + }); + this.mvc.perform(get(url).accept(MediaType.TEXT_PLAIN)) + .andExpect(status().isOk()) + .andExpect(content().string("Exclude 1")); + assertNull(ClusterBuilderSlot.getClusterNode(url)); + WebCallbackManager.setUrlCleaner(new DefaultUrlCleaner()); + } + private void testCustomOriginParser() throws Exception { String url = "/hello"; String limitOrigin = "userA"; diff --git a/sentinel-adapter/sentinel-web-servlet/src/test/java/com/alibaba/csp/sentinel/adapter/servlet/TestController.java b/sentinel-adapter/sentinel-web-servlet/src/test/java/com/alibaba/csp/sentinel/adapter/servlet/TestController.java index 6221190b67..dce4e2ebfe 100644 --- a/sentinel-adapter/sentinel-web-servlet/src/test/java/com/alibaba/csp/sentinel/adapter/servlet/TestController.java +++ b/sentinel-adapter/sentinel-web-servlet/src/test/java/com/alibaba/csp/sentinel/adapter/servlet/TestController.java @@ -39,4 +39,9 @@ public String apiError() { public String apiFoo(@PathVariable("id") Long id) { return "Hello " + id; } + + @GetMapping("/exclude/{id}") + public String apiExclude(@PathVariable("id") Long id) { + return "Exclude " + id; + } }