• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License").
5  * You may not use this file except in compliance with the License.
6  * A copy of the License is located at
7  *
8  *  http://aws.amazon.com/apache2.0
9  *
10  * or in the "license" file accompanying this file. This file is distributed
11  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12  * express or implied. See the License for the specific language governing
13  * permissions and limitations under the License.
14  */
15 
16 package software.amazon.awssdk.services.s3.internal.handlers;
17 
18 import static software.amazon.awssdk.services.s3.internal.checksums.ChecksumConstant.ENABLE_CHECKSUM_REQUEST_HEADER;
19 import static software.amazon.awssdk.services.s3.internal.checksums.ChecksumConstant.ENABLE_MD5_CHECKSUM_HEADER_VALUE;
20 import static software.amazon.awssdk.services.s3.internal.checksums.ChecksumConstant.S3_MD5_CHECKSUM_LENGTH;
21 import static software.amazon.awssdk.services.s3.internal.checksums.ChecksumsEnabledValidator.getObjectChecksumEnabledPerRequest;
22 import static software.amazon.awssdk.services.s3.internal.checksums.ChecksumsEnabledValidator.getObjectChecksumEnabledPerResponse;
23 
24 import software.amazon.awssdk.annotations.SdkInternalApi;
25 import software.amazon.awssdk.core.SdkRequest;
26 import software.amazon.awssdk.core.SdkResponse;
27 import software.amazon.awssdk.core.interceptor.Context;
28 import software.amazon.awssdk.core.interceptor.ExecutionAttributes;
29 import software.amazon.awssdk.core.interceptor.ExecutionInterceptor;
30 import software.amazon.awssdk.http.SdkHttpRequest;
31 import software.amazon.awssdk.http.SdkHttpResponse;
32 import software.amazon.awssdk.services.s3.internal.s3express.S3ExpressUtils;
33 import software.amazon.awssdk.services.s3.model.ChecksumMode;
34 import software.amazon.awssdk.services.s3.model.GetObjectRequest;
35 import software.amazon.awssdk.services.s3.model.GetObjectResponse;
36 import software.amazon.awssdk.utils.Validate;
37 
38 @SdkInternalApi
39 public final class EnableTrailingChecksumInterceptor implements ExecutionInterceptor {
40 
41     /**
42      * Enable {@link ChecksumMode} for {@link GetObjectRequest} if trailing checksum is enabled from config,
43      * {@link ChecksumMode} is disabled, and is S3Express.
44      * TODO (s3express) - refactor to migrate out s3express specific code
45      */
46     @Override
modifyRequest(Context.ModifyRequest context, ExecutionAttributes executionAttributes)47     public SdkRequest modifyRequest(Context.ModifyRequest context, ExecutionAttributes executionAttributes) {
48 
49         SdkRequest request = context.request();
50         if (getObjectChecksumEnabledPerRequest(request, executionAttributes)
51             && S3ExpressUtils.useS3Express(executionAttributes)) {
52             return ((GetObjectRequest) request).toBuilder().checksumMode(ChecksumMode.ENABLED).build();
53         }
54         return request;
55     }
56 
57     /**
58      * Append trailing checksum header for {@link GetObjectRequest} if trailing checksum is enabled from config,
59      * {@link ChecksumMode} is disabled, and is not S3Express.
60      */
61     @Override
modifyHttpRequest(Context.ModifyHttpRequest context, ExecutionAttributes executionAttributes)62     public SdkHttpRequest modifyHttpRequest(Context.ModifyHttpRequest context,
63                                             ExecutionAttributes executionAttributes) {
64 
65         if (getObjectChecksumEnabledPerRequest(context.request(), executionAttributes)
66             && !S3ExpressUtils.useS3Express(executionAttributes)) {
67             return context.httpRequest()
68                           .toBuilder()
69                           .putHeader(ENABLE_CHECKSUM_REQUEST_HEADER, ENABLE_MD5_CHECKSUM_HEADER_VALUE)
70                           .build();
71         }
72 
73         return context.httpRequest();
74     }
75 
76     /**
77      * Subtract the contentLength of {@link GetObjectResponse} if trailing checksums is enabled.
78      */
79     @Override
modifyResponse(Context.ModifyResponse context, ExecutionAttributes executionAttributes)80     public SdkResponse modifyResponse(Context.ModifyResponse context, ExecutionAttributes executionAttributes) {
81         SdkResponse response = context.response();
82         SdkHttpResponse httpResponse = context.httpResponse();
83 
84         if (getObjectChecksumEnabledPerResponse(context.request(), httpResponse)) {
85             GetObjectResponse getResponse = (GetObjectResponse) response;
86             Long contentLength = getResponse.contentLength();
87             Validate.notNull(contentLength, "Service returned null 'Content-Length'.");
88             return getResponse.toBuilder()
89                               .contentLength(contentLength - S3_MD5_CHECKSUM_LENGTH)
90                               .build();
91         }
92 
93         return response;
94     }
95 }
96