This is an automated email from the ASF dual-hosted git repository.

dataroaring pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 06bd06c9629 [fix](storage vault) fix Azure Storage Vault endpoint 
always using HTTP instead of HTTPS (#60854)
06bd06c9629 is described below

commit 06bd06c9629eeb7f5471aabad9c813afc16c8a72
Author: hui lai <[email protected]>
AuthorDate: Fri Feb 27 10:26:41 2026 +0800

    [fix](storage vault) fix Azure Storage Vault endpoint always using HTTP 
instead of HTTPS (#60854)
    
    ### What problem does this PR solve?
    
    When creating an Azure Storage Vault, the endpoint scheme handling in
    AzureResource.java has two bugs:
    
    Default to HTTP instead of HTTPS: When user provides an endpoint without
    a scheme (e.g., myaccount.blob.core.windows.net), the code prepends
    http:// instead of https://. Azure storage accounts that require HTTPS
    reject the connection with AccountRequiresHttps error.
    
    Incorrect scheme detection: The code uses startsWith("http://";) to check
    if a scheme is already present. When user provides
    https://myaccount.blob.core.windows.net, this check returns false
    (because the string starts with https://, not http://), so the code
    incorrectly prepends http:// again, resulting in
    http://https://myaccount.blob.core.windows.net. This causes
    UnknownHostException: https because the DNS resolver treats https as a
    hostname.
    
    ### Root Cause:
    
    In AzureResource.java line 71:
    ```
    if (!pingEndpoint.startsWith("http://";)) {
        pingEndpoint = "http://"; + this.properties.get(S3Properties.ENDPOINT);
    }
    ```
    This logic:
    
    Only checks for http:// prefix, not https://
    Defaults to http:// scheme, but Azure typically requires https://
    Note: Other parts of the codebase (e.g.,
    AzureProperties.formatAzureEndpoint() and
    S3ClientFactory._create_azure_client() in BE) correctly use
    contains("://") and default to https://.
    
    ### Fix:
    
    Change the condition to !pingEndpoint.contains("://") and default scheme
    to https://:
    
    ```
    if (!pingEndpoint.contains("://")) {
        pingEndpoint = "https://"; + pingEndpoint;
    }
    ```
    
    ### How to reproduce:
    
    ```
    CREATE STORAGE VAULT IF NOT EXISTS azure_vault_demo
    PROPERTIES (
        "type" = "S3",
        "s3.endpoint" = "myaccount.blob.core.windows.net",
        "s3.access_key" = "myaccount",
        "s3.secret_key" = "***",
        "s3.region" = "eu-west-1",
        "s3.bucket" = "mybucket",
        "s3.root.path" = "mypath",
        "provider" = "AZURE"
    );
    ```
    Error: AccountRequiresHttps (because http:// is used instead of
    https://)
    
    Trying with https:// prefix: "s3.endpoint" =
    "https://myaccount.blob.core.windows.net";
    Error: UnknownHostException: https (because http:// is prepended to
    https://...)
    
    ###  Affected versions
    All versions with Azure Storage Vault support.
---
 .../org/apache/doris/catalog/AzureResource.java    |  4 +-
 .../apache/doris/catalog/AzureResourceTest.java    | 55 ++++++++++++++++++++++
 2 files changed, 57 insertions(+), 2 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/AzureResource.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/AzureResource.java
index 54477da2db4..165e69720e9 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/AzureResource.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/AzureResource.java
@@ -68,8 +68,8 @@ public class AzureResource extends Resource {
 
         // the endpoint for ping need add uri scheme.
         String pingEndpoint = this.properties.get(S3Properties.ENDPOINT);
-        if (!pingEndpoint.startsWith("http://";)) {
-            pingEndpoint = "http://"; + 
this.properties.get(S3Properties.ENDPOINT);
+        if (!pingEndpoint.contains("://")) {
+            pingEndpoint = "https://"; + pingEndpoint;
             this.properties.put(S3Properties.ENDPOINT, pingEndpoint);
             this.properties.put(S3Properties.Env.ENDPOINT, pingEndpoint);
         }
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/catalog/AzureResourceTest.java 
b/fe/fe-core/src/test/java/org/apache/doris/catalog/AzureResourceTest.java
index cbf50d6cc58..3e3c05f5454 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/catalog/AzureResourceTest.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/catalog/AzureResourceTest.java
@@ -20,6 +20,7 @@ package org.apache.doris.catalog;
 import org.apache.doris.common.DdlException;
 
 import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableMap;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.junit.jupiter.api.Assertions;
@@ -54,4 +55,58 @@ public class AzureResourceTest {
             Assertions.assertTrue(false, e.getMessage());
         }
     }
+
+    @Test
+    public void testEndpointSchemeHandling() throws DdlException {
+        // Test 1: endpoint without scheme should get https:// prefix
+        AzureResource resource1 = new AzureResource("test1");
+        Map<String, String> props1 = new HashMap<>();
+        props1.put("s3.endpoint", "myaccount.blob.core.windows.net");
+        props1.put("s3.region", "eu-west-1");
+        props1.put("s3.access_key", "myaccount");
+        props1.put("s3.secret_key", "mysecret");
+        props1.put("s3.bucket", "mybucket");
+        props1.put("s3.root.path", "mypath");
+        props1.put("provider", "AZURE");
+        props1.put("s3_validity_check", "false");
+        resource1.setProperties(ImmutableMap.copyOf(props1));
+        Map<String, String> result1 = resource1.getCopiedProperties();
+        Assertions.assertEquals("https://myaccount.blob.core.windows.net";,
+                result1.get("s3.endpoint"),
+                "Endpoint without scheme should get https:// prefix");
+
+        // Test 2: endpoint with https:// should remain unchanged
+        AzureResource resource2 = new AzureResource("test2");
+        Map<String, String> props2 = new HashMap<>();
+        props2.put("s3.endpoint", "https://myaccount.blob.core.windows.net";);
+        props2.put("s3.region", "eu-west-1");
+        props2.put("s3.access_key", "myaccount");
+        props2.put("s3.secret_key", "mysecret");
+        props2.put("s3.bucket", "mybucket");
+        props2.put("s3.root.path", "mypath");
+        props2.put("provider", "AZURE");
+        props2.put("s3_validity_check", "false");
+        resource2.setProperties(ImmutableMap.copyOf(props2));
+        Map<String, String> result2 = resource2.getCopiedProperties();
+        Assertions.assertEquals("https://myaccount.blob.core.windows.net";,
+                result2.get("s3.endpoint"),
+                "Endpoint with https:// should remain unchanged");
+
+        // Test 3: endpoint with http:// should remain unchanged
+        AzureResource resource3 = new AzureResource("test3");
+        Map<String, String> props3 = new HashMap<>();
+        props3.put("s3.endpoint", "http://myaccount.blob.core.windows.net";);
+        props3.put("s3.region", "eu-west-1");
+        props3.put("s3.access_key", "myaccount");
+        props3.put("s3.secret_key", "mysecret");
+        props3.put("s3.bucket", "mybucket");
+        props3.put("s3.root.path", "mypath");
+        props3.put("provider", "AZURE");
+        props3.put("s3_validity_check", "false");
+        resource3.setProperties(ImmutableMap.copyOf(props3));
+        Map<String, String> result3 = resource3.getCopiedProperties();
+        Assertions.assertEquals("http://myaccount.blob.core.windows.net";,
+                result3.get("s3.endpoint"),
+                "Endpoint with http:// should remain unchanged");
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to