comphead commented on code in PR #5872:
URL: https://github.com/apache/datafusion-comet/pull/5872#discussion_r4265558925


##########
native/core/src/parquet/objectstore/s3.rs:
##########
@@ -352,24 +354,33 @@ fn extract_s3_config_options(
         s3_configs.insert(AmazonS3ConfigKey::Region, region.to_string());
     }
 
-    // Extract and handle path style access (virtual hosted style)
-    let mut virtual_hosted_style_request = false;
-    if let Some(path_style) = get_config_trimmed(configs, bucket, 
"path.style.access") {
-        virtual_hosted_style_request = path_style.to_lowercase() == "true";
-        s3_configs.insert(
-            AmazonS3ConfigKey::VirtualHostedStyleRequest,
-            virtual_hosted_style_request.to_string(),
-        );
-    }
-
-    // Extract endpoint configuration and modify if virtual hosted style is 
enabled
-    if let Some(endpoint) = get_config_trimmed(configs, bucket, "endpoint") {
-        let normalized_endpoint =
-            normalize_endpoint(endpoint, bucket, virtual_hosted_style_request);
-        if let Some(endpoint) = normalized_endpoint {
-            s3_configs.insert(AmazonS3ConfigKey::Endpoint, endpoint);
+    // Hadoop defaults fs.s3a.path.style.access to false, which means 
virtual-hosted addressing,
+    // and treats non-boolean text as that default. object_store expects the 
inverse flag.
+    let path_style_access = get_config_trimmed(configs, bucket, 
"path.style.access")
+        .is_some_and(|value| value.eq_ignore_ascii_case("true"));
+    let mut virtual_hosted_style_request = !path_style_access;
+
+    // Extract endpoint configuration and shape it for the selected addressing 
style. The flag is
+    // taken from the normalized result so the endpoint and the flag never 
disagree. A custom
+    // endpoint decides the bucket-name rule by its own scheme inside 
normalize_endpoint; the
+    // default AWS endpoint is HTTPS, so the rule applies to it here without 
dots.
+    let custom_endpoint = get_config_trimmed(configs, bucket, "endpoint")
+        .and_then(|endpoint| normalize_endpoint(endpoint, bucket, 
virtual_hosted_style_request));
+    match custom_endpoint {
+        Some(normalized) => {
+            virtual_hosted_style_request = 
normalized.virtual_hosted_style_request;
+            s3_configs.insert(AmazonS3ConfigKey::Endpoint, 
normalized.endpoint);
+        }
+        None => {

Review Comment:
   This arm is the default AWS endpoint, but when `fs.s3a.endpoint.region` is 
not set either, `S3StoreTemplate::new` first calls `resolve_bucket_region`, 
which sends HEAD to `https://{bucket}.s3.amazonaws.com` (line 301). That probe 
is always virtual-hosted, so it does not follow the rule added here. I expect, 
not run, that a dotted bucket fails TLS on that request since the wildcard 
certificate covers one label, and that `LegacyBucket` is lowercased by URL 
parsing and so probes a different bucket name (a `Bucket not found` error, or 
the region of someone else's bucket). That would mean the dotted and mixed-case 
fixes only work when the region is configured, and every test for them sets 
one. Could the probe reuse `is_virtual_hostable_bucket(bucket, false)` and use 
a path-style probe URL when it is false, with a test of the probe URL? If not, 
the data sources paragraph should say these buckets need 
`fs.s3a.endpoint.region`.



##########
native/core/src/parquet/objectstore/s3.rs:
##########
@@ -1414,6 +1540,159 @@ mod tests {
         assert_eq!(lookup_provider_class(&configs, "public-data"), None);
     }
 
+    #[test]
+    fn test_hadoop_profile_provider_routes_through_the_adapter() {

Review Comment:
   About half of the 18 rows duplicate tests that exist already. The global 
class, per-bucket class, empty and blank class rows repeat 
`test_empty_per_bucket_provider_class_opts_out`, and the per-bucket list rows 
exercise `get_config_trimmed` precedence, which `test_get_config_trimmed` 
covers. The rows specific to this change are the list matching (padded entries, 
exact names, whole entries, SDK names) plus one row where a configured class 
wins and one where a blank class opts out. Could the table keep those and drop 
the rest?



##########
native/core/src/parquet/objectstore/s3.rs:
##########
@@ -2357,75 +2656,497 @@ mod tests {
     }
 
     #[test]
-    fn test_extract_s3_config_custom_endpoint() {
-        let cases = vec![
-            ("custom.endpoint.com", "https://custom.endpoint.com";),
-            ("https://custom.endpoint.com";, "https://custom.endpoint.com";),
+    fn test_normalize_endpoint_virtual_hosted_style() {
+        // Virtual-hosted addressing inserts the bucket as the leading host 
label. The scheme,
+        // port and any path suffix are preserved and a trailing slash is 
dropped.
+        let cases = [
+            (
+                "custom.endpoint.com",
+                "https://test-bucket.custom.endpoint.com";,
+            ),
+            (
+                "http://custom.endpoint.com";,
+                "http://test-bucket.custom.endpoint.com";,
+            ),
+            (
+                "https://custom.endpoint.com/";,
+                "https://test-bucket.custom.endpoint.com";,
+            ),
+            (
+                "http://minio.internal:9000";,
+                "http://test-bucket.minio.internal:9000";,
+            ),
+            (
+                "https://custom.endpoint.com:8443/";,
+                "https://test-bucket.custom.endpoint.com:8443";,
+            ),
             (
                 "https://custom.endpoint.com/path/to/resource";,
-                "https://custom.endpoint.com/path/to/resource";,
+                "https://test-bucket.custom.endpoint.com/path/to/resource";,
+            ),
+            (
+                "https://custom.endpoint.com/path/to/resource/";,
+                "https://test-bucket.custom.endpoint.com/path/to/resource";,
+            ),
+            (
+                "s3.us-west-2.amazonaws.com",
+                "https://test-bucket.s3.us-west-2.amazonaws.com";,
             ),
         ];
-        for (endpoint, configured_endpoint) in cases {
-            let mut configs = HashMap::new();
-            configs.insert("fs.s3a.endpoint".to_string(), 
endpoint.to_string());
-            let s3_configs = extract_s3_config_options(&configs, 
"test-bucket");
+        for (endpoint, expected) in cases {
             assert_eq!(
-                s3_configs.get(&AmazonS3ConfigKey::Endpoint),
-                Some(&configured_endpoint.to_string())
+                normalize_endpoint(endpoint, "test-bucket", true),
+                Some(NormalizedEndpoint {
+                    endpoint: expected.to_string(),
+                    virtual_hosted_style_request: true,
+                }),
+                "endpoint {endpoint}"
             );
         }
+
+        // A dotted bucket over HTTPS stays path-style, as the AWS SDK 
addresses it, since the
+        // dotted host falls outside S3's wildcard certificate; over HTTP it 
is virtual-hosted.
+        assert_eq!(
+            normalize_endpoint("custom.endpoint.com", "my.dotted.bucket", 
true),
+            Some(NormalizedEndpoint {
+                endpoint: "https://custom.endpoint.com".to_string(),
+                virtual_hosted_style_request: false,
+            })
+        );
+        assert_eq!(
+            normalize_endpoint("http://custom.endpoint.com";, 
"my.dotted.bucket", true),
+            Some(NormalizedEndpoint {
+                endpoint: 
"http://my.dotted.bucket.custom.endpoint.com".to_string(),
+                virtual_hosted_style_request: true,
+            })
+        );
     }
 
     #[test]
-    fn test_extract_s3_config_custom_endpoint_with_virtual_hosted_style() {
-        let cases = vec![
+    fn 
test_extract_s3_config_dotted_bucket_stays_path_style_on_default_endpoint() {
+        // No custom endpoint means the HTTPS AWS endpoint, where a dotted 
bucket must be
+        // addressed path-style whatever the flag says.
+        let configs = 
TestConfigBuilder::new().with_region("us-east-1").build();
+        let s3_configs = extract_s3_config_options(&configs, 
"review.dotted.bucket");
+        assert_eq!(
+            s3_configs.get(&AmazonS3ConfigKey::VirtualHostedStyleRequest),
+            Some(&"false".to_string())
+        );
+        assert!(!s3_configs.contains_key(&AmazonS3ConfigKey::Endpoint));
+
+        let configs = TestConfigBuilder::new()
+            .with_region("us-east-1")
+            .with_property("endpoint", "https://s3.us-east-1.amazonaws.com";)
+            .build();
+        let s3_configs = extract_s3_config_options(&configs, 
"review.dotted.bucket");
+        assert_eq!(
+            s3_configs.get(&AmazonS3ConfigKey::VirtualHostedStyleRequest),
+            Some(&"false".to_string())
+        );
+        assert_eq!(
+            s3_configs.get(&AmazonS3ConfigKey::Endpoint),
+            Some(&"https://s3.us-east-1.amazonaws.com".to_string())
+        );
+
+        let s3_configs = extract_s3_config_options(&configs, "plainbucket");
+        assert_eq!(
+            s3_configs.get(&AmazonS3ConfigKey::VirtualHostedStyleRequest),
+            Some(&"true".to_string())
+        );
+
+        // A custom HTTP endpoint keeps virtual hosting for a dotted bucket, 
as the SDK does,
+        // since the certificate rule only applies to HTTPS.
+        let configs = TestConfigBuilder::new()
+            .with_property("endpoint", "http://storage.example.test";)
+            .build();
+        let s3_configs = extract_s3_config_options(&configs, 
"review.dotted.bucket");
+        assert_eq!(
+            s3_configs.get(&AmazonS3ConfigKey::VirtualHostedStyleRequest),
+            Some(&"true".to_string())
+        );
+        assert_eq!(
+            s3_configs.get(&AmazonS3ConfigKey::Endpoint),
+            
Some(&"http://review.dotted.bucket.storage.example.test".to_string())
+        );
+    }
+
+    /// The URL object_store sends a GET for `s3a://<bucket>/object` to under 
the options Comet
+    /// derives from `configs`, read from a presigned URL so no request leaves 
the test.
+    async fn final_url(bucket: &str, configs: &HashMap<String, String>) -> 
String {
+        use object_store::signer::Signer;
+
+        let mut builder = AmazonS3Builder::new()
+            .with_url(format!("s3a://{bucket}/object"))
+            .with_allow_http(true)
+            .with_access_key_id("test_access_key")
+            .with_secret_access_key("test_secret_key");
+        for (key, value) in extract_s3_config_options(configs, bucket) {
+            builder = builder.with_config(key, value);
+        }
+        let signed = match builder.build() {
+            Ok(store) => {
+                store
+                    .signed_url(
+                        reqwest::Method::GET,
+                        &Path::from("object"),
+                        Duration::from_secs(60),
+                    )
+                    .await
+            }
+            Err(e) => Err(e),
+        };
+        match signed {
+            Ok(mut url) => {
+                url.set_query(None);
+                url.to_string()
+            }
+            Err(e) => format!("error: {e}"),
+        }
+    }
+
+    #[tokio::test]
+    #[cfg_attr(miri, ignore)] // object_store calls foreign functions
+    async fn test_bucket_the_sdk_cannot_virtual_host_stays_path_style() {
+        // The AWS SDK virtual-hosts a bucket only when its name is a DNS 
label: 3 to 63
+        // lowercase letters, digits and hyphens that start and end with a 
letter or digit.
+        // Other names, such as the mixed-case ones US East accepted before 
March 2018, go
+        // path-style, since a hostname would lowercase the bucket into a 
different one.
+        let default_endpoint = 
TestConfigBuilder::new().with_region("us-east-1").build();
+        let http_endpoint = TestConfigBuilder::new()
+            .with_region("us-east-1")
+            .with_property("endpoint", "http://storage.example.test";)
+            .build();
+        let long = "a".repeat(64);
+        let cases = [
             (
-                "custom.endpoint.com",
-                "https://custom.endpoint.com/test-bucket";,
+                &default_endpoint,
+                "LegacyBucket",
+                
"https://s3.us-east-1.amazonaws.com/LegacyBucket/object".to_string(),
+            ),
+            (
+                &default_endpoint,
+                "legacy_bucket",
+                
"https://s3.us-east-1.amazonaws.com/legacy_bucket/object".to_string(),
+            ),
+            (
+                &default_endpoint,
+                "-legacy-bucket",
+                
"https://s3.us-east-1.amazonaws.com/-legacy-bucket/object".to_string(),
             ),
             (
-                "https://custom.endpoint.com";,
-                "https://custom.endpoint.com/test-bucket";,
+                &default_endpoint,
+                "legacy-bucket-",
+                
"https://s3.us-east-1.amazonaws.com/legacy-bucket-/object".to_string(),
             ),
             (
+                &default_endpoint,
+                long.as_str(),
+                format!("https://s3.us-east-1.amazonaws.com/{long}/object";),
+            ),
+            (
+                &default_endpoint,
+                "legacy-bucket",
+                
"https://legacy-bucket.s3.us-east-1.amazonaws.com/object".to_string(),
+            ),
+            // Over plain HTTP the SDK also accepts dots, but not an 
IPv4-shaped name, a dot next
+            // to a hyphen or an uppercase letter
+            (
+                &http_endpoint,
+                "192.168.10.12",
+                "http://storage.example.test/192.168.10.12/object".to_string(),
+            ),
+            (
+                &http_endpoint,
+                "legacy-.bucket",
+                
"http://storage.example.test/legacy-.bucket/object".to_string(),
+            ),
+            (
+                &http_endpoint,
+                "LegacyBucket",
+                "http://storage.example.test/LegacyBucket/object".to_string(),
+            ),
+        ];
+        let mut actual = Vec::new();
+        let mut expected = Vec::new();
+        for (configs, bucket, url) in cases {
+            actual.push(format!("{bucket}: {}", final_url(bucket, 
configs).await));
+            expected.push(format!("{bucket}: {url}"));
+        }
+        assert_eq!(actual, expected);
+    }
+
+    #[test]
+    fn test_normalize_endpoint_path_style() {
+        // Path-style leaves the endpoint as configured apart from the https 
default, since
+        // object_store appends the bucket itself
+        let cases = [
+            ("custom.endpoint.com", "https://custom.endpoint.com";),
+            ("http://custom.endpoint.com";, "http://custom.endpoint.com";),
+            (
+                "https://custom.endpoint.com/";,
                 "https://custom.endpoint.com/";,
-                "https://custom.endpoint.com/test-bucket";,
+            ),
+            ("http://minio.internal:9000";, "http://minio.internal:9000";),
+            (
+                "https://custom.endpoint.com:8443/";,
+                "https://custom.endpoint.com:8443/";,
             ),
             (
                 "https://custom.endpoint.com/path/to/resource";,
-                "https://custom.endpoint.com/path/to/resource/test-bucket";,
+                "https://custom.endpoint.com/path/to/resource";,
             ),
             (
-                "https://custom.endpoint.com/path/to/resource/";,
-                "https://custom.endpoint.com/path/to/resource/test-bucket";,
+                "s3.us-west-2.amazonaws.com",
+                "https://s3.us-west-2.amazonaws.com";,
             ),
         ];
-        for (endpoint, configured_endpoint) in cases {
-            let mut configs = HashMap::new();
-            configs.insert("fs.s3a.endpoint".to_string(), 
endpoint.to_string());
-            configs.insert("fs.s3a.path.style.access".to_string(), 
"true".to_string());
+        for (endpoint, expected) in cases {
+            assert_eq!(
+                normalize_endpoint(endpoint, "test-bucket", false),
+                Some(NormalizedEndpoint {
+                    endpoint: expected.to_string(),
+                    virtual_hosted_style_request: false,
+                }),
+                "endpoint {endpoint}"
+            );
+        }
+
+        assert_eq!(
+            normalize_endpoint("custom.endpoint.com", "my.dotted.bucket", 
false),
+            Some(NormalizedEndpoint {
+                endpoint: "https://custom.endpoint.com".to_string(),
+                virtual_hosted_style_request: false,
+            })
+        );
+    }
+
+    #[test]
+    fn test_normalize_endpoint_ip_host_forces_path_style() {
+        // The AWS SDK endpoint rules address IP-literal hosts path-style 
whatever the
+        // configuration says, since `bucket.127.0.0.1` is not a valid host
+        let cases = [
+            ("http://127.0.0.1:9000";, "http://127.0.0.1:9000";),
+            ("http://127.0.0.1";, "http://127.0.0.1";),
+            ("127.0.0.1:9000", "https://127.0.0.1:9000";),
+            ("http://[::1]:9000";, "http://[::1]:9000";),
+            ("https://[::1]";, "https://[::1]";),
+            ("[::1]:9000", "https://[::1]:9000";),
+        ];
+        for (endpoint, expected) in cases {
+            for virtual_hosted_style_request in [true, false] {
+                assert_eq!(
+                    normalize_endpoint(endpoint, "test-bucket", 
virtual_hosted_style_request),
+                    Some(NormalizedEndpoint {
+                        endpoint: expected.to_string(),
+                        virtual_hosted_style_request: false,
+                    }),
+                    "endpoint {endpoint}, requested virtual-hosted 
{virtual_hosted_style_request}"
+                );
+            }
+        }
+    }
+
+    #[test]
+    fn test_normalize_endpoint_skips_default_aws_endpoint() {
+        for virtual_hosted_style_request in [true, false] {
+            assert_eq!(
+                normalize_endpoint(
+                    "s3.amazonaws.com",
+                    "test-bucket",
+                    virtual_hosted_style_request
+                ),
+                None
+            );
+            assert_eq!(
+                normalize_endpoint("", "test-bucket", 
virtual_hosted_style_request),
+                None
+            );
+        }
+    }
+
+    #[test]
+    fn test_extract_s3_config_path_style_access() {
+        // Hadoop defaults fs.s3a.path.style.access to false (virtual-hosted) 
and, like
+        // Configuration.getBoolean, falls back to that default for 
non-boolean text
+        let cases = [
+            (None, "true", "https://test-bucket.custom.endpoint.com";),
+            (
+                Some("false"),
+                "true",
+                "https://test-bucket.custom.endpoint.com";,
+            ),
+            (
+                Some("yes"),
+                "true",
+                "https://test-bucket.custom.endpoint.com";,
+            ),
+            (Some("true"), "false", "https://custom.endpoint.com";),
+            (Some(" TRUE "), "false", "https://custom.endpoint.com";),
+        ];
+        for (path_style_access, expected_flag, expected_endpoint) in cases {
+            let mut builder =
+                TestConfigBuilder::new().with_property("endpoint", 
"custom.endpoint.com");
+            if let Some(value) = path_style_access {
+                builder = builder.with_property("path.style.access", value);
+            }
+            let s3_configs = extract_s3_config_options(&builder.build(), 
"test-bucket");
+            assert_eq!(
+                s3_configs.get(&AmazonS3ConfigKey::VirtualHostedStyleRequest),
+                Some(&expected_flag.to_string()),
+                "path.style.access {path_style_access:?}"
+            );
+            assert_eq!(
+                s3_configs.get(&AmazonS3ConfigKey::Endpoint),
+                Some(&expected_endpoint.to_string()),
+                "path.style.access {path_style_access:?}"
+            );
+        }
+    }
+
+    #[test]
+    fn test_extract_s3_config_ip_endpoint_forces_path_style() {

Review Comment:
   Several of the new tests repeat each other. This one uses the same four IP 
endpoints as `test_normalize_endpoint_ip_host_forces_path_style`, and the flag 
it checks is the `virtual_hosted_style_request` that `normalize_endpoint` 
already returns. `test_extract_s3_config_http_endpoint_keeps_scheme` repeats 
the `http://minio.internal:9000` rows of the virtual-hosted and path-style 
tables, dotted-bucket expectations appear in three tests, and 
`test_create_store_with_custom_endpoint` only asserts that `create_store` 
returns `Ok`, which every `final_url` case already needs. Since `final_url` 
pins what object_store really sends, could the `extract_s3_config_*` tests 
become one table of (properties, bucket, expected URL) next to the 
`normalize_endpoint` unit tests, covering the flag unset, `true`, `false` and 
invalid, per-bucket overrides, IP hosts, HTTP and the default endpoint? I 
expect that removes a few hundred lines with the same coverage.



##########
native/core/src/parquet/objectstore/s3.rs:
##########
@@ -2357,75 +2656,497 @@ mod tests {
     }
 
     #[test]
-    fn test_extract_s3_config_custom_endpoint() {
-        let cases = vec![
-            ("custom.endpoint.com", "https://custom.endpoint.com";),
-            ("https://custom.endpoint.com";, "https://custom.endpoint.com";),
+    fn test_normalize_endpoint_virtual_hosted_style() {
+        // Virtual-hosted addressing inserts the bucket as the leading host 
label. The scheme,
+        // port and any path suffix are preserved and a trailing slash is 
dropped.
+        let cases = [
+            (
+                "custom.endpoint.com",
+                "https://test-bucket.custom.endpoint.com";,
+            ),
+            (
+                "http://custom.endpoint.com";,
+                "http://test-bucket.custom.endpoint.com";,
+            ),
+            (
+                "https://custom.endpoint.com/";,
+                "https://test-bucket.custom.endpoint.com";,
+            ),
+            (
+                "http://minio.internal:9000";,
+                "http://test-bucket.minio.internal:9000";,
+            ),
+            (
+                "https://custom.endpoint.com:8443/";,
+                "https://test-bucket.custom.endpoint.com:8443";,
+            ),
             (
                 "https://custom.endpoint.com/path/to/resource";,
-                "https://custom.endpoint.com/path/to/resource";,
+                "https://test-bucket.custom.endpoint.com/path/to/resource";,
+            ),
+            (
+                "https://custom.endpoint.com/path/to/resource/";,
+                "https://test-bucket.custom.endpoint.com/path/to/resource";,
+            ),
+            (
+                "s3.us-west-2.amazonaws.com",
+                "https://test-bucket.s3.us-west-2.amazonaws.com";,
             ),
         ];
-        for (endpoint, configured_endpoint) in cases {
-            let mut configs = HashMap::new();
-            configs.insert("fs.s3a.endpoint".to_string(), 
endpoint.to_string());
-            let s3_configs = extract_s3_config_options(&configs, 
"test-bucket");
+        for (endpoint, expected) in cases {
             assert_eq!(
-                s3_configs.get(&AmazonS3ConfigKey::Endpoint),
-                Some(&configured_endpoint.to_string())
+                normalize_endpoint(endpoint, "test-bucket", true),
+                Some(NormalizedEndpoint {
+                    endpoint: expected.to_string(),
+                    virtual_hosted_style_request: true,
+                }),
+                "endpoint {endpoint}"
             );
         }
+
+        // A dotted bucket over HTTPS stays path-style, as the AWS SDK 
addresses it, since the
+        // dotted host falls outside S3's wildcard certificate; over HTTP it 
is virtual-hosted.
+        assert_eq!(
+            normalize_endpoint("custom.endpoint.com", "my.dotted.bucket", 
true),
+            Some(NormalizedEndpoint {
+                endpoint: "https://custom.endpoint.com".to_string(),
+                virtual_hosted_style_request: false,
+            })
+        );
+        assert_eq!(
+            normalize_endpoint("http://custom.endpoint.com";, 
"my.dotted.bucket", true),
+            Some(NormalizedEndpoint {
+                endpoint: 
"http://my.dotted.bucket.custom.endpoint.com".to_string(),
+                virtual_hosted_style_request: true,
+            })
+        );
     }
 
     #[test]
-    fn test_extract_s3_config_custom_endpoint_with_virtual_hosted_style() {
-        let cases = vec![
+    fn 
test_extract_s3_config_dotted_bucket_stays_path_style_on_default_endpoint() {
+        // No custom endpoint means the HTTPS AWS endpoint, where a dotted 
bucket must be
+        // addressed path-style whatever the flag says.
+        let configs = 
TestConfigBuilder::new().with_region("us-east-1").build();
+        let s3_configs = extract_s3_config_options(&configs, 
"review.dotted.bucket");
+        assert_eq!(
+            s3_configs.get(&AmazonS3ConfigKey::VirtualHostedStyleRequest),
+            Some(&"false".to_string())
+        );
+        assert!(!s3_configs.contains_key(&AmazonS3ConfigKey::Endpoint));
+
+        let configs = TestConfigBuilder::new()
+            .with_region("us-east-1")
+            .with_property("endpoint", "https://s3.us-east-1.amazonaws.com";)
+            .build();
+        let s3_configs = extract_s3_config_options(&configs, 
"review.dotted.bucket");
+        assert_eq!(
+            s3_configs.get(&AmazonS3ConfigKey::VirtualHostedStyleRequest),
+            Some(&"false".to_string())
+        );
+        assert_eq!(
+            s3_configs.get(&AmazonS3ConfigKey::Endpoint),
+            Some(&"https://s3.us-east-1.amazonaws.com".to_string())
+        );
+
+        let s3_configs = extract_s3_config_options(&configs, "plainbucket");
+        assert_eq!(
+            s3_configs.get(&AmazonS3ConfigKey::VirtualHostedStyleRequest),
+            Some(&"true".to_string())
+        );
+
+        // A custom HTTP endpoint keeps virtual hosting for a dotted bucket, 
as the SDK does,
+        // since the certificate rule only applies to HTTPS.
+        let configs = TestConfigBuilder::new()
+            .with_property("endpoint", "http://storage.example.test";)
+            .build();
+        let s3_configs = extract_s3_config_options(&configs, 
"review.dotted.bucket");
+        assert_eq!(
+            s3_configs.get(&AmazonS3ConfigKey::VirtualHostedStyleRequest),
+            Some(&"true".to_string())
+        );
+        assert_eq!(
+            s3_configs.get(&AmazonS3ConfigKey::Endpoint),
+            
Some(&"http://review.dotted.bucket.storage.example.test".to_string())
+        );
+    }
+
+    /// The URL object_store sends a GET for `s3a://<bucket>/object` to under 
the options Comet
+    /// derives from `configs`, read from a presigned URL so no request leaves 
the test.
+    async fn final_url(bucket: &str, configs: &HashMap<String, String>) -> 
String {
+        use object_store::signer::Signer;
+
+        let mut builder = AmazonS3Builder::new()
+            .with_url(format!("s3a://{bucket}/object"))
+            .with_allow_http(true)
+            .with_access_key_id("test_access_key")
+            .with_secret_access_key("test_secret_key");
+        for (key, value) in extract_s3_config_options(configs, bucket) {
+            builder = builder.with_config(key, value);
+        }
+        let signed = match builder.build() {

Review Comment:
   `final_url` rebuilds what `S3StoreTemplate::build` does (`with_url`, 
`with_allow_http(true)`, then each extracted option), so a later change to 
`build` would not be seen by these tests. 
`builds_from_a_template_inside_the_runtime` already shows the pattern: 
`S3StoreTemplate::new(&url, configs, 
bucket)?.build(S3Credentials::Provider(..))` with a static credential provider, 
which gives a store that can presign. Could `final_url` use that so the pinned 
URL comes from the production build path?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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

Reply via email to