Update Sentinel Web Servlet integration
- Add RequestOriginParser interface to extract request origin from the HTTP request - Some code refinement Signed-off-by: Eric Zhao <sczyh16@gmail.com>
This commit is contained in:
parent
be43a31dc4
commit
90d5611b23
|
|
@ -1,7 +1,16 @@
|
|||
# Sentinel Web Servlet Filter
|
||||
|
||||
Sentinel provides Servlet filter integration. To use the filter,
|
||||
you can simply configure your `web.xml` with:
|
||||
Sentinel provides Servlet filter integration to enable flow control for web requests. Add the following dependency in `pom.xml` (if you are using Maven):
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-web-servlet</artifactId>
|
||||
<version>x.y.z</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
To use the filter, you can simply configure your `web.xml` with:
|
||||
|
||||
```xml
|
||||
<filter>
|
||||
|
|
@ -20,3 +29,9 @@ If customized block page is set (via `WebServletConfig.setBlockPage(blockPage)`
|
|||
the filter will redirect the request to provided URL. You can also implement your own
|
||||
block handler (the `UrlBlockHandler` interface) and register to `WebCallbackManager`.
|
||||
|
||||
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.
|
||||
|
||||
`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`.
|
||||
|
|
@ -30,15 +30,19 @@ import com.alibaba.csp.sentinel.Entry;
|
|||
import com.alibaba.csp.sentinel.EntryType;
|
||||
import com.alibaba.csp.sentinel.SphU;
|
||||
import com.alibaba.csp.sentinel.Tracer;
|
||||
import com.alibaba.csp.sentinel.adapter.servlet.callback.RequestOriginParser;
|
||||
import com.alibaba.csp.sentinel.adapter.servlet.callback.UrlCleaner;
|
||||
import com.alibaba.csp.sentinel.adapter.servlet.callback.WebCallbackManager;
|
||||
import com.alibaba.csp.sentinel.adapter.servlet.util.FilterUtil;
|
||||
import com.alibaba.csp.sentinel.context.ContextUtil;
|
||||
import com.alibaba.csp.sentinel.slots.block.BlockException;
|
||||
import com.alibaba.csp.sentinel.util.StringUtil;
|
||||
|
||||
/***
|
||||
* Servlet filter that integrates with Sentinel.
|
||||
*
|
||||
* @author youji.zj
|
||||
* @author Eric Zhao
|
||||
*/
|
||||
public class CommonFilter implements Filter {
|
||||
|
||||
|
|
@ -55,14 +59,24 @@ public class CommonFilter implements Filter {
|
|||
|
||||
try {
|
||||
String target = FilterUtil.filterTarget(sRequest);
|
||||
target = WebCallbackManager.getUrlCleaner().clean(target);
|
||||
// Clean and unify the URL.
|
||||
// For REST APIs, you have to clean the URL (e.g. `/foo/1` and `/foo/2` -> `/foo/:id`), or
|
||||
// the amount of context and resources will exceed the threshold.
|
||||
UrlCleaner urlCleaner = WebCallbackManager.getUrlCleaner();
|
||||
if (urlCleaner != null) {
|
||||
target = urlCleaner.clean(target);
|
||||
}
|
||||
|
||||
ContextUtil.enter(target);
|
||||
// Parse the request origin using registered origin parser.
|
||||
String origin = parseOrigin(sRequest);
|
||||
|
||||
ContextUtil.enter(target, origin);
|
||||
entry = SphU.entry(target, EntryType.IN);
|
||||
|
||||
chain.doFilter(request, response);
|
||||
} catch (BlockException e) {
|
||||
HttpServletResponse sResponse = (HttpServletResponse)response;
|
||||
// Return the block page, or redirect to another URL.
|
||||
WebCallbackManager.getUrlBlockHandler().blocked(sRequest, sResponse);
|
||||
} catch (IOException e2) {
|
||||
Tracer.trace(e2);
|
||||
|
|
@ -81,8 +95,22 @@ public class CommonFilter implements Filter {
|
|||
}
|
||||
}
|
||||
|
||||
private String parseOrigin(HttpServletRequest request) {
|
||||
RequestOriginParser originParser = WebCallbackManager.getRequestOriginParser();
|
||||
String origin = EMPTY_ORIGIN;
|
||||
if (originParser != null) {
|
||||
origin = originParser.parseOrigin(request);
|
||||
if (StringUtil.isEmpty(origin)) {
|
||||
return EMPTY_ORIGIN;
|
||||
}
|
||||
}
|
||||
return origin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
|
||||
}
|
||||
|
||||
private static final String EMPTY_ORIGIN = "";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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 com.alibaba.csp.sentinel.adapter.servlet.callback;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* The origin parser parses request origin (e.g. IP, user, appName) from HTTP request.
|
||||
*
|
||||
* @author Eric Zhao
|
||||
* @since 0.2.0
|
||||
*/
|
||||
public interface RequestOriginParser {
|
||||
|
||||
/**
|
||||
* Parse the origin from given HTTP request.
|
||||
*
|
||||
* @param request HTTP request
|
||||
* @return parsed origin
|
||||
*/
|
||||
String parseOrigin(HttpServletRequest request);
|
||||
}
|
||||
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package com.alibaba.csp.sentinel.adapter.servlet.callback;
|
||||
|
||||
import com.alibaba.csp.sentinel.util.AssertUtil;
|
||||
|
||||
/**
|
||||
* Registry for URL cleaner and URL block handler.
|
||||
*
|
||||
|
|
@ -23,15 +25,17 @@ package com.alibaba.csp.sentinel.adapter.servlet.callback;
|
|||
public class WebCallbackManager {
|
||||
|
||||
/**
|
||||
* URL cleaner
|
||||
* URL cleaner.
|
||||
*/
|
||||
private static volatile UrlCleaner urlCleaner = new DefaultUrlCleaner();
|
||||
|
||||
/**
|
||||
* URL block handler
|
||||
* URL block handler.
|
||||
*/
|
||||
private static volatile UrlBlockHandler urlBlockHandler = new DefaultUrlBlockHandler();
|
||||
|
||||
private static volatile RequestOriginParser requestOriginParser = null;
|
||||
|
||||
public static UrlCleaner getUrlCleaner() {
|
||||
return urlCleaner;
|
||||
}
|
||||
|
|
@ -45,6 +49,16 @@ public class WebCallbackManager {
|
|||
}
|
||||
|
||||
public static void setUrlBlockHandler(UrlBlockHandler urlBlockHandler) {
|
||||
AssertUtil.isTrue(urlBlockHandler != null, "URL block handler should not be null");
|
||||
WebCallbackManager.urlBlockHandler = urlBlockHandler;
|
||||
}
|
||||
|
||||
public static RequestOriginParser getRequestOriginParser() {
|
||||
return requestOriginParser;
|
||||
}
|
||||
|
||||
public static void setRequestOriginParser(
|
||||
RequestOriginParser requestOriginParser) {
|
||||
WebCallbackManager.requestOriginParser = requestOriginParser;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue