Skip to content

Commit 8dc6bf8

Browse files
authored
Default S3 endpoint scheme to HTTPS when not specified (#127489)
1 parent 4e4d59c commit 8dc6bf8

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3Service.java

+15-1
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,21 @@ protected S3ClientBuilder buildClientBuilder(S3ClientSettings clientSettings, Sd
254254
}
255255

256256
if (Strings.hasLength(clientSettings.endpoint)) {
257-
s3clientBuilder.endpointOverride(URI.create(clientSettings.endpoint));
257+
String endpoint = clientSettings.endpoint;
258+
if ((endpoint.startsWith("http://") || endpoint.startsWith("https://")) == false) {
259+
// The SDK does not know how to interpret endpoints without a scheme prefix and will error. Therefore, when the scheme is
260+
// absent, we'll supply HTTPS as a default to avoid errors.
261+
// See https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/client-configuration.html#client-config-other-diffs
262+
endpoint = "https://" + endpoint;
263+
LOGGER.warn(
264+
"""
265+
found S3 client with endpoint [{}] that is missing a scheme, guessing it should use 'https://'; \
266+
to suppress this warning, add a scheme prefix to the [{}] setting on this node""",
267+
clientSettings.endpoint,
268+
S3ClientSettings.ENDPOINT_SETTING.getConcreteSettingForNamespace("CLIENT_NAME").getKey()
269+
);
270+
}
271+
s3clientBuilder.endpointOverride(URI.create(endpoint));
258272
}
259273

260274
return s3clientBuilder;

modules/repository-s3/src/test/java/org/elasticsearch/repositories/s3/S3ServiceTests.java

+22
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
import software.amazon.awssdk.awscore.exception.AwsServiceException;
1313
import software.amazon.awssdk.core.retry.RetryPolicyContext;
1414
import software.amazon.awssdk.core.retry.conditions.RetryCondition;
15+
import software.amazon.awssdk.http.SdkHttpClient;
1516
import software.amazon.awssdk.regions.Region;
17+
import software.amazon.awssdk.services.s3.S3Client;
1618
import software.amazon.awssdk.services.s3.endpoints.S3EndpointParams;
1719
import software.amazon.awssdk.services.s3.endpoints.internal.DefaultS3EndpointProvider;
1820
import software.amazon.awssdk.services.s3.model.S3Exception;
@@ -29,8 +31,10 @@
2931
import org.elasticsearch.watcher.ResourceWatcherService;
3032

3133
import java.io.IOException;
34+
import java.net.URI;
3235
import java.util.concurrent.atomic.AtomicBoolean;
3336

37+
import static org.hamcrest.Matchers.equalTo;
3438
import static org.mockito.Mockito.mock;
3539

3640
public class S3ServiceTests extends ESTestCase {
@@ -217,4 +221,22 @@ public void testGetClientRegionFallbackToUsEast1() {
217221
);
218222
}
219223
}
224+
225+
public void testEndpointOverrideSchemeDefaultsToHttpsWhenNotSpecified() {
226+
final S3Service s3Service = new S3Service(
227+
mock(Environment.class),
228+
Settings.EMPTY,
229+
mock(ResourceWatcherService.class),
230+
() -> Region.of("es-test-region")
231+
);
232+
final String endpointWithoutScheme = randomIdentifier() + ".ignore";
233+
S3Client s3Client = s3Service.buildClient(
234+
S3ClientSettings.getClientSettings(
235+
Settings.builder().put("s3.client.test-client.endpoint", endpointWithoutScheme).build(),
236+
"test-client"
237+
),
238+
mock(SdkHttpClient.class)
239+
);
240+
assertThat(s3Client.serviceClientConfiguration().endpointOverride().get(), equalTo(URI.create("https://" + endpointWithoutScheme)));
241+
}
220242
}

0 commit comments

Comments
 (0)