@Override
    protected String calculateContentHash(SignableRequest<?> request) {
        // To be consistent with other service clients using sig-v4,
        // we just set the header as "required", and AWS4Signer.sign() will be
        // notified to pick up the header value returned by this method.
        request.addHeader(X_AMZ_CONTENT_SHA256, "required");

        if (isPayloadSigningEnabled(request)) {
            if (useChunkEncoding(request)) {
                final String contentLength = request.getHeaders().get(Headers.CONTENT_LENGTH);
                final long originalContentLength;
                if (contentLength != null) {
                    originalContentLength = Long.parseLong(contentLength);
                } else {
                    /**
                     * "Content-Length" header could be missing if the caller is
                     * uploading a stream without setting Content-Length in
                     * ObjectMetadata. Before using sigv4, we rely on HttpClient to
                     * add this header by using BufferedHttpEntity when creating the
                     * HttpRequest object. But now, we need this information
                     * immediately for the signing process, so we have to cache the
                     * stream here.
                     */
                    try {
                        originalContentLength = getContentLength(request);
                    } catch (IOException e) {
                        throw new SdkClientException(
                                "Cannot get the content-length of the request content.", e);
                    }
                }
                request.addHeader("x-amz-decoded-content-length",
                                  Long.toString(originalContentLength));
                // Make sure "Content-Length" header is not empty so that HttpClient
                // won't cache the stream again to recover Content-Length
                request.addHeader(Headers.CONTENT_LENGTH, Long.toString(
                        AwsChunkedEncodingInputStream
                                .calculateStreamContentLength(originalContentLength)));
                return CONTENT_SHA_256;
            } else {
                return super.calculateContentHash(request);
            }
        }

        return UNSIGNED_PAYLOAD;
    }
Returns the pre-defined header value and set other necessary headers if
the request needs to be chunk-encoded. Otherwise calls the superclass
method which calculates the hash of the whole content for signing.
aws-java-sdk-s3/src/main/java/com/amazonaws/services/s3/internal/AWSS3V4Signer.java