Skip to content

Commit 40605b3

Browse files
committed
Fix S3Express utils and tests for auth scheme resolution pipeline migration
1 parent 21e089f commit 40605b3

9 files changed

Lines changed: 61 additions & 25 deletions

File tree

codegen/src/main/java/software/amazon/awssdk/codegen/poet/rules/EndpointResolverUtilsSpec.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -676,7 +676,7 @@ private MethodSpec setMetricValuesMethod() {
676676
b.endControlFlow();
677677

678678
if (endpointRulesSpecUtils.isS3()) {
679-
b.addStatement("$T.addS3ExpressBusinessMetricIfApplicable(executionAttributes)",
679+
b.addStatement("$T.addS3ExpressBusinessMetricIfApplicable(endpoint, executionAttributes)",
680680
ClassName.get("software.amazon.awssdk.services.s3.internal.s3express", "S3ExpressUtils"));
681681
}
682682

services/s3/src/main/java/software/amazon/awssdk/services/s3/S3Utilities.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@
3838
import software.amazon.awssdk.awscore.endpoint.AwsClientEndpointProvider;
3939
import software.amazon.awssdk.awscore.endpoint.DualstackEnabledProvider;
4040
import software.amazon.awssdk.awscore.endpoint.FipsEnabledProvider;
41-
import software.amazon.awssdk.awscore.internal.defaultsmode.DefaultsModeConfiguration;
4241
import software.amazon.awssdk.awscore.endpoints.AwsEndpointProviderUtils;
42+
import software.amazon.awssdk.awscore.internal.defaultsmode.DefaultsModeConfiguration;
4343
import software.amazon.awssdk.core.ClientEndpointProvider;
4444
import software.amazon.awssdk.core.ClientType;
4545
import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;

services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/crt/DefaultS3CrtAsyncClient.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ public void afterMarshalling(Context.AfterMarshalling context,
430430
.put(SIGNING_REGION, executionAttributes.getAttribute(AwsSignerExecutionAttribute.SIGNING_REGION))
431431
.put(S3InternalSdkHttpExecutionAttribute.OBJECT_FILE_PATH,
432432
executionAttributes.getAttribute(OBJECT_FILE_PATH))
433-
.put(USE_S3_EXPRESS_AUTH, S3ExpressUtils.useS3ExpressAuthScheme(executionAttributes))
433+
.put(USE_S3_EXPRESS_AUTH, S3ExpressUtils.isS3ExpressAuthRequest(context.request(), executionAttributes))
434434
.put(SIGNING_NAME, executionAttributes.getAttribute(SERVICE_SIGNING_NAME))
435435
.put(REQUEST_CHECKSUM_CALCULATION,
436436
executionAttributes.getAttribute(SdkInternalExecutionAttribute.REQUEST_CHECKSUM_CALCULATION))

services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/handlers/EnableTrailingChecksumInterceptor.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public SdkRequest modifyRequest(Context.ModifyRequest context, ExecutionAttribut
4848

4949
SdkRequest request = context.request();
5050
if (getObjectChecksumEnabledPerRequest(request, executionAttributes)
51-
&& S3ExpressUtils.useS3Express(executionAttributes)) {
51+
&& S3ExpressUtils.isS3ExpressBucket(request)) {
5252
return ((GetObjectRequest) request).toBuilder().checksumMode(ChecksumMode.ENABLED).build();
5353
}
5454
return request;
@@ -63,7 +63,7 @@ public SdkHttpRequest modifyHttpRequest(Context.ModifyHttpRequest context,
6363
ExecutionAttributes executionAttributes) {
6464

6565
if (getObjectChecksumEnabledPerRequest(context.request(), executionAttributes)
66-
&& !S3ExpressUtils.useS3Express(executionAttributes)) {
66+
&& !S3ExpressUtils.isS3ExpressBucket(context.request())) {
6767
return context.httpRequest()
6868
.toBuilder()
6969
.putHeader(ENABLE_CHECKSUM_REQUEST_HEADER, ENABLE_MD5_CHECKSUM_HEADER_VALUE)

services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/s3express/S3ExpressUtils.java

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,13 @@
1717

1818
import static software.amazon.awssdk.core.interceptor.SdkInternalExecutionAttribute.SELECTED_AUTH_SCHEME;
1919

20+
import java.util.List;
2021
import software.amazon.awssdk.annotations.SdkInternalApi;
22+
import software.amazon.awssdk.core.SdkRequest;
2123
import software.amazon.awssdk.core.SelectedAuthScheme;
2224
import software.amazon.awssdk.core.interceptor.ExecutionAttributes;
2325
import software.amazon.awssdk.core.interceptor.SdkInternalExecutionAttribute;
26+
import software.amazon.awssdk.core.spi.identity.AuthSchemeOptionsResolver;
2427
import software.amazon.awssdk.core.useragent.BusinessMetricFeatureId;
2528
import software.amazon.awssdk.endpoints.Endpoint;
2629
import software.amazon.awssdk.http.auth.spi.scheme.AuthSchemeOption;
@@ -36,21 +39,31 @@ private S3ExpressUtils() {
3639
}
3740

3841
/**
39-
* Returns true if the resolved endpoint contains S3Express, else false.
42+
* Determines if this request targets an S3Express bucket by checking the bucket name suffix.
4043
*/
41-
public static boolean useS3Express(ExecutionAttributes executionAttributes) {
42-
Endpoint endpoint = executionAttributes.getAttribute(SdkInternalExecutionAttribute.RESOLVED_ENDPOINT);
43-
if (endpoint != null) {
44-
String useS3Express = endpoint.attribute(KnownS3ExpressEndpointProperty.BACKEND);
45-
return S3_EXPRESS.equals(useS3Express);
44+
public static boolean isS3ExpressBucket(SdkRequest request) {
45+
return request.getValueForField("Bucket", String.class)
46+
.map(b -> b.endsWith("--x-s3"))
47+
.orElse(false);
48+
}
49+
50+
/**
51+
* Determines if this request uses S3Express auth by checking the auth scheme options.
52+
*/
53+
public static boolean isS3ExpressAuthRequest(SdkRequest request, ExecutionAttributes executionAttributes) {
54+
AuthSchemeOptionsResolver resolver =
55+
executionAttributes.getAttribute(SdkInternalExecutionAttribute.AUTH_SCHEME_OPTIONS_RESOLVER);
56+
if (resolver != null) {
57+
List<AuthSchemeOption> options = resolver.resolve(request);
58+
return options.stream().anyMatch(o -> S3ExpressAuthScheme.SCHEME_ID.equals(o.schemeId()));
4659
}
4760
return false;
4861
}
4962

5063
/**
51-
* Whether aws.auth#sigv4-s3express is used or not
64+
* Whether aws.auth#sigv4-s3express is the selected auth scheme.
5265
*/
53-
public static boolean useS3ExpressAuthScheme(ExecutionAttributes executionAttributes) {
66+
private static boolean useS3ExpressAuthScheme(ExecutionAttributes executionAttributes) {
5467
SelectedAuthScheme<?> selectedAuthScheme = executionAttributes.getAttribute(SELECTED_AUTH_SCHEME);
5568
if (selectedAuthScheme != null) {
5669
AuthSchemeOption authSchemeOption = selectedAuthScheme.authSchemeOption();
@@ -62,8 +75,10 @@ public static boolean useS3ExpressAuthScheme(ExecutionAttributes executionAttrib
6275
/**
6376
* Adds S3 Express business metric if applicable for the current operation.
6477
*/
65-
public static void addS3ExpressBusinessMetricIfApplicable(ExecutionAttributes executionAttributes) {
66-
if (executionAttributes != null && useS3Express(executionAttributes) && useS3ExpressAuthScheme(executionAttributes)) {
78+
public static void addS3ExpressBusinessMetricIfApplicable(Endpoint endpoint, ExecutionAttributes executionAttributes) {
79+
if (endpoint != null && executionAttributes != null
80+
&& S3_EXPRESS.equals(endpoint.attribute(KnownS3ExpressEndpointProperty.BACKEND))
81+
&& useS3ExpressAuthScheme(executionAttributes)) {
6782
executionAttributes.getOptionalAttribute(SdkInternalExecutionAttribute.BUSINESS_METRICS)
6883
.ifPresent(businessMetrics ->
6984
businessMetrics.addMetric(BusinessMetricFeatureId.S3_EXPRESS_BUCKET.value()));

services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/signing/DefaultS3Presigner.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@
4444
import software.amazon.awssdk.awscore.defaultsmode.DefaultsMode;
4545
import software.amazon.awssdk.awscore.endpoint.AwsClientEndpointProvider;
4646
import software.amazon.awssdk.awscore.endpoints.AwsEndpointAttribute;
47+
import software.amazon.awssdk.awscore.endpoints.AwsEndpointProviderUtils;
4748
import software.amazon.awssdk.awscore.endpoints.authscheme.EndpointAuthScheme;
4849
import software.amazon.awssdk.awscore.internal.AwsExecutionContextBuilder;
4950
import software.amazon.awssdk.awscore.internal.defaultsmode.DefaultsModeConfiguration;
50-
import software.amazon.awssdk.awscore.endpoints.AwsEndpointProviderUtils;
5151
import software.amazon.awssdk.awscore.presigner.PresignRequest;
5252
import software.amazon.awssdk.awscore.presigner.PresignedRequest;
5353
import software.amazon.awssdk.core.ClientEndpointProvider;

services/s3/src/test/java/software/amazon/awssdk/services/s3/functionaltests/S3ExpressCreateSessionTest.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,11 @@ private static final class PathStyleEnforcingInterceptor implements ExecutionInt
316316
public SdkHttpRequest modifyHttpRequest(Context.ModifyHttpRequest context, ExecutionAttributes executionAttributes) {
317317
SdkHttpRequest sdkHttpRequest = context.httpRequest();
318318
String host = sdkHttpRequest.host();
319-
String bucket = host.substring(0, host.indexOf(".localhost"));
319+
int idx = host.indexOf(".localhost");
320+
if (idx < 0) {
321+
return sdkHttpRequest;
322+
}
323+
String bucket = host.substring(0, idx);
320324

321325
return sdkHttpRequest.toBuilder().host("localhost")
322326
.encodedPath(SdkHttpUtils.appendUri(bucket, sdkHttpRequest.encodedPath()))

services/s3/src/test/java/software/amazon/awssdk/services/s3/functionaltests/S3ExpressTest.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,11 @@ private static final class PathStyleEnforcingInterceptor implements ExecutionInt
411411
public SdkHttpRequest modifyHttpRequest(Context.ModifyHttpRequest context, ExecutionAttributes executionAttributes) {
412412
SdkHttpRequest sdkHttpRequest = context.httpRequest();
413413
String host = sdkHttpRequest.host();
414-
String bucket = host.substring(0, host.indexOf(".localhost"));
414+
int idx = host.indexOf(".localhost");
415+
if (idx < 0) {
416+
return sdkHttpRequest;
417+
}
418+
String bucket = host.substring(0, idx);
415419

416420
return sdkHttpRequest.toBuilder().host("localhost")
417421
.encodedPath(SdkHttpUtils.appendUri(bucket, sdkHttpRequest.encodedPath()))

services/s3/src/test/java/software/amazon/awssdk/services/s3/internal/s3express/S3ExpressCacheFunctionalTest.java

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
4545
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
4646
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
47+
import software.amazon.awssdk.awscore.AwsRequestOverrideConfiguration;
4748
import software.amazon.awssdk.core.SelectedAuthScheme;
4849
import software.amazon.awssdk.core.interceptor.Context;
4950
import software.amazon.awssdk.core.interceptor.ExecutionAttributes;
@@ -278,21 +279,29 @@ public List<IdentityProvider<AwsCredentialsIdentity>> apiCredentialsProviders()
278279

279280
@Override
280281
public void beforeExecution(Context.BeforeExecution context, ExecutionAttributes executionAttributes) {
281-
IdentityProviders providers = executionAttributes.getAttribute(SdkInternalExecutionAttribute.IDENTITY_PROVIDERS);
282-
IdentityProvider<AwsCredentialsIdentity> awsCredentialsIdentityIdentityProvider =
283-
providers.identityProvider(AwsCredentialsIdentity.class);
282+
283+
IdentityProvider<AwsCredentialsIdentity> credentialsProvider = context.request()
284+
.overrideConfiguration()
285+
.filter(c -> c instanceof AwsRequestOverrideConfiguration)
286+
.map(c -> (AwsRequestOverrideConfiguration) c)
287+
.flatMap(AwsRequestOverrideConfiguration::credentialsIdentityProvider)
288+
.map(p -> (IdentityProvider<AwsCredentialsIdentity>) p)
289+
.orElseGet(() -> {
290+
IdentityProviders providers = executionAttributes.getAttribute(SdkInternalExecutionAttribute.IDENTITY_PROVIDERS);
291+
return providers.identityProvider(AwsCredentialsIdentity.class);
292+
});
284293

285294
String operationName = executionAttributes.getAttribute(SdkExecutionAttribute.OPERATION_NAME);
286295
if (operationName.equalsIgnoreCase("createsession")) {
287296
sessionRequests++;
288-
sessionCredentialsProvider.add(awsCredentialsIdentityIdentityProvider);
297+
sessionCredentialsProvider.add(credentialsProvider);
289298
} else {
290-
apiCredentialsProvider.add(awsCredentialsIdentityIdentityProvider);
299+
apiCredentialsProvider.add(credentialsProvider);
291300
}
292301
}
293302

294303
@Override
295-
public void beforeMarshalling(Context.BeforeMarshalling context, ExecutionAttributes executionAttributes) {
304+
public void beforeTransmission(Context.BeforeTransmission context, ExecutionAttributes executionAttributes) {
296305
SelectedAuthScheme<?> attribute = executionAttributes.getAttribute(SdkInternalExecutionAttribute.SELECTED_AUTH_SCHEME);
297306
CompletableFuture<?> identity = attribute.identity();
298307

@@ -311,7 +320,11 @@ private static final class PathStyleEnforcingInterceptor implements ExecutionInt
311320
public SdkHttpRequest modifyHttpRequest(Context.ModifyHttpRequest context, ExecutionAttributes executionAttributes) {
312321
SdkHttpRequest sdkHttpRequest = context.httpRequest();
313322
String host = sdkHttpRequest.host();
314-
String bucket = host.substring(0, host.indexOf(".localhost"));
323+
int idx = host.indexOf(".localhost");
324+
if (idx < 0) {
325+
return sdkHttpRequest;
326+
}
327+
String bucket = host.substring(0, idx);
315328

316329
return sdkHttpRequest.toBuilder().host("localhost")
317330
.encodedPath(SdkHttpUtils.appendUri(bucket, sdkHttpRequest.encodedPath()))

0 commit comments

Comments
 (0)