From 102b419549fdf4acdbe26ee4b10992d6acb71207 Mon Sep 17 00:00:00 2001 From: Ludo Mikula Date: Sun, 20 Aug 2023 11:11:33 +0200 Subject: [PATCH 1/2] fix: honor timeout set for REST API calls --- deploy/docker/frontend/nginx-http.conf | 3 + deploy/docker/frontend/nginx-https.conf | 4 + .../query/service/QueryExecutionService.java | 1 + .../plugin/restapi/RestApiExecutor.java | 95 ++++++++++++------- .../restapi/model/RestApiQueryConfig.java | 4 +- .../model/RestApiQueryExecutionContext.java | 5 + 6 files changed, 78 insertions(+), 34 deletions(-) diff --git a/deploy/docker/frontend/nginx-http.conf b/deploy/docker/frontend/nginx-http.conf index fee35838d..d798ed14f 100644 --- a/deploy/docker/frontend/nginx-http.conf +++ b/deploy/docker/frontend/nginx-http.conf @@ -35,6 +35,9 @@ http { listen 3000 default_server; root /lowcoder/client; + proxy_connect_timeout 125; + proxy_send_timeout 125; + proxy_read_timeout 125; location / { try_files $uri /index.html; diff --git a/deploy/docker/frontend/nginx-https.conf b/deploy/docker/frontend/nginx-https.conf index 4f0e01cb7..6692eb184 100644 --- a/deploy/docker/frontend/nginx-https.conf +++ b/deploy/docker/frontend/nginx-https.conf @@ -38,6 +38,10 @@ http { include /etc/nginx/ssl-certificate.conf; include /etc/nginx/ssl-params.conf; + proxy_connect_timeout 125; + proxy_send_timeout 125; + proxy_read_timeout 125; + location / { try_files $uri /index.html; diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/query/service/QueryExecutionService.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/query/service/QueryExecutionService.java index 86f981af7..eb654c2d3 100644 --- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/query/service/QueryExecutionService.java +++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/query/service/QueryExecutionService.java @@ -44,6 +44,7 @@ public Mono executeQuery(Datasource datasource, Map { if (datasourceMetaInfoService.isJsDatasourcePlugin(datasource.getType())) { diff --git a/server/api-service/lowcoder-plugins/restApiPlugin/src/main/java/org/lowcoder/plugin/restapi/RestApiExecutor.java b/server/api-service/lowcoder-plugins/restApiPlugin/src/main/java/org/lowcoder/plugin/restapi/RestApiExecutor.java index c10ff8ebc..6f9ab7a37 100644 --- a/server/api-service/lowcoder-plugins/restApiPlugin/src/main/java/org/lowcoder/plugin/restapi/RestApiExecutor.java +++ b/server/api-service/lowcoder-plugins/restApiPlugin/src/main/java/org/lowcoder/plugin/restapi/RestApiExecutor.java @@ -19,12 +19,48 @@ package org.lowcoder.plugin.restapi; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ObjectNode; -import com.google.common.collect.ImmutableMap; -import lombok.Builder; -import lombok.Getter; +import static com.google.common.base.MoreObjects.firstNonNull; +import static org.apache.commons.collections4.MapUtils.emptyIfNull; +import static org.apache.commons.lang3.StringUtils.trimToEmpty; +import static org.lowcoder.plugin.restapi.RestApiError.REST_API_EXECUTION_ERROR; +import static org.lowcoder.plugin.restapi.helpers.ContentTypeHelper.isBinary; +import static org.lowcoder.plugin.restapi.helpers.ContentTypeHelper.isJson; +import static org.lowcoder.plugin.restapi.helpers.ContentTypeHelper.isJsonContentType; +import static org.lowcoder.plugin.restapi.helpers.ContentTypeHelper.isPicture; +import static org.lowcoder.plugin.restapi.helpers.ContentTypeHelper.isValidContentType; +import static org.lowcoder.plugin.restapi.helpers.ContentTypeHelper.parseContentType; +import static org.lowcoder.sdk.exception.PluginCommonError.JSON_PARSE_ERROR; +import static org.lowcoder.sdk.exception.PluginCommonError.QUERY_ARGUMENT_ERROR; +import static org.lowcoder.sdk.exception.PluginCommonError.QUERY_EXECUTION_ERROR; +import static org.lowcoder.sdk.plugin.restapi.DataUtils.convertToMultiformFileValue; +import static org.lowcoder.sdk.plugin.restapi.auth.RestApiAuthType.DIGEST_AUTH; +import static org.lowcoder.sdk.plugin.restapi.auth.RestApiAuthType.OAUTH2_INHERIT_FROM_LOGIN; +import static org.lowcoder.sdk.util.ExceptionUtils.propagateError; +import static org.lowcoder.sdk.util.JsonUtils.readTree; +import static org.lowcoder.sdk.util.JsonUtils.toJsonThrows; +import static org.lowcoder.sdk.util.MustacheHelper.renderMustacheJson; +import static org.lowcoder.sdk.util.MustacheHelper.renderMustacheString; +import static org.lowcoder.sdk.util.StreamUtils.collectList; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.charset.StandardCharsets; +import java.text.ParseException; +import java.time.Duration; +import java.util.ArrayList; +import java.util.Base64; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import javax.annotation.Nullable; + import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; @@ -51,41 +87,29 @@ import org.lowcoder.sdk.query.QueryVisitorContext; import org.lowcoder.sdk.webclient.WebClientBuildHelper; import org.pf4j.Extension; -import org.springframework.http.*; +import org.springframework.http.HttpCookie; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import org.springframework.http.client.reactive.ClientHttpRequest; +import org.springframework.http.client.reactive.ReactorClientHttpConnector; import org.springframework.util.MultiValueMap; import org.springframework.web.reactive.function.BodyInserter; import org.springframework.web.reactive.function.BodyInserters; import org.springframework.web.reactive.function.client.ExchangeStrategies; import org.springframework.web.reactive.function.client.WebClient; -import reactor.core.publisher.Mono; -import javax.annotation.Nullable; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.charset.StandardCharsets; -import java.text.ParseException; -import java.util.*; -import java.util.function.Consumer; -import java.util.stream.Collectors; -import java.util.stream.Stream; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.common.collect.ImmutableMap; -import static com.google.common.base.MoreObjects.firstNonNull; -import static org.apache.commons.collections4.MapUtils.emptyIfNull; -import static org.apache.commons.lang3.StringUtils.trimToEmpty; -import static org.lowcoder.plugin.restapi.RestApiError.REST_API_EXECUTION_ERROR; -import static org.lowcoder.plugin.restapi.helpers.ContentTypeHelper.*; -import static org.lowcoder.sdk.exception.PluginCommonError.*; -import static org.lowcoder.sdk.plugin.restapi.DataUtils.convertToMultiformFileValue; -import static org.lowcoder.sdk.plugin.restapi.auth.RestApiAuthType.DIGEST_AUTH; -import static org.lowcoder.sdk.plugin.restapi.auth.RestApiAuthType.OAUTH2_INHERIT_FROM_LOGIN; -import static org.lowcoder.sdk.util.ExceptionUtils.propagateError; -import static org.lowcoder.sdk.util.JsonUtils.readTree; -import static org.lowcoder.sdk.util.JsonUtils.toJsonThrows; -import static org.lowcoder.sdk.util.MustacheHelper.renderMustacheJson; -import static org.lowcoder.sdk.util.MustacheHelper.renderMustacheString; -import static org.lowcoder.sdk.util.StreamUtils.collectList; +import lombok.Builder; +import lombok.Getter; +import reactor.core.publisher.Mono; +import reactor.netty.http.client.HttpClient; @Extension public class RestApiExecutor implements QueryExecutor { @@ -176,6 +200,7 @@ public RestApiQueryExecutionContext buildQueryExecutionContext(RestApiDatasource .authConfig(datasourceConfig.getAuthConfig()) .sslConfig(datasourceConfig.getSslConfig()) .authTokenMono(queryVisitorContext.getAuthTokenMono()) + .timeoutMs(queryConfig.getTimeoutMs()) .build(); } @@ -235,9 +260,13 @@ public Mono executeQuery(Object webClientFilter, RestApiQu webClientBuilder.filter(new BufferingFilter()); } + HttpClient httpClient = HttpClient.create() + .responseTimeout(Duration.ofMillis(context.getTimeoutMs())); + webClientBuilder.defaultCookies(injectCookies(context)); WebClient client = webClientBuilder .exchangeStrategies(exchangeStrategies) + .clientConnector(new ReactorClientHttpConnector(httpClient)) .build(); BodyInserter bodyInserter = buildBodyInserter( diff --git a/server/api-service/lowcoder-plugins/restApiPlugin/src/main/java/org/lowcoder/plugin/restapi/model/RestApiQueryConfig.java b/server/api-service/lowcoder-plugins/restApiPlugin/src/main/java/org/lowcoder/plugin/restapi/model/RestApiQueryConfig.java index c823f1932..5c93f1917 100644 --- a/server/api-service/lowcoder-plugins/restApiPlugin/src/main/java/org/lowcoder/plugin/restapi/model/RestApiQueryConfig.java +++ b/server/api-service/lowcoder-plugins/restApiPlugin/src/main/java/org/lowcoder/plugin/restapi/model/RestApiQueryConfig.java @@ -30,10 +30,11 @@ public class RestApiQueryConfig { private final List params; private final List headers; private final List bodyFormData; + private final long timeoutMs; @JsonCreator private RestApiQueryConfig(HttpMethod httpMethod, boolean disableEncodingParams, String body, String path, - List params, List headers, List bodyFormData) { + List params, List headers, List bodyFormData, long timeoutMs) { this.httpMethod = httpMethod; this.disableEncodingParams = disableEncodingParams; this.body = body; @@ -41,6 +42,7 @@ private RestApiQueryConfig(HttpMethod httpMethod, boolean disableEncodingParams, this.params = params; this.headers = headers; this.bodyFormData = bodyFormData; + this.timeoutMs = timeoutMs; } public static RestApiQueryConfig from(Map queryConfigs) { diff --git a/server/api-service/lowcoder-plugins/restApiPlugin/src/main/java/org/lowcoder/plugin/restapi/model/RestApiQueryExecutionContext.java b/server/api-service/lowcoder-plugins/restApiPlugin/src/main/java/org/lowcoder/plugin/restapi/model/RestApiQueryExecutionContext.java index a5ddba1b9..930fcab04 100644 --- a/server/api-service/lowcoder-plugins/restApiPlugin/src/main/java/org/lowcoder/plugin/restapi/model/RestApiQueryExecutionContext.java +++ b/server/api-service/lowcoder-plugins/restApiPlugin/src/main/java/org/lowcoder/plugin/restapi/model/RestApiQueryExecutionContext.java @@ -43,6 +43,7 @@ public class RestApiQueryExecutionContext extends QueryExecutionContext { @Getter private Mono> authTokenMono; private SslConfig sslConfig; + private long timeoutMs; public URI getUri() { return uri; @@ -96,4 +97,8 @@ public AuthConfig getAuthConfig() { public SslConfig getSslConfig() { return sslConfig; } + + public long getTimeoutMs() { + return timeoutMs; + } } From 6025a802d6bfcca93fbe6e3909d223f9cf086ce9 Mon Sep 17 00:00:00 2001 From: Ludo Mikula Date: Sun, 20 Aug 2023 14:24:04 +0200 Subject: [PATCH 2/2] new: make default max query timeout configurable --- deploy/docker/README.md | 4 ++++ deploy/docker/docker-compose-multi.yaml | 2 ++ deploy/docker/docker-compose.yaml | 1 + deploy/docker/frontend/01-update-nginx-conf.sh | 1 + deploy/docker/frontend/nginx-http.conf | 6 +++--- deploy/docker/frontend/nginx-https.conf | 6 +++--- .../domain/query/service/QueryExecutionService.java | 6 +++++- .../domain/query/util/QueryTimeoutUtils.java | 13 ++++++------- .../java/org/lowcoder/sdk/config/CommonConfig.java | 1 + .../src/main/resources/selfhost/ce/application.yml | 1 + 10 files changed, 27 insertions(+), 14 deletions(-) diff --git a/deploy/docker/README.md b/deploy/docker/README.md index 378f9eadd..a219714c5 100644 --- a/deploy/docker/README.md +++ b/deploy/docker/README.md @@ -37,6 +37,7 @@ Image can be configured by setting environment variables. | `ENCRYPTION_SALT` | Salt used for encrypting password | `lowcoder.org` | | `CORS_ALLOWED_DOMAINS` | CORS allowed domains | `*` | | `LOWCODER_MAX_REQUEST_SIZE` | Lowcoder max request size | `20m` | +| `LOWCODER_MAX_QUERY_TIMEOUT` | Lowcoder max query timeout (in seconds) | `120` | | `LOWCODER_API_SERVICE_URL` | Lowcoder API service URL | `http://localhost:8080` | | `LOWCODER_NODE_SERVICE_URL` | Lowcoder Node service (js executor) URL | `http://localhost:6060` | | `DEFAULT_ORGS_PER_USER` | Default maximum organizations per user | `100` | @@ -77,6 +78,8 @@ Image can be configured by setting environment variables. | `DEFAULT_ORG_GROUP_COUNT` | Default maximum groups per organization | `100` | | `DEFAULT_ORG_APP_COUNT` | Default maximum applications per organization | `1000` | | `DEFAULT_DEVELOPER_COUNT` | Default maximum developers | `100` | +| `LOWCODER_MAX_QUERY_TIMEOUT` | Lowcoder max query timeout (in seconds) | `120` | +| `LOWCODER_MAX_REQUEST_SIZE` | Lowcoder max request size | `20m` | @@ -122,6 +125,7 @@ Image can be configured by setting environment variables. | --------------------------------| --------------------------------------------------------------------| ------------------------------------------------------- | | `PUID` | ID of user running services. It will own all created logs and data. | `9001` | | `PGID` | ID of group of the user running services. | `9001` | +| `LOWCODER_MAX_QUERY_TIMEOUT` | Lowcoder max query timeout (in seconds) | `120` | | `LOWCODER_MAX_REQUEST_SIZE` | Lowcoder max request size | `20m` | | `LOWCODER_API_SERVICE_URL` | Lowcoder API service URL | `http://localhost:8080` | | `LOWCODER_NODE_SERVICE_URL` | Lowcoder Node service (js executor) URL | `http://localhost:6060` | diff --git a/deploy/docker/docker-compose-multi.yaml b/deploy/docker/docker-compose-multi.yaml index dbfecc714..74155454b 100644 --- a/deploy/docker/docker-compose-multi.yaml +++ b/deploy/docker/docker-compose-multi.yaml @@ -36,6 +36,7 @@ services: MONGODB_URL: "mongodb://lowcoder:secret123@mongodb/lowcoder?authSource=admin" REDIS_URL: "redis://redis:6379" LOWCODER_NODE_SERVICE_URL: "http://lowcoder-node-service:6060" + LOWCODER_MAX_QUERY_TIMEOUT: 120 ENABLE_USER_SIGN_UP: "true" ENCRYPTION_PASSWORD: "lowcoder.org" ENCRYPTION_SALT: "lowcoder.org" @@ -76,6 +77,7 @@ services: PUID: "9001" PGID: "9001" LOWCODER_MAX_REQUEST_SIZE: 20m + LOWCODER_MAX_QUERY_TIMEOUT: 120 LOWCODER_API_SERVICE_URL: "http://lowcoder-api-service:8080" LOWCODER_NODE_SERVICE_URL: "http://lowcoder-node-service:6060" restart: unless-stopped diff --git a/deploy/docker/docker-compose.yaml b/deploy/docker/docker-compose.yaml index d07aed9ea..860808aee 100644 --- a/deploy/docker/docker-compose.yaml +++ b/deploy/docker/docker-compose.yaml @@ -38,6 +38,7 @@ services: LOWCODER_NODE_SERVICE_URL: "http://localhost:6060" # frontend parameters LOWCODER_MAX_REQUEST_SIZE: 20m + LOWCODER_MAX_QUERY_TIMEOUT: 120 volumes: - ./lowcoder-stacks:/lowcoder-stacks restart: unless-stopped diff --git a/deploy/docker/frontend/01-update-nginx-conf.sh b/deploy/docker/frontend/01-update-nginx-conf.sh index 97e6570da..6330f540c 100644 --- a/deploy/docker/frontend/01-update-nginx-conf.sh +++ b/deploy/docker/frontend/01-update-nginx-conf.sh @@ -18,6 +18,7 @@ else ln -s /etc/nginx/nginx-http.conf /etc/nginx/nginx.conf fi; +sed -i "s@__LOWCODER_MAX_QUERY_TIMEOUT__@${LOWCODER_MAX_QUERY_TIMEOUT:=120}@" /etc/nginx/nginx.conf sed -i "s@__LOWCODER_MAX_REQUEST_SIZE__@${LOWCODER_MAX_REQUEST_SIZE:=20m}@" /etc/nginx/nginx.conf sed -i "s@__LOWCODER_API_SERVICE_URL__@${LOWCODER_API_SERVICE_URL:=http://localhost:8080}@" /etc/nginx/nginx.conf sed -i "s@__LOWCODER_NODE_SERVICE_URL__@${LOWCODER_NODE_SERVICE_URL:=http://localhost:6060}@" /etc/nginx/nginx.conf diff --git a/deploy/docker/frontend/nginx-http.conf b/deploy/docker/frontend/nginx-http.conf index d798ed14f..c25c9cf2e 100644 --- a/deploy/docker/frontend/nginx-http.conf +++ b/deploy/docker/frontend/nginx-http.conf @@ -35,9 +35,9 @@ http { listen 3000 default_server; root /lowcoder/client; - proxy_connect_timeout 125; - proxy_send_timeout 125; - proxy_read_timeout 125; + proxy_connect_timeout __LOWCODER_MAX_QUERY_TIMEOUT__; + proxy_send_timeout __LOWCODER_MAX_QUERY_TIMEOUT__; + proxy_read_timeout __LOWCODER_MAX_QUERY_TIMEOUT__; location / { try_files $uri /index.html; diff --git a/deploy/docker/frontend/nginx-https.conf b/deploy/docker/frontend/nginx-https.conf index 6692eb184..f6f0d5280 100644 --- a/deploy/docker/frontend/nginx-https.conf +++ b/deploy/docker/frontend/nginx-https.conf @@ -38,9 +38,9 @@ http { include /etc/nginx/ssl-certificate.conf; include /etc/nginx/ssl-params.conf; - proxy_connect_timeout 125; - proxy_send_timeout 125; - proxy_read_timeout 125; + proxy_connect_timeout __LOWCODER_MAX_QUERY_TIMEOUT__; + proxy_send_timeout __LOWCODER_MAX_QUERY_TIMEOUT__; + proxy_read_timeout __LOWCODER_MAX_QUERY_TIMEOUT__; location / { try_files $uri /index.html; diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/query/service/QueryExecutionService.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/query/service/QueryExecutionService.java index eb654c2d3..750b375f5 100644 --- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/query/service/QueryExecutionService.java +++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/query/service/QueryExecutionService.java @@ -16,6 +16,7 @@ import org.lowcoder.domain.plugin.client.DatasourcePluginClient; import org.lowcoder.domain.plugin.service.DatasourceMetaInfoService; import org.lowcoder.domain.query.util.QueryTimeoutUtils; +import org.lowcoder.sdk.config.CommonConfig; import org.lowcoder.sdk.exception.BizException; import org.lowcoder.sdk.exception.PluginException; import org.lowcoder.sdk.models.QueryExecutionResult; @@ -40,10 +41,13 @@ public class QueryExecutionService { @Autowired private DatasourcePluginClient datasourcePluginClient; + @Autowired + private CommonConfig common; + public Mono executeQuery(Datasource datasource, Map queryConfig, Map requestParams, String timeoutStr, QueryVisitorContext queryVisitorContext) { - int timeoutMs = QueryTimeoutUtils.parseQueryTimeoutMs(timeoutStr, requestParams); + int timeoutMs = QueryTimeoutUtils.parseQueryTimeoutMs(timeoutStr, requestParams, common.getMaxQueryTimeout()); queryConfig.putIfAbsent("timeoutMs", timeoutMs); return Mono.defer(() -> { diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/query/util/QueryTimeoutUtils.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/query/util/QueryTimeoutUtils.java index aaab4c0dc..cb4d08310 100644 --- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/query/util/QueryTimeoutUtils.java +++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/query/util/QueryTimeoutUtils.java @@ -17,14 +17,13 @@ public final class QueryTimeoutUtils { private static final int DEFAULT_QUERY_TIMEOUT_MILLIS = 10000; - private static final int MAX_QUERY_TIMEOUT_SECONDS = 120; - public static int parseQueryTimeoutMs(String timeoutStr, Map paramMap) { - return parseQueryTimeoutMs(renderMustacheString(timeoutStr, paramMap)); + public static int parseQueryTimeoutMs(String timeoutStr, Map paramMap, int maxQueryTimeout) { + return parseQueryTimeoutMs(renderMustacheString(timeoutStr, paramMap), maxQueryTimeout); } @VisibleForTesting - public static int parseQueryTimeoutMs(String timeoutStr) { + public static int parseQueryTimeoutMs(String timeoutStr, int maxQueryTimeout) { if (StringUtils.isBlank(timeoutStr)) { return DEFAULT_QUERY_TIMEOUT_MILLIS; } @@ -44,10 +43,10 @@ public static int parseQueryTimeoutMs(String timeoutStr) { if (value < 0) { throw new PluginException(QUERY_ARGUMENT_ERROR, "INVALID_TIMEOUT_SETTING", timeoutStr); } - + int millis = convertToMs(value, unit); - if (millis > Duration.ofSeconds(MAX_QUERY_TIMEOUT_SECONDS).toMillis()) { - throw new PluginException(EXCEED_MAX_QUERY_TIMEOUT, "EXCEED_MAX_QUERY_TIMEOUT", MAX_QUERY_TIMEOUT_SECONDS); + if (millis > Duration.ofSeconds(maxQueryTimeout).toMillis()) { + throw new PluginException(EXCEED_MAX_QUERY_TIMEOUT, "EXCEED_MAX_QUERY_TIMEOUT", maxQueryTimeout); } return millis; diff --git a/server/api-service/lowcoder-sdk/src/main/java/org/lowcoder/sdk/config/CommonConfig.java b/server/api-service/lowcoder-sdk/src/main/java/org/lowcoder/sdk/config/CommonConfig.java index 626529ce8..8faac8ed6 100644 --- a/server/api-service/lowcoder-sdk/src/main/java/org/lowcoder/sdk/config/CommonConfig.java +++ b/server/api-service/lowcoder-sdk/src/main/java/org/lowcoder/sdk/config/CommonConfig.java @@ -35,6 +35,7 @@ public class CommonConfig { private String version; private boolean blockHoundEnable; private String cookieName; + private int maxQueryTimeout = 300; private String maxUploadSize = "20MB"; private String maxQueryRequestSize = "20MB"; private String maxQueryResponseSize = "20MB"; diff --git a/server/api-service/lowcoder-server/src/main/resources/selfhost/ce/application.yml b/server/api-service/lowcoder-server/src/main/resources/selfhost/ce/application.yml index b51df0e21..ce0618058 100644 --- a/server/api-service/lowcoder-server/src/main/resources/selfhost/ce/application.yml +++ b/server/api-service/lowcoder-server/src/main/resources/selfhost/ce/application.yml @@ -44,6 +44,7 @@ common: max-query-request-size: ${LOWCODER_MAX_REQUEST_SIZE:20m} max-query-response-size: ${LOWCODER_MAX_REQUEST_SIZE:20m} max-upload-size: ${LOWCODER_MAX_REQUEST_SIZE:20m} + max-query-timeout: ${LOWCODER_MAX_QUERY_TIMEOUT:120} material: mongodb-grid-fs: