Browse Source

Support customized block page HTTP status in sentinel-web-servlet-adapter (#1112)

* Return canonical status 429 in the default block handler of sentinel-web-servlet-adapter.
* Add a `csp.sentinel.web.servlet.block.page.http.status` property to support customized block status configuration.
master
于玉桔 Eric Zhao 5 years ago
parent
commit
a451d4bbac
4 changed files with 48 additions and 4 deletions
  1. +33
    -0
      sentinel-adapter/sentinel-web-servlet/src/main/java/com/alibaba/csp/sentinel/adapter/servlet/config/WebServletConfig.java
  2. +4
    -2
      sentinel-adapter/sentinel-web-servlet/src/main/java/com/alibaba/csp/sentinel/adapter/servlet/util/FilterUtil.java
  3. +9
    -1
      sentinel-adapter/sentinel-web-servlet/src/test/java/com/alibaba/csp/sentinel/adapter/servlet/CommonFilterTest.java
  4. +2
    -1
      sentinel-adapter/sentinel-web-servlet/src/test/java/com/alibaba/csp/sentinel/adapter/servletmethod/CommonFilterMethodTest.java

+ 33
- 0
sentinel-adapter/sentinel-web-servlet/src/main/java/com/alibaba/csp/sentinel/adapter/servlet/config/WebServletConfig.java View File

@@ -18,8 +18,10 @@ package com.alibaba.csp.sentinel.adapter.servlet.config;
import com.alibaba.csp.sentinel.adapter.servlet.CommonFilter;
import com.alibaba.csp.sentinel.adapter.servlet.CommonTotalFilter;
import com.alibaba.csp.sentinel.config.SentinelConfig;
import com.alibaba.csp.sentinel.util.StringUtil;

/**
* @author zhaoyuguang
* @author leyou
*/
public class WebServletConfig {
@@ -28,6 +30,10 @@ public class WebServletConfig {

public static final String BLOCK_PAGE = "csp.sentinel.web.servlet.block.page";

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;

/**
* Get redirecting page when Sentinel blocking for {@link CommonFilter} or
* {@link CommonTotalFilter} occurs.
@@ -41,4 +47,31 @@ public class WebServletConfig {
public static void setBlockPage(String blockPage) {
SentinelConfig.setConfig(BLOCK_PAGE, blockPage);
}

/**
* Return status 429 in the default block page,
* you can use -Dcsp.sentinel.web.servlet.block.page.http.status=200 or other http status,
* to set http status which you want of the default block page.
* When csp.sentinel.web.servlet.block.page.http.status is empty or not number,
* the block page http status will be automatically set to 429(Too Many Requests).
*
* @return block page http status
*/
public static int getBlockPageHttpStatus() {
String value = SentinelConfig.getConfig(BLOCK_PAGE_HTTP_STATUS);
if (StringUtil.isEmpty(value)) {
setBlockPageHttpStatus(HTTP_STATUS_TOO_MANY_REQUESTS);
return HTTP_STATUS_TOO_MANY_REQUESTS;
}
try {
return Integer.parseInt(SentinelConfig.getConfig(BLOCK_PAGE_HTTP_STATUS));
} catch (NumberFormatException e) {
setBlockPageHttpStatus(HTTP_STATUS_TOO_MANY_REQUESTS);
}
return HTTP_STATUS_TOO_MANY_REQUESTS;
}

public static void setBlockPageHttpStatus(int httpStatus) {
SentinelConfig.setConfig(BLOCK_PAGE_HTTP_STATUS, String.valueOf(httpStatus));
}
}

+ 4
- 2
sentinel-adapter/sentinel-web-servlet/src/main/java/com/alibaba/csp/sentinel/adapter/servlet/util/FilterUtil.java View File

@@ -27,6 +27,7 @@ import com.alibaba.csp.sentinel.util.StringUtil;
/**
* Util class for web servlet filter.
*
* @author zhaoyuguang
* @author youji.zj
* @author Eric Zhao
*/
@@ -65,7 +66,7 @@ public final class FilterUtil {
}

if (StringUtil.isBlank(WebServletConfig.getBlockPage())) {
writeDefaultBlockedPage(response);
writeDefaultBlockedPage(response, WebServletConfig.getBlockPageHttpStatus());
} else {
String redirectUrl = WebServletConfig.getBlockPage() + "?http_referer=" + url.toString();
// Redirect to the customized block page.
@@ -73,7 +74,8 @@ public final class FilterUtil {
}
}

private static void writeDefaultBlockedPage(HttpServletResponse response) throws IOException {
private static void writeDefaultBlockedPage(HttpServletResponse response, int httpStatus) throws IOException {
response.setStatus(httpStatus);
PrintWriter out = response.getWriter();
out.print(DEFAULT_BLOCK_MSG);
out.flush();


+ 9
- 1
sentinel-adapter/sentinel-web-servlet/src/test/java/com/alibaba/csp/sentinel/adapter/servlet/CommonFilterTest.java View File

@@ -41,6 +41,7 @@ import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
@@ -50,6 +51,7 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

/**
* @author zhaoyuguang
* @author Eric Zhao
*/
@RunWith(SpringRunner.class)
@@ -111,11 +113,17 @@ public class CommonFilterTest {
private void testCommonBlockAndRedirectBlockPage(String url, ClusterNode cn) throws Exception {
configureRulesFor(url, 0);
// The request will be blocked and response is default block message.
WebServletConfig.setBlockPageHttpStatus(HttpStatus.OK.value());
this.mvc.perform(get(url).accept(MediaType.TEXT_PLAIN))
.andExpect(status().isOk())
.andExpect(content().string(FilterUtil.DEFAULT_BLOCK_MSG));
assertEquals(1, cn.blockQps(), 0.01);

WebServletConfig.setBlockPageHttpStatus(HttpStatus.TOO_MANY_REQUESTS.value());
this.mvc.perform(get(url).accept(MediaType.TEXT_PLAIN))
.andExpect(status().isTooManyRequests())
.andExpect(content().string(FilterUtil.DEFAULT_BLOCK_MSG));

// Test for redirect.
String redirectUrl = "http://some-location.com";
WebServletConfig.setBlockPage(redirectUrl);
@@ -192,7 +200,7 @@ public class CommonFilterTest {
.andExpect(content().string(HELLO_STR));
// This will be blocked.
this.mvc.perform(get(url).accept(MediaType.TEXT_PLAIN).header(headerName, limitOrigin))
.andExpect(status().isOk())
.andExpect(status().isTooManyRequests())
.andExpect(content().string(FilterUtil.DEFAULT_BLOCK_MSG));
this.mvc.perform(get(url).accept(MediaType.TEXT_PLAIN))
.andExpect(status().isOk())


+ 2
- 1
sentinel-adapter/sentinel-web-servlet/src/test/java/com/alibaba/csp/sentinel/adapter/servletmethod/CommonFilterMethodTest.java View File

@@ -41,6 +41,7 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

/**
* @author zhaoyuguang
* @author Roger Law
*/
@RunWith(SpringRunner.class)
@@ -107,7 +108,7 @@ public class CommonFilterMethodTest {
configureRulesFor(GET + ":" + url, 0);
// The request will be blocked and response is default block message.
this.mvc.perform(get(url).accept(MediaType.TEXT_PLAIN))
.andExpect(status().isOk())
.andExpect(status().isTooManyRequests())
.andExpect(content().string(FilterUtil.DEFAULT_BLOCK_MSG));
assertEquals(1, cnGet.blockQps(), 0.01);



Loading…
Cancel
Save