This is an automated email from the ASF dual-hosted git repository. morningman pushed a commit to branch doris-for-zhongjin in repository https://gitbox.apache.org/repos/asf/doris.git
commit d13cb02e8c026a45866a0130075c69788d7559a7 Author: yongjinhou <109586248+yongjin...@users.noreply.github.com> AuthorDate: Mon Apr 3 14:18:17 2023 +0800 [Enhancement](HttpServer) Support https interface (#16834) 1. Organize http documents 2. Add http interface authentication for FE 3. **Support https interface for FE** 4. Provide authentication interface 5. Add http interface authentication for BE 6. Support https interface for BE --- build.sh | 1 + docs/en/docs/admin-manual/config/fe-config.md | 17 ++++++- .../admin-manual/http-actions/fe/cluster-action.md | 12 +++++ .../http-actions/fe/colocate-meta-action.md | 8 +++- .../admin-manual/http-actions/fe/metrics-action.md | 3 ++ docs/zh-CN/docs/admin-manual/config/fe-config.md | 13 +++++ .../admin-manual/http-actions/fe/cluster-action.md | 12 +++++ .../http-actions/fe/colocate-meta-action.md | 8 +++- .../admin-manual/http-actions/fe/metrics-action.md | 3 ++ .../admin-manual/http-actions/fe/profile-action.md | 2 +- .../main/java/org/apache/doris/common/Config.java | 39 ++++++++++++++- .../src/main/java/org/apache/doris/DorisFE.java | 10 ++++ .../org/apache/doris/common/util/NetUtils.java | 2 + .../java/org/apache/doris/httpv2/HttpServer.java | 50 +++++++++++++++++-- .../httpv2/config/HttpToHttpsJettyConfig.java | 54 +++++++++++++++++++++ .../config/WebServerFactoryCustomizerConfig.java | 56 ++++++++++++++++++++++ .../doris/httpv2/controller/BaseController.java | 7 ++- .../doris/httpv2/meta/ColocateMetaService.java | 8 ++++ .../apache/doris/httpv2/rest/CancelLoadAction.java | 5 +- .../org/apache/doris/httpv2/rest/LoadAction.java | 16 +++++++ .../org/apache/doris/httpv2/rest/MultiAction.java | 24 ++++++++++ .../doris/httpv2/rest/RestBaseController.java | 18 +++++++ .../doris/httpv2/rest/StmtExecutionAction.java | 10 +++- .../doris/httpv2/rest/TableQueryPlanAction.java | 4 ++ .../org/apache/doris/httpv2/rest/UploadAction.java | 3 ++ .../apache/doris/httpv2/restv2/ImportAction.java | 4 ++ 26 files changed, 375 insertions(+), 14 deletions(-) diff --git a/build.sh b/build.sh index 7f173015ab..0df9fc0b8c 100755 --- a/build.sh +++ b/build.sh @@ -529,6 +529,7 @@ if [[ "${BUILD_FE}" -eq 1 ]]; then copy_common_files "${DORIS_OUTPUT}/fe/" mkdir -p "${DORIS_OUTPUT}/fe/log" mkdir -p "${DORIS_OUTPUT}/fe/doris-meta" + mkdir -p "${DORIS_OUTPUT}/fe/conf/ssl" fi if [[ "${BUILD_SPARK_DPP}" -eq 1 ]]; then diff --git a/docs/en/docs/admin-manual/config/fe-config.md b/docs/en/docs/admin-manual/config/fe-config.md index 3158cc8eed..b1a9a01aa3 100644 --- a/docs/en/docs/admin-manual/config/fe-config.md +++ b/docs/en/docs/admin-manual/config/fe-config.md @@ -392,13 +392,26 @@ Default value: 0.0.0.0 Default:none -Declare a selection strategy for those servers have many ips. Note that there should at most one ip match this list. this is a list in semicolon-delimited format, in CIDR notation, e.g. 10.10.10.0/24 , If no ip match this rule, will choose one randomly.. +Declare a selection strategy for those servers have many ips. Note that there should at most one ip match this list. this is a list in semicolon-delimited format, in CIDR notation, e.g. 10.10.10.0/24 , If no ip match this rule, will choose one randomly. #### `http_port` Default:8030 -HTTP bind port. Defaults to 8030 +HTTP bind port. All FE http ports must be same currently. + +#### `https_port` + +Default:8050 + +HTTPS bind port. All FE https ports must be same currently. + +#### `enable_https` + +Default:false + +Https enable flag. If the value is false, http is supported. Otherwise, both http and https are supported, and http requests are automatically redirected to https. +If enable_https is true, you need to configure ssl certificate information in fe.conf. #### `qe_max_connection` diff --git a/docs/en/docs/admin-manual/http-actions/fe/cluster-action.md b/docs/en/docs/admin-manual/http-actions/fe/cluster-action.md index b9328cc249..657b9577da 100644 --- a/docs/en/docs/admin-manual/http-actions/fe/cluster-action.md +++ b/docs/en/docs/admin-manual/http-actions/fe/cluster-action.md @@ -38,6 +38,18 @@ under the License. Used to get cluster http, mysql connection information. +## Path parameters + +None + +## Query parameters + +None + +## Request body + +None + ### Response ``` diff --git a/docs/en/docs/admin-manual/http-actions/fe/colocate-meta-action.md b/docs/en/docs/admin-manual/http-actions/fe/colocate-meta-action.md index 99a07597b5..38e8b64e19 100644 --- a/docs/en/docs/admin-manual/http-actions/fe/colocate-meta-action.md +++ b/docs/en/docs/admin-manual/http-actions/fe/colocate-meta-action.md @@ -42,7 +42,13 @@ None ## Query parameters -None +* `db_id` + + Specify database id + +* `group_id` + + Specify group id ## Request body diff --git a/docs/en/docs/admin-manual/http-actions/fe/metrics-action.md b/docs/en/docs/admin-manual/http-actions/fe/metrics-action.md index 0ad53640f9..b1caadb1f9 100644 --- a/docs/en/docs/admin-manual/http-actions/fe/metrics-action.md +++ b/docs/en/docs/admin-manual/http-actions/fe/metrics-action.md @@ -46,3 +46,6 @@ None None +## Response + +TO DO \ No newline at end of file diff --git a/docs/zh-CN/docs/admin-manual/config/fe-config.md b/docs/zh-CN/docs/admin-manual/config/fe-config.md index 369220d732..8241a268a8 100644 --- a/docs/zh-CN/docs/admin-manual/config/fe-config.md +++ b/docs/zh-CN/docs/admin-manual/config/fe-config.md @@ -400,6 +400,19 @@ Doris FE 通过 mysql 协议查询连接端口 FE http 端口,当前所有 FE http 端口都必须相同 +#### `https_port` + +默认值:8050 + +FE https 端口,当前所有 FE https 端口都必须相同 + +#### `enable_https` + +默认值:false + +FE https 使能标志位,false 表示支持 http,true 表示同时支持 http 与 https,并且会自动将 http 请求重定向到 https +如果 enable_https 为 true,需要在 fe.conf 中配置 ssl 证书信息 + #### `qe_max_connection` 默认值:1024 diff --git a/docs/zh-CN/docs/admin-manual/http-actions/fe/cluster-action.md b/docs/zh-CN/docs/admin-manual/http-actions/fe/cluster-action.md index 74bf68d86e..bfb4de6b12 100644 --- a/docs/zh-CN/docs/admin-manual/http-actions/fe/cluster-action.md +++ b/docs/zh-CN/docs/admin-manual/http-actions/fe/cluster-action.md @@ -38,6 +38,18 @@ under the License. 用于获取集群http、mysql连接信息。 +## Path parameters + +无 + +## Query parameters + +无 + +## Request body + +无 + ### Response ``` diff --git a/docs/zh-CN/docs/admin-manual/http-actions/fe/colocate-meta-action.md b/docs/zh-CN/docs/admin-manual/http-actions/fe/colocate-meta-action.md index fecaf01d1a..988380830f 100644 --- a/docs/zh-CN/docs/admin-manual/http-actions/fe/colocate-meta-action.md +++ b/docs/zh-CN/docs/admin-manual/http-actions/fe/colocate-meta-action.md @@ -42,7 +42,13 @@ under the License. ## Query parameters -无 +* `db_id` + + 指定数据库id + +* `group_id` + + 指定组id ## Request body diff --git a/docs/zh-CN/docs/admin-manual/http-actions/fe/metrics-action.md b/docs/zh-CN/docs/admin-manual/http-actions/fe/metrics-action.md index 4e4b305b11..0c6cc8fbea 100644 --- a/docs/zh-CN/docs/admin-manual/http-actions/fe/metrics-action.md +++ b/docs/zh-CN/docs/admin-manual/http-actions/fe/metrics-action.md @@ -46,3 +46,6 @@ under the License. 无 +## Response + +TO DO \ No newline at end of file diff --git a/docs/zh-CN/docs/admin-manual/http-actions/fe/profile-action.md b/docs/zh-CN/docs/admin-manual/http-actions/fe/profile-action.md index 71e7d5dda0..f02380d125 100644 --- a/docs/zh-CN/docs/admin-manual/http-actions/fe/profile-action.md +++ b/docs/zh-CN/docs/admin-manual/http-actions/fe/profile-action.md @@ -126,7 +126,7 @@ Query: ## Query parameters -* query_id +* `query_id` 指定的 query id diff --git a/fe/fe-common/src/main/java/org/apache/doris/common/Config.java b/fe/fe-common/src/main/java/org/apache/doris/common/Config.java index 53daefcf83..1960f8a97c 100644 --- a/fe/fe-common/src/main/java/org/apache/doris/common/Config.java +++ b/fe/fe-common/src/main/java/org/apache/doris/common/Config.java @@ -338,6 +338,11 @@ public class Config extends ConfigBase { */ @ConfField public static long max_bdbje_clock_delta_ms = 5000; // 5s + /** + * Whether to enable all http interface authentication + */ + @ConfField public static boolean enable_all_http_auth = false; + /** * Fe http port * Currently, all FEs' http port must be same. @@ -345,9 +350,39 @@ public class Config extends ConfigBase { @ConfField public static int http_port = 8030; /** - * Whether to enable all http interface authentication + * Fe https port + * Currently, all FEs' https port must be same. */ - @ConfField public static boolean enable_all_http_auth = false; + @ConfField public static int https_port = 8050; + + /** + * ssl key store path. + * If you want to change the path, you need to create corresponding directory. + */ + @ConfField public static String key_store_path = System.getenv("DORIS_HOME") + + "/conf/ssl/doris_ssl_certificate.keystore"; + + /** + * ssl key store password. Null by default. + */ + @ConfField public static String key_store_password = ""; + + /** + * ssl key store type. "JKS" by default. + */ + @ConfField public static String key_store_type = "JKS"; + + /** + * ssl key store alias. "doris_ssl_certificate" by default. + */ + @ConfField public static String key_store_alias = "doris_ssl_certificate"; + + /** + * https enable flag. false by default. + * If the value is false, http is supported. Otherwise, https is supported. + * Currently doris uses many ports, so http and https are not supported at the same time. + */ + @ConfField public static boolean enable_https = false; /** * Jetty container default configuration diff --git a/fe/fe-core/src/main/java/org/apache/doris/DorisFE.java b/fe/fe-core/src/main/java/org/apache/doris/DorisFE.java index 7bebd6ac25..26bfc139df 100755 --- a/fe/fe-core/src/main/java/org/apache/doris/DorisFE.java +++ b/fe/fe-core/src/main/java/org/apache/doris/DorisFE.java @@ -158,10 +158,16 @@ public class DorisFE { if (options.enableHttpServer) { HttpServer httpServer = new HttpServer(); httpServer.setPort(Config.http_port); + httpServer.setHttpsPort(Config.https_port); httpServer.setMaxHttpPostSize(Config.jetty_server_max_http_post_size); httpServer.setAcceptors(Config.jetty_server_acceptors); httpServer.setSelectors(Config.jetty_server_selectors); httpServer.setWorkers(Config.jetty_server_workers); + httpServer.setKeyStorePath(Config.key_store_path); + httpServer.setKeyStorePassword(Config.key_store_password); + httpServer.setKeyStoreType(Config.key_store_type); + httpServer.setKeyStoreAlias(Config.key_store_alias); + httpServer.setEnableHttps(Config.enable_https); httpServer.setMaxThreads(Config.jetty_threadPool_maxThreads); httpServer.setMinThreads(Config.jetty_threadPool_minThreads); httpServer.setMaxHttpHeaderSize(Config.jetty_server_max_http_header_size); @@ -192,6 +198,10 @@ public class DorisFE { "Http port", NetUtils.HTTP_PORT_SUGGESTION)) { throw new IOException("port " + Config.http_port + " already in use"); } + if (Config.enable_https && !NetUtils.isPortAvailable(FrontendOptions.getLocalHostAddress(), + Config.https_port, "Https port", NetUtils.HTTPS_PORT_SUGGESTION)) { + throw new IOException("port " + Config.https_port + " already in use"); + } if (!NetUtils.isPortAvailable(FrontendOptions.getLocalHostAddress(), Config.query_port, "Query port", NetUtils.QUERY_PORT_SUGGESTION)) { throw new IOException("port " + Config.query_port + " already in use"); diff --git a/fe/fe-core/src/main/java/org/apache/doris/common/util/NetUtils.java b/fe/fe-core/src/main/java/org/apache/doris/common/util/NetUtils.java index 61f288b20a..0318a7abdb 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/common/util/NetUtils.java +++ b/fe/fe-core/src/main/java/org/apache/doris/common/util/NetUtils.java @@ -45,6 +45,8 @@ public class NetUtils { public static final String QUERY_PORT_SUGGESTION = "Please change the 'query_port' in fe.conf and try again."; public static final String HTTP_PORT_SUGGESTION = "Please change the 'http_port' in fe.conf and try again. " + "But you need to make sure that ALL FEs http_port are same."; + public static final String HTTPS_PORT_SUGGESTION = "Please change the 'https_port' in fe.conf and try again. " + + "But you need to make sure that ALL FEs https_port are same."; public static final String RPC_PORT_SUGGESTION = "Please change the 'rpc_port' in fe.conf and try again."; // Target format is "host:port" diff --git a/fe/fe-core/src/main/java/org/apache/doris/httpv2/HttpServer.java b/fe/fe-core/src/main/java/org/apache/doris/httpv2/HttpServer.java index 922efe5ea7..88ec1a1b9f 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/httpv2/HttpServer.java +++ b/fe/fe-core/src/main/java/org/apache/doris/httpv2/HttpServer.java @@ -36,13 +36,19 @@ import java.util.Map; @EnableConfigurationProperties @ServletComponentScan public class HttpServer extends SpringBootServletInitializer { - private int port; + private int httpsPort; private int acceptors; private int selectors; private int maxHttpPostSize; private int workers; + private String keyStorePath; + private String keyStorePassword; + private String keyStoreType; + private String keyStoreAlias; + private boolean enableHttps; + private int minThreads; private int maxThreads; private int maxHttpHeaderSize; @@ -91,6 +97,30 @@ public class HttpServer extends SpringBootServletInitializer { this.port = port; } + public void setHttpsPort(int httpsPort) { + this.httpsPort = httpsPort; + } + + public void setKeyStorePath(String keyStorePath) { + this.keyStorePath = keyStorePath; + } + + public void setKeyStorePassword(String keyStorePassword) { + this.keyStorePassword = keyStorePassword; + } + + public void setKeyStoreType(String keyStoreType) { + this.keyStoreType = keyStoreType; + } + + public void setKeyStoreAlias(String keyStoreAlias) { + this.keyStoreAlias = keyStoreAlias; + } + + public void setEnableHttps(boolean enableHttps) { + this.enableHttps = enableHttps; + } + @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(HttpServer.class); @@ -98,7 +128,19 @@ public class HttpServer extends SpringBootServletInitializer { public void start() { Map<String, Object> properties = new HashMap<>(); - properties.put("server.port", port); + if (enableHttps) { + properties.put("server.http.port", port); + properties.put("server.port", httpsPort); + // ssl config + properties.put("server.ssl.key-store", keyStorePath); + properties.put("server.ssl.key-store-password", keyStorePassword); + properties.put("server.ssl.key-store-type", keyStoreType); + properties.put("server.ssl.keyalias", keyStoreAlias); + properties.put("server.ssl.enabled", enableHttps); + } else { + properties.put("server.port", port); + properties.put("server.ssl.enabled", enableHttps); + } if (FrontendOptions.isBindIPV6()) { properties.put("server.address", "::0"); } else { @@ -109,14 +151,14 @@ public class HttpServer extends SpringBootServletInitializer { properties.put("spring.http.encoding.charset", "UTF-8"); properties.put("spring.http.encoding.enabled", true); properties.put("spring.http.encoding.force", true); - //enable jetty config + // enable jetty config properties.put("server.jetty.acceptors", this.acceptors); properties.put("server.jetty.max-http-post-size", this.maxHttpPostSize); properties.put("server.jetty.selectors", this.selectors); properties.put("server.jetty.threadPool.maxThreads", this.maxThreads); properties.put("server.jetty.threadPool.minThreads", this.minThreads); properties.put("server.max-http-header-size", this.maxHttpHeaderSize); - //Worker thread pool is not set by default, set according to your needs + // Worker thread pool is not set by default, set according to your needs if (this.workers > 0) { properties.put("server.jetty.workers", this.workers); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/httpv2/config/HttpToHttpsJettyConfig.java b/fe/fe-core/src/main/java/org/apache/doris/httpv2/config/HttpToHttpsJettyConfig.java new file mode 100644 index 0000000000..84b81f6c72 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/httpv2/config/HttpToHttpsJettyConfig.java @@ -0,0 +1,54 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 org.apache.doris.httpv2.config; + +import org.eclipse.jetty.security.ConstraintMapping; +import org.eclipse.jetty.security.ConstraintSecurityHandler; +import org.eclipse.jetty.util.security.Constraint; +import org.eclipse.jetty.webapp.AbstractConfiguration; +import org.eclipse.jetty.webapp.WebAppContext; + +public class HttpToHttpsJettyConfig extends AbstractConfiguration { + @Override + public void configure(WebAppContext context) throws Exception { + Constraint constraint = new Constraint(); + constraint.setDataConstraint(Constraint.DC_CONFIDENTIAL); + + ConstraintSecurityHandler handler = new ConstraintSecurityHandler(); + + ConstraintMapping mappingGet = new ConstraintMapping(); + mappingGet.setConstraint(constraint); + mappingGet.setPathSpec("/*"); + mappingGet.setMethod("GET"); + handler.addConstraintMapping(mappingGet); + + ConstraintMapping mappingDel = new ConstraintMapping(); + mappingDel.setConstraint(constraint); + mappingDel.setPathSpec("/*"); + mappingDel.setMethod("DELETE"); + handler.addConstraintMapping(mappingDel); + + ConstraintMapping mappingRest = new ConstraintMapping(); + mappingRest.setConstraint(constraint); + mappingRest.setPathSpec("/rest/*"); + mappingRest.setMethod("POST"); + handler.addConstraintMapping(mappingRest); + + context.setSecurityHandler(handler); + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/httpv2/config/WebServerFactoryCustomizerConfig.java b/fe/fe-core/src/main/java/org/apache/doris/httpv2/config/WebServerFactoryCustomizerConfig.java new file mode 100644 index 0000000000..c0eb2dc7c7 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/httpv2/config/WebServerFactoryCustomizerConfig.java @@ -0,0 +1,56 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 org.apache.doris.httpv2.config; + +import org.apache.doris.common.Config; + +import org.eclipse.jetty.server.HttpConfiguration; +import org.eclipse.jetty.server.HttpConnectionFactory; +import org.eclipse.jetty.server.ServerConnector; +import org.springframework.boot.web.embedded.jetty.ConfigurableJettyWebServerFactory; +import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; +import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.context.annotation.Configuration; + +import java.util.Collections; + +@Configuration +public class WebServerFactoryCustomizerConfig implements WebServerFactoryCustomizer<ConfigurableJettyWebServerFactory> { + @Override + public void customize(ConfigurableJettyWebServerFactory factory) { + if (Config.enable_https) { + ((JettyServletWebServerFactory) factory).setConfigurations( + Collections.singleton(new HttpToHttpsJettyConfig()) + ); + + factory.addServerCustomizers( + server -> { + HttpConfiguration httpConfiguration = new HttpConfiguration(); + httpConfiguration.setSecurePort(Config.https_port); + httpConfiguration.setSecureScheme("https"); + + ServerConnector connector = new ServerConnector(server); + connector.addConnectionFactory(new HttpConnectionFactory(httpConfiguration)); + connector.setPort(Config.http_port); + + server.addConnector(connector); + } + ); + } + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/httpv2/controller/BaseController.java b/fe/fe-core/src/main/java/org/apache/doris/httpv2/controller/BaseController.java index cc1a208a2e..59cde0093b 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/httpv2/controller/BaseController.java +++ b/fe/fe-core/src/main/java/org/apache/doris/httpv2/controller/BaseController.java @@ -296,6 +296,11 @@ public class BaseController { } protected String getCurrentFrontendURL() { - return "http://" + FrontendOptions.getLocalHostAddress() + ":" + Config.http_port; + if (Config.enable_https) { + // this could be the result of redirection. + return "https://" + FrontendOptions.getLocalHostAddress() + ":" + Config.https_port; + } else { + return "http://" + FrontendOptions.getLocalHostAddress() + ":" + Config.http_port; + } } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/httpv2/meta/ColocateMetaService.java b/fe/fe-core/src/main/java/org/apache/doris/httpv2/meta/ColocateMetaService.java index 9be85cd86e..9d63a00501 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/httpv2/meta/ColocateMetaService.java +++ b/fe/fe-core/src/main/java/org/apache/doris/httpv2/meta/ColocateMetaService.java @@ -103,6 +103,10 @@ public class ColocateMetaService extends RestBaseController { @RequestMapping(path = "/api/colocate/group_stable", method = {RequestMethod.POST, RequestMethod.DELETE}) public Object group_stable(HttpServletRequest request, HttpServletResponse response) throws DdlException { + if (needRedirect(request.getScheme())) { + return redirectToHttps(request); + } + executeWithoutPassword(request, response); GroupId groupId = checkAndGetGroupId(request); @@ -118,6 +122,10 @@ public class ColocateMetaService extends RestBaseController { @RequestMapping(path = "/api/colocate/bucketseq", method = RequestMethod.POST) public Object bucketseq(HttpServletRequest request, HttpServletResponse response, @RequestBody String meta) throws DdlException { + if (needRedirect(request.getScheme())) { + return redirectToHttps(request); + } + executeWithoutPassword(request, response); final String clusterName = ConnectContext.get().getClusterName(); GroupId groupId = checkAndGetGroupId(request); diff --git a/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/CancelLoadAction.java b/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/CancelLoadAction.java index b215b3c711..5468bf812a 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/CancelLoadAction.java +++ b/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/CancelLoadAction.java @@ -45,8 +45,11 @@ public class CancelLoadAction extends RestBaseController { @RequestMapping(path = "/api/{" + DB_KEY + "}/_cancel", method = RequestMethod.POST) public Object execute(@PathVariable(value = DB_KEY) final String dbName, HttpServletRequest request, HttpServletResponse response) { - executeCheckPassword(request, response); + if (needRedirect(request.getScheme())) { + return redirectToHttps(request); + } + executeCheckPassword(request, response); RedirectView redirectView = redirectToMaster(request, response); if (redirectView != null) { return redirectView; diff --git a/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/LoadAction.java b/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/LoadAction.java index 0e2eb815fd..df0f689953 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/LoadAction.java +++ b/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/LoadAction.java @@ -59,6 +59,10 @@ public class LoadAction extends RestBaseController { @RequestMapping(path = "/api/{" + DB_KEY + "}/{" + TABLE_KEY + "}/_load", method = RequestMethod.PUT) public Object load(HttpServletRequest request, HttpServletResponse response, @PathVariable(value = DB_KEY) String db, @PathVariable(value = TABLE_KEY) String table) { + if (needRedirect(request.getScheme())) { + return redirectToHttps(request); + } + if (Config.disable_mini_load) { ResponseEntity entity = ResponseEntityBuilder.notFound("The mini load operation has been" + " disabled by default, if you need to add disable_mini_load=false in fe.conf."); @@ -73,6 +77,10 @@ public class LoadAction extends RestBaseController { public Object streamLoad(HttpServletRequest request, HttpServletResponse response, @PathVariable(value = DB_KEY) String db, @PathVariable(value = TABLE_KEY) String table) { + if (needRedirect(request.getScheme())) { + return redirectToHttps(request); + } + executeCheckPassword(request, response); return executeWithoutPassword(request, response, db, table, true); } @@ -81,6 +89,10 @@ public class LoadAction extends RestBaseController { public Object streamLoad2PC(HttpServletRequest request, HttpServletResponse response, @PathVariable(value = DB_KEY) String db) { + if (needRedirect(request.getScheme())) { + return redirectToHttps(request); + } + executeCheckPassword(request, response); return executeStreamLoad2PC(request, db); } @@ -90,6 +102,10 @@ public class LoadAction extends RestBaseController { HttpServletResponse response, @PathVariable(value = DB_KEY) String db, @PathVariable(value = TABLE_KEY) String table) { + if (needRedirect(request.getScheme())) { + return redirectToHttps(request); + } + executeCheckPassword(request, response); return executeStreamLoad2PC(request, db); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/MultiAction.java b/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/MultiAction.java index 14d79ab15c..b04005ae7c 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/MultiAction.java +++ b/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/MultiAction.java @@ -52,6 +52,10 @@ public class MultiAction extends RestBaseController { public Object multi_desc( @PathVariable(value = DB_KEY) final String dbName, HttpServletRequest request, HttpServletResponse response) { + if (needRedirect(request.getScheme())) { + return redirectToHttps(request); + } + try { executeCheckPassword(request, response); @@ -84,6 +88,10 @@ public class MultiAction extends RestBaseController { @PathVariable(value = DB_KEY) final String dbName, HttpServletRequest request, HttpServletResponse response) throws DdlException { + if (needRedirect(request.getScheme())) { + return redirectToHttps(request); + } + try { executeCheckPassword(request, response); execEnv = ExecuteEnv.getInstance(); @@ -110,6 +118,10 @@ public class MultiAction extends RestBaseController { @PathVariable(value = DB_KEY) final String dbName, HttpServletRequest request, HttpServletResponse response) throws DdlException { + if (needRedirect(request.getScheme())) { + return redirectToHttps(request); + } + try { executeCheckPassword(request, response); execEnv = ExecuteEnv.getInstance(); @@ -154,6 +166,10 @@ public class MultiAction extends RestBaseController { public Object multi_unload( @PathVariable(value = DB_KEY) final String dbName, HttpServletRequest request, HttpServletResponse response) { + if (needRedirect(request.getScheme())) { + return redirectToHttps(request); + } + try { executeCheckPassword(request, response); execEnv = ExecuteEnv.getInstance(); @@ -188,6 +204,10 @@ public class MultiAction extends RestBaseController { @PathVariable(value = DB_KEY) final String dbName, HttpServletRequest request, HttpServletResponse response) throws DdlException { + if (needRedirect(request.getScheme())) { + return redirectToHttps(request); + } + try { executeCheckPassword(request, response); execEnv = ExecuteEnv.getInstance(); @@ -222,6 +242,10 @@ public class MultiAction extends RestBaseController { @PathVariable(value = DB_KEY) final String dbName, HttpServletRequest request, HttpServletResponse response) throws DdlException { + if (needRedirect(request.getScheme())) { + return redirectToHttps(request); + } + try { executeCheckPassword(request, response); execEnv = ExecuteEnv.getInstance(); diff --git a/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/RestBaseController.java b/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/RestBaseController.java index 1d8a71def3..2bbf914051 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/RestBaseController.java +++ b/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/RestBaseController.java @@ -20,6 +20,7 @@ package org.apache.doris.httpv2.rest; import org.apache.doris.analysis.UserIdentity; import org.apache.doris.catalog.Env; import org.apache.doris.cluster.ClusterNamespace; +import org.apache.doris.common.Config; import org.apache.doris.httpv2.controller.BaseController; import org.apache.doris.httpv2.exception.UnauthorizedException; import org.apache.doris.qe.ConnectContext; @@ -30,6 +31,7 @@ import com.google.common.base.Preconditions; import com.google.common.base.Strings; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.springframework.http.HttpStatus; import org.springframework.web.servlet.view.RedirectView; import java.io.BufferedInputStream; @@ -172,4 +174,20 @@ public class RestBaseController extends BaseController { } return fullDbName; } + + public boolean needRedirect(String scheme) { + return Config.enable_https && "http".equalsIgnoreCase(scheme); + } + + public Object redirectToHttps(HttpServletRequest request) { + String serverName = request.getServerName(); + String uri = request.getRequestURI(); + String query = request.getQueryString(); + query = query == null ? "" : query; + String newUrl = "https://" + serverName + ":" + Config.https_port + uri + "?" + query; + LOG.info("redirect to new url: {}", newUrl); + RedirectView redirectView = new RedirectView(newUrl); + redirectView.setStatusCode(HttpStatus.TEMPORARY_REDIRECT); + return redirectView; + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/StmtExecutionAction.java b/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/StmtExecutionAction.java index 190c5cf82e..8175762ba8 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/StmtExecutionAction.java +++ b/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/StmtExecutionAction.java @@ -84,6 +84,10 @@ public class StmtExecutionAction extends RestBaseController { @RequestMapping(path = "/api/query/{" + NS_KEY + "}/{" + DB_KEY + "}", method = {RequestMethod.POST}) public Object executeSQL(@PathVariable(value = NS_KEY) String ns, @PathVariable(value = DB_KEY) String dbName, HttpServletRequest request, HttpServletResponse response, @RequestBody String body) { + if (needRedirect(request.getScheme())) { + return redirectToHttps(request); + } + ActionAuthorizationInfo authInfo = checkWithCookie(request, response, false); String fullDbName = getFullDbName(dbName); if (Config.enable_all_http_auth) { @@ -125,8 +129,12 @@ public class StmtExecutionAction extends RestBaseController { * @return plain text of create table stmts */ @RequestMapping(path = "/api/query_schema/{" + NS_KEY + "}/{" + DB_KEY + "}", method = {RequestMethod.POST}) - public String querySchema(@PathVariable(value = NS_KEY) String ns, @PathVariable(value = DB_KEY) String dbName, + public Object querySchema(@PathVariable(value = NS_KEY) String ns, @PathVariable(value = DB_KEY) String dbName, HttpServletRequest request, HttpServletResponse response, @RequestBody String sql) { + if (needRedirect(request.getScheme())) { + return redirectToHttps(request); + } + checkWithCookie(request, response, false); if (ns.equalsIgnoreCase(SystemInfoService.DEFAULT_CLUSTER)) { diff --git a/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/TableQueryPlanAction.java b/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/TableQueryPlanAction.java index fa051b983f..dcae36301e 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/TableQueryPlanAction.java +++ b/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/TableQueryPlanAction.java @@ -84,6 +84,10 @@ public class TableQueryPlanAction extends RestBaseController { @PathVariable(value = DB_KEY) final String dbName, @PathVariable(value = TABLE_KEY) final String tblName, HttpServletRequest request, HttpServletResponse response) { + if (needRedirect(request.getScheme())) { + return redirectToHttps(request); + } + executeCheckPassword(request, response); // just allocate 2 slot for top holder map Map<String, Object> resultMap = new HashMap<>(4); diff --git a/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/UploadAction.java b/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/UploadAction.java index 8431bd5195..6b58fcefcf 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/UploadAction.java +++ b/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/UploadAction.java @@ -75,6 +75,9 @@ public class UploadAction extends RestBaseController { @PathVariable(value = TABLE_KEY) String tblName, @RequestParam("file") MultipartFile file, HttpServletRequest request, HttpServletResponse response) { + if (needRedirect(request.getScheme())) { + return redirectToHttps(request); + } checkWithCookie(request, response, false); diff --git a/fe/fe-core/src/main/java/org/apache/doris/httpv2/restv2/ImportAction.java b/fe/fe-core/src/main/java/org/apache/doris/httpv2/restv2/ImportAction.java index 11f66a906c..1979a9e983 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/httpv2/restv2/ImportAction.java +++ b/fe/fe-core/src/main/java/org/apache/doris/httpv2/restv2/ImportAction.java @@ -76,6 +76,10 @@ public class ImportAction extends RestBaseController { @RequestMapping(path = "/api/import/file_review", method = RequestMethod.POST) public Object fileReview(@RequestBody FileReviewRequestVo body, HttpServletRequest request, HttpServletResponse response) { + if (needRedirect(request.getScheme())) { + return redirectToHttps(request); + } + if (Config.enable_all_http_auth) { executeCheckPassword(request, response); } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org