diff --git a/app-builder/plugins/aipp-http-call/src/main/java/modelengine/fit/jade/aipp/http/call/AippHttpCallService.java b/app-builder/plugins/aipp-http-call/src/main/java/modelengine/fit/jade/aipp/http/call/AippHttpCallService.java index d6fcf9ac6a..9ad5d68ff9 100644 --- a/app-builder/plugins/aipp-http-call/src/main/java/modelengine/fit/jade/aipp/http/call/AippHttpCallService.java +++ b/app-builder/plugins/aipp-http-call/src/main/java/modelengine/fit/jade/aipp/http/call/AippHttpCallService.java @@ -14,6 +14,11 @@ import modelengine.fit.jade.aipp.http.call.command.HttpCallResult; import modelengine.fitframework.annotation.Component; import modelengine.fitframework.annotation.Fitable; +import modelengine.fitframework.annotation.Value; +import modelengine.fitframework.log.Logger; +import modelengine.fitframework.util.StringUtils; + +import java.util.List; /** * 表示 {@link HttpCallService} 的 aipp 实现。 @@ -23,16 +28,34 @@ */ @Component public class AippHttpCallService implements HttpCallService { + private static final Logger log = Logger.get(AippHttpCallService.class); + private final HttpCallCommandHandler handler; - public AippHttpCallService(HttpCallCommandHandler handler) { + private List blacklistHttpEndpoints; + + public AippHttpCallService(HttpCallCommandHandler handler, + @Value("${blacklist.httpEndpoints:[]}") List blacklistHttpEndpoints) { this.handler = handler; + this.blacklistHttpEndpoints = blacklistHttpEndpoints; } @Override @Fitable("aipp") public HttpResult httpCall(HttpRequest request) throws HttpClientException { notNull(request, "Http request cannot be null."); + + String url = request.getUrl(); + if (StringUtils.isBlank(url)) { + log.error("Blocked: URL is null or empty."); + return createErrorResponse(); + } + if (this.isInBlacklist(url)) { + String baseOnly = this.getBaseUrlSafely(url); + log.error("Blocked: URL is in the blacklist. Base URL: {}", baseOnly); + return createErrorResponse(); + } + HttpCallCommand command = new HttpCallCommand(); command.setMethod(request.getHttpMethod()); command.setUrl(request.getUrl()); @@ -49,4 +72,23 @@ public HttpResult httpCall(HttpRequest request) throws HttpClientException { result.setData(httpCallResult.getData()); return result; } + + private String getBaseUrlSafely(String url) { + int queryOrFragmentIndex = Math.min(url.indexOf('?'), url.indexOf('#')); + if (queryOrFragmentIndex < 0) { + queryOrFragmentIndex = url.length(); + } + return url.substring(0, queryOrFragmentIndex); + } + + private boolean isInBlacklist(String url) { + return blacklistHttpEndpoints.stream().anyMatch(url::contains); + } + + private HttpResult createErrorResponse() { + HttpResult result = new HttpResult(); + result.setStatus(-1); + result.setErrorMsg("Invalid request."); + return result; + } } diff --git a/app-builder/plugins/aipp-http-call/src/main/resources/application.yml b/app-builder/plugins/aipp-http-call/src/main/resources/application.yml index da4634c599..513a9c8c65 100644 --- a/app-builder/plugins/aipp-http-call/src/main/resources/application.yml +++ b/app-builder/plugins/aipp-http-call/src/main/resources/application.yml @@ -1,4 +1,7 @@ fit: beans: packages: - - 'modelengine.fit.jade.aipp.http.call' \ No newline at end of file + - 'modelengine.fit.jade.aipp.http.call' + +blacklist: + httpEndpoints: [] \ No newline at end of file diff --git a/app-builder/plugins/aipp-http-call/src/test/java/modelengine/fit/jade/aipp/http/call/AippHttpCallServiceTest.java b/app-builder/plugins/aipp-http-call/src/test/java/modelengine/fit/jade/aipp/http/call/AippHttpCallServiceTest.java index 47df044522..7903a52a17 100644 --- a/app-builder/plugins/aipp-http-call/src/test/java/modelengine/fit/jade/aipp/http/call/AippHttpCallServiceTest.java +++ b/app-builder/plugins/aipp-http-call/src/test/java/modelengine/fit/jade/aipp/http/call/AippHttpCallServiceTest.java @@ -19,6 +19,8 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import java.util.List; + /** * {@link AippHttpCallService}测试集。 * @@ -33,7 +35,7 @@ public class AippHttpCallServiceTest { @BeforeEach void setUp() { this.handler = mock(HttpCallCommandHandler.class); - this.httpCallService = new AippHttpCallService(this.handler); + this.httpCallService = new AippHttpCallService(this.handler, List.of("blacklist.com")); } @Test @@ -44,11 +46,7 @@ void shouldOk() { when(this.handler.handle(any())).thenReturn(httpResult); when(httpResult.getStatus()).thenReturn(200); - HttpRequest request = new HttpRequest(); - request.setHttpMethod("GET"); - request.setUrl("http://examples.com"); - request.setTimeout(1000); - request.setArgs(MapBuilder.get().put("111", "2222").build()); + HttpRequest request = constructHttpRequest("http://examples.com"); // when HttpResult result = this.httpCallService.httpCall(request); @@ -56,4 +54,27 @@ void shouldOk() { // then Assertions.assertEquals(200, result.getStatus()); } + + @Test + @DisplayName("黑名单网站调用失败") + void blackListShouldBeBlocked() { + // given + HttpRequest request = constructHttpRequest("http://blacklist.com"); + + // when + HttpResult result = this.httpCallService.httpCall(request); + + // then + Assertions.assertEquals(-1, result.getStatus()); + Assertions.assertEquals("The URL is in the blacklist.", result.getErrorMsg()); + } + + private static HttpRequest constructHttpRequest(String url) { + HttpRequest request = new HttpRequest(); + request.setHttpMethod("GET"); + request.setUrl(url); + request.setTimeout(1000); + request.setArgs(MapBuilder.get().put("111", "2222").build()); + return request; + } }