Skip to content

Commit fae444b

Browse files
fix(s3): strip endpoint scheme from env vars and honor ssl.enabled=true
1 parent 7d6f80f commit fae444b

2 files changed

Lines changed: 37 additions & 23 deletions

File tree

‎src/iceberg/arrow/s3/arrow_s3_file_io.cc‎

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,17 @@ Status EnsureS3Initialized() {
7575
return {};
7676
}
7777

78+
// Splits any URI scheme off `endpoint` into `options.scheme`, returning the bare
79+
// host[:port] that Arrow's `endpoint_override` expects.
80+
std::string SplitEndpointScheme(std::string_view endpoint,
81+
::arrow::fs::S3Options& options) {
82+
if (const auto pos = endpoint.find("://"); pos != std::string_view::npos) {
83+
options.scheme = std::string(endpoint.substr(0, pos));
84+
endpoint = endpoint.substr(pos + 3);
85+
}
86+
return std::string(endpoint);
87+
}
88+
7889
#endif
7990

8091
} // namespace
@@ -116,27 +127,17 @@ Result<::arrow::fs::S3Options> ConfigureS3Options(
116127
options.region = *region;
117128
}
118129

119-
// Configure endpoint (for MinIO, LocalStack, OSS, etc.)
130+
// Configure endpoint (for MinIO, LocalStack, OSS, etc.) from `s3.endpoint` or
131+
// the AWS standard env vars.
120132
if (const auto* endpoint = FindProperty(properties, S3Properties::kEndpoint);
121133
endpoint != nullptr) {
122-
// `s3.endpoint` may be a full URI; Arrow wants host[:port], so strip the scheme.
123-
std::string_view ep = *endpoint;
124-
if (const auto pos = ep.find("://"); pos != std::string_view::npos) {
125-
options.scheme = std::string(ep.substr(0, pos));
126-
ep = ep.substr(pos + 3);
127-
}
128-
options.endpoint_override = std::string(ep);
129-
} else {
130-
// Fall back to AWS standard environment variables for endpoint override
131-
const char* s3_endpoint_env = std::getenv("AWS_ENDPOINT_URL_S3");
132-
if (s3_endpoint_env != nullptr) {
133-
options.endpoint_override = s3_endpoint_env;
134-
} else {
135-
const char* endpoint_env = std::getenv("AWS_ENDPOINT_URL");
136-
if (endpoint_env != nullptr) {
137-
options.endpoint_override = endpoint_env;
138-
}
139-
}
134+
options.endpoint_override = SplitEndpointScheme(*endpoint, options);
135+
} else if (const char* s3_endpoint_env = std::getenv("AWS_ENDPOINT_URL_S3");
136+
s3_endpoint_env != nullptr) {
137+
options.endpoint_override = SplitEndpointScheme(s3_endpoint_env, options);
138+
} else if (const char* endpoint_env = std::getenv("AWS_ENDPOINT_URL");
139+
endpoint_env != nullptr) {
140+
options.endpoint_override = SplitEndpointScheme(endpoint_env, options);
140141
}
141142

142143
ICEBERG_ASSIGN_OR_RAISE(const auto path_style_access,
@@ -145,12 +146,11 @@ Result<::arrow::fs::S3Options> ConfigureS3Options(
145146
options.force_virtual_addressing = !*path_style_access;
146147
}
147148

148-
// Configure SSL. Explicit `s3.ssl.enabled` overrides any scheme derived from
149-
// the endpoint above.
149+
// Explicit `s3.ssl.enabled` overrides any endpoint-derived scheme.
150150
ICEBERG_ASSIGN_OR_RAISE(const auto ssl_enabled,
151151
ParseOptionalBool(properties, S3Properties::kSslEnabled));
152-
if (ssl_enabled.has_value() && !*ssl_enabled) {
153-
options.scheme = "http";
152+
if (ssl_enabled.has_value()) {
153+
options.scheme = *ssl_enabled ? "https" : "http";
154154
}
155155

156156
// Configure timeouts

‎src/iceberg/test/arrow_s3_file_io_test.cc‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,20 @@ TEST_F(ArrowS3FileIOTest, ConfigureS3OptionsKeepsSchemelessEndpoint) {
227227
EXPECT_EQ(result->endpoint_override, "localhost:9000");
228228
}
229229

230+
TEST_F(ArrowS3FileIOTest, ConfigureS3OptionsSslEnabledOverridesEndpointScheme) {
231+
auto https =
232+
ConfigureS3Options({{std::string(S3Properties::kEndpoint), "http://localhost:9000"},
233+
{std::string(S3Properties::kSslEnabled), "true"}});
234+
ASSERT_THAT(https, IsOk());
235+
EXPECT_EQ(https->scheme, "https");
236+
237+
auto http = ConfigureS3Options(
238+
{{std::string(S3Properties::kEndpoint), "https://localhost:9000"},
239+
{std::string(S3Properties::kSslEnabled), "false"}});
240+
ASSERT_THAT(http, IsOk());
241+
EXPECT_EQ(http->scheme, "http");
242+
}
243+
230244
TEST_F(ArrowS3FileIOTest,
231245
ConfigureS3OptionsPathStyleAccessFalseEnablesVirtualAddressing) {
232246
auto result =

0 commit comments

Comments
 (0)