Skip to content

Commit

Permalink
Update Sentinel Web Servlet integration
Browse files Browse the repository at this point in the history
- Add RequestOriginParser interface to extract request origin from the HTTP request
- Some code refinement

Signed-off-by: Eric Zhao <[email protected]>
  • Loading branch information
sczyh30 committed Sep 20, 2018
1 parent be43a31 commit 90d5611
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 6 deletions.
19 changes: 17 additions & 2 deletions sentinel-adapter/sentinel-web-servlet/README.md
Original file line number Diff line number Diff line change
@@ -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>
Expand All @@ -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`.
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,19 @@
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 {

Expand All @@ -55,14 +59,24 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha

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);
}

// Parse the request origin using registered origin parser.
String origin = parseOrigin(sRequest);

ContextUtil.enter(target);
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);
Expand All @@ -81,8 +95,22 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha
}
}

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 = "";
}
Original file line number Diff line number Diff line change
@@ -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);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand All @@ -23,15 +25,17 @@
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;
}
Expand All @@ -45,6 +49,16 @@ public static UrlBlockHandler getUrlBlockHandler() {
}

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;
}
}

0 comments on commit 90d5611

Please sign in to comment.