Improve CommonFilter and WebServletConfig in Sentinel Web Servlet adapter
Signed-off-by: Eric Zhao <sczyh16@gmail.com>
This commit is contained in:
parent
b6c2979cee
commit
9d514d5036
|
|
@ -39,7 +39,7 @@ public class FilterConfig {
|
||||||
registration.addUrlPatterns("/*");
|
registration.addUrlPatterns("/*");
|
||||||
registration.setName("sentinelCommonFilter");
|
registration.setName("sentinelCommonFilter");
|
||||||
registration.setOrder(1);
|
registration.setOrder(1);
|
||||||
// Set whether to support the specified HTTP method for the filter.
|
// Set whether to support the specified HTTP method prefix for the filter.
|
||||||
registration.addInitParameter(CommonFilter.HTTP_METHOD_SPECIFY, "false");
|
registration.addInitParameter(CommonFilter.HTTP_METHOD_SPECIFY, "false");
|
||||||
return registration;
|
return registration;
|
||||||
}
|
}
|
||||||
|
|
@ -47,6 +47,9 @@ public class FilterConfig {
|
||||||
```
|
```
|
||||||
|
|
||||||
When a request is blocked, Sentinel servlet filter will display a default page indicating the request is rejected.
|
When a request is blocked, Sentinel servlet filter will display a default page indicating the request is rejected.
|
||||||
|
The HTTP status code of the default block page is **429 (Too Many Requests)**. You can customize it
|
||||||
|
via the `csp.sentinel.web.servlet.block.status` configuration item (since 1.7.0).
|
||||||
|
|
||||||
If customized block page is set (via `WebServletConfig.setBlockPage(blockPage)` method),
|
If customized block page is set (via `WebServletConfig.setBlockPage(blockPage)` method),
|
||||||
the filter will redirect the request to provided URL. You can also implement your own
|
the filter will redirect the request to provided URL. You can also implement your own
|
||||||
block handler (the `UrlBlockHandler` interface) and register to `WebCallbackManager`.
|
block handler (the `UrlBlockHandler` interface) and register to `WebCallbackManager`.
|
||||||
|
|
@ -59,5 +62,5 @@ If you need to exclude some URLs (that should not be recorded as Sentinel resour
|
||||||
leverage the `UrlCleaner` interface. You may unify the unwanted URLs to the empty string `""` or `null`,
|
leverage the `UrlCleaner` interface. You may unify the unwanted URLs to the empty string `""` or `null`,
|
||||||
then the URLs will be excluded (since Sentinel 1.6.3).
|
then the URLs will be excluded (since Sentinel 1.6.3).
|
||||||
|
|
||||||
`RequestOriginParser` interface is useful for extracting request origin (e.g. IP or appName from HTTP Header)
|
The `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`.
|
from HTTP request. You can implement your own `RequestOriginParser` and register to `WebCallbackManager`.
|
||||||
|
|
|
||||||
|
|
@ -39,21 +39,30 @@ import com.alibaba.csp.sentinel.context.ContextUtil;
|
||||||
import com.alibaba.csp.sentinel.slots.block.BlockException;
|
import com.alibaba.csp.sentinel.slots.block.BlockException;
|
||||||
import com.alibaba.csp.sentinel.util.StringUtil;
|
import com.alibaba.csp.sentinel.util.StringUtil;
|
||||||
|
|
||||||
/***
|
/**
|
||||||
* Servlet filter that integrates with Sentinel.
|
* Servlet filter that integrates with Sentinel.
|
||||||
*
|
*
|
||||||
* @author zhaoyuguang
|
|
||||||
* @author youji.zj
|
* @author youji.zj
|
||||||
* @author Eric Zhao
|
* @author Eric Zhao
|
||||||
|
* @author zhaoyuguang
|
||||||
*/
|
*/
|
||||||
public class CommonFilter implements Filter {
|
public class CommonFilter implements Filter {
|
||||||
|
|
||||||
public final static String HTTP_METHOD_SPECIFY = "HTTP_METHOD_SPECIFY";
|
|
||||||
/**
|
/**
|
||||||
* Use the path of the url as the context, if necessary, but pay attention to the number of context EntranceNode
|
* Specify whether the URL resource name should contain the HTTP method prefix (e.g. {@code POST:}).
|
||||||
*/
|
*/
|
||||||
public final static String WEB_CONTEXT_UNIFY = "WEB_CONTEXT_UNIFY";
|
public static final String HTTP_METHOD_SPECIFY = "HTTP_METHOD_SPECIFY";
|
||||||
|
/**
|
||||||
|
* If enabled, use the URL path as the context name, or else use the default
|
||||||
|
* {@link WebServletConfig#WEB_SERVLET_CONTEXT_NAME}. Please pay attention to the number of context (EntranceNode),
|
||||||
|
* which may affect the memory footprint.
|
||||||
|
*
|
||||||
|
* @since 1.7.0
|
||||||
|
*/
|
||||||
|
public static final String WEB_CONTEXT_UNIFY = "WEB_CONTEXT_UNIFY";
|
||||||
|
|
||||||
private final static String COLON = ":";
|
private final static String COLON = ":";
|
||||||
|
|
||||||
private boolean httpMethodSpecify = false;
|
private boolean httpMethodSpecify = false;
|
||||||
private boolean webContextUnify = true;
|
private boolean webContextUnify = true;
|
||||||
|
|
||||||
|
|
@ -87,7 +96,8 @@ public class CommonFilter implements Filter {
|
||||||
if (!StringUtil.isEmpty(target)) {
|
if (!StringUtil.isEmpty(target)) {
|
||||||
// Parse the request origin using registered origin parser.
|
// Parse the request origin using registered origin parser.
|
||||||
String origin = parseOrigin(sRequest);
|
String origin = parseOrigin(sRequest);
|
||||||
ContextUtil.enter(webContextUnify ? WebServletConfig.WEB_SERVLET_CONTEXT_NAME : target, origin);
|
String contextName = webContextUnify ? WebServletConfig.WEB_SERVLET_CONTEXT_NAME : target;
|
||||||
|
ContextUtil.enter(contextName, origin);
|
||||||
urlEntry = SphU.entry(target, EntryType.IN);
|
urlEntry = SphU.entry(target, EntryType.IN);
|
||||||
// Add method specification if necessary
|
// Add method specification if necessary
|
||||||
if (httpMethodSpecify) {
|
if (httpMethodSpecify) {
|
||||||
|
|
|
||||||
|
|
@ -18,19 +18,21 @@ package com.alibaba.csp.sentinel.adapter.servlet.config;
|
||||||
import com.alibaba.csp.sentinel.adapter.servlet.CommonFilter;
|
import com.alibaba.csp.sentinel.adapter.servlet.CommonFilter;
|
||||||
import com.alibaba.csp.sentinel.adapter.servlet.CommonTotalFilter;
|
import com.alibaba.csp.sentinel.adapter.servlet.CommonTotalFilter;
|
||||||
import com.alibaba.csp.sentinel.config.SentinelConfig;
|
import com.alibaba.csp.sentinel.config.SentinelConfig;
|
||||||
|
import com.alibaba.csp.sentinel.log.RecordLog;
|
||||||
import com.alibaba.csp.sentinel.util.StringUtil;
|
import com.alibaba.csp.sentinel.util.StringUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author zhaoyuguang
|
* The configuration center for Web Servlet adapter.
|
||||||
|
*
|
||||||
* @author leyou
|
* @author leyou
|
||||||
|
* @author zhaoyuguang
|
||||||
*/
|
*/
|
||||||
public class WebServletConfig {
|
public final class WebServletConfig {
|
||||||
|
|
||||||
public static final String WEB_SERVLET_CONTEXT_NAME = "sentinel_web_servlet_context";
|
public static final String WEB_SERVLET_CONTEXT_NAME = "sentinel_web_servlet_context";
|
||||||
|
|
||||||
public static final String BLOCK_PAGE = "csp.sentinel.web.servlet.block.page";
|
public static final String BLOCK_PAGE_URL_CONF_KEY = "csp.sentinel.web.servlet.block.page";
|
||||||
|
public static final String BLOCK_PAGE_HTTP_STATUS_CONF_KEY = "csp.sentinel.web.servlet.block.status";
|
||||||
public static final String BLOCK_PAGE_HTTP_STATUS = "csp.sentinel.web.servlet.block.page.http.status";
|
|
||||||
|
|
||||||
private static final int HTTP_STATUS_TOO_MANY_REQUESTS = 429;
|
private static final int HTTP_STATUS_TOO_MANY_REQUESTS = 429;
|
||||||
|
|
||||||
|
|
@ -41,37 +43,52 @@ public class WebServletConfig {
|
||||||
* @return the block page URL, maybe null if not configured.
|
* @return the block page URL, maybe null if not configured.
|
||||||
*/
|
*/
|
||||||
public static String getBlockPage() {
|
public static String getBlockPage() {
|
||||||
return SentinelConfig.getConfig(BLOCK_PAGE);
|
return SentinelConfig.getConfig(BLOCK_PAGE_URL_CONF_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setBlockPage(String blockPage) {
|
public static void setBlockPage(String blockPage) {
|
||||||
SentinelConfig.setConfig(BLOCK_PAGE, blockPage);
|
SentinelConfig.setConfig(BLOCK_PAGE_URL_CONF_KEY, blockPage);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return status 429 in the default block page,
|
* <p>Get the HTTP status when using the default block page.</p>
|
||||||
* you can use -Dcsp.sentinel.web.servlet.block.page.http.status=200 or other http status,
|
* <p>You can set the status code with the {@code -Dcsp.sentinel.web.servlet.block.status}
|
||||||
* to set http status which you want of the default block page.
|
* property. When the property is empty or invalid, Sentinel will use 429 (Too Many Requests)
|
||||||
* When csp.sentinel.web.servlet.block.page.http.status is empty or not number,
|
* as the default status code.</p>
|
||||||
* the block page http status will be automatically set to 429(Too Many Requests).
|
|
||||||
*
|
*
|
||||||
* @return block page http status
|
* @return the HTTP status of the default block page
|
||||||
|
* @since 1.7.0
|
||||||
*/
|
*/
|
||||||
public static int getBlockPageHttpStatus() {
|
public static int getBlockPageHttpStatus() {
|
||||||
String value = SentinelConfig.getConfig(BLOCK_PAGE_HTTP_STATUS);
|
String value = SentinelConfig.getConfig(BLOCK_PAGE_HTTP_STATUS_CONF_KEY);
|
||||||
if (StringUtil.isEmpty(value)) {
|
if (StringUtil.isEmpty(value)) {
|
||||||
setBlockPageHttpStatus(HTTP_STATUS_TOO_MANY_REQUESTS);
|
|
||||||
return HTTP_STATUS_TOO_MANY_REQUESTS;
|
return HTTP_STATUS_TOO_MANY_REQUESTS;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return Integer.parseInt(SentinelConfig.getConfig(BLOCK_PAGE_HTTP_STATUS));
|
int s = Integer.parseInt(value);
|
||||||
} catch (NumberFormatException e) {
|
if (s <= 0) {
|
||||||
|
throw new IllegalArgumentException("Invalid status code: " + s);
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
} catch (Exception e) {
|
||||||
|
RecordLog.warn("[WebServletConfig] Invalid block HTTP status (" + value + "), using default 429");
|
||||||
setBlockPageHttpStatus(HTTP_STATUS_TOO_MANY_REQUESTS);
|
setBlockPageHttpStatus(HTTP_STATUS_TOO_MANY_REQUESTS);
|
||||||
}
|
}
|
||||||
return HTTP_STATUS_TOO_MANY_REQUESTS;
|
return HTTP_STATUS_TOO_MANY_REQUESTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the HTTP status of the default block page.
|
||||||
|
*
|
||||||
|
* @param httpStatus the HTTP status of the default block page
|
||||||
|
* @since 1.7.0
|
||||||
|
*/
|
||||||
public static void setBlockPageHttpStatus(int httpStatus) {
|
public static void setBlockPageHttpStatus(int httpStatus) {
|
||||||
SentinelConfig.setConfig(BLOCK_PAGE_HTTP_STATUS, String.valueOf(httpStatus));
|
if (httpStatus <= 0) {
|
||||||
|
throw new IllegalArgumentException("Invalid HTTP status code: " + httpStatus);
|
||||||
|
}
|
||||||
|
SentinelConfig.setConfig(BLOCK_PAGE_HTTP_STATUS_CONF_KEY, String.valueOf(httpStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private WebServletConfig() {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue