All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.qcloud.cos.internal.SkipMd5CheckStrategy Maven / Gradle / Ivy

The newest version!
package com.qcloud.cos.internal;

import com.qcloud.cos.model.GetObjectRequest;
import com.qcloud.cos.model.ObjectMetadata;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.model.UploadPartRequest;

/**
 * Logic for determining whether MD5 checksum validation should be performed or not.
 */
public class SkipMd5CheckStrategy {

    /**
     * System property to disable MD5 validation for GetObject. Any value set for this property will
     * disable validation.
     */
    public static final String DISABLE_GET_OBJECT_MD5_VALIDATION_PROPERTY =
            "com.Qcloud.services.cos.disableGetObjectMD5Validation";

    /**
     * System property to disable MD5 validation for both PutObject and UploadPart. Any value set
     * for this property will disable validation.
     */
    public static final String DISABLE_PUT_OBJECT_MD5_VALIDATION_PROPERTY =
            "com.Qcloud.services.cos.disablePutObjectMD5Validation";

    public static final SkipMd5CheckStrategy INSTANCE = new SkipMd5CheckStrategy();

    // Singleton
    private SkipMd5CheckStrategy() {}

    /**
     * Determines whether the client should use the {@link Headers#ETAG} header returned by COS to
     * validate the integrity of the message client side based on the server response. We skip the
     * client side check if any of the following conditions are true:
     * 
    *
  1. The system property {@value #DISABLE_GET_OBJECT_MD5_VALIDATION_PROPERTY} is set
  2. *
  3. The request involves SSE-C or SSE-KMS
  4. *
  5. The Etag header is missing
  6. *
  7. The Etag indicates that the object was created by a MultiPart Upload
  8. *
* * @return True if client side validation should be skipped, false otherwise. */ public boolean skipClientSideValidationPerGetResponse(ObjectMetadata metadata) { if (isGetObjectMd5ValidationDisabledByProperty()) { return true; } return skipClientSideValidationPerResponse(metadata); } /** * Determines whether the client should use the {@link Headers#ETAG} header returned by COS to * validate the integrity of the message client side based on the server response. We skip the * client side check if any of the following conditions are true: *
    *
  1. The system property {@value #DISABLE_PUT_OBJECT_MD5_VALIDATION_PROPERTY} is set
  2. *
  3. The request involves SSE-C or SSE-KMS
  4. *
  5. The Etag header is missing
  6. *
* * @return True if client side validation should be skipped, false otherwise. */ public boolean skipClientSideValidationPerPutResponse(ObjectMetadata metadata) { if (isPutObjectMd5ValidationDisabledByProperty()) { return true; } return skipClientSideValidationPerResponse(metadata); } /** * Determines whether the client should use the {@link Headers#ETAG} header returned by COS to * validate the integrity of the message client side based on the server response. We skip the * client side check if any of the following conditions are true: *
    *
  1. The system property {@value #DISABLE_PUT_OBJECT_MD5_VALIDATION_PROPERTY} is set
  2. *
  3. The request involves SSE-C or SSE-KMS
  4. *
  5. The Etag header is missing
  6. *
* * @return True if client side validation should be skipped, false otherwise. */ public boolean skipClientSideValidationPerUploadPartResponse(ObjectMetadata metadata) { return skipClientSideValidationPerPutResponse(metadata); } /** * Conveience method to determine whether to do client side validation of a GetObject call based * on both the request and the response. See * {@link #skipClientSideValidationPerRequest(GetObjectRequest)} and * {@link #skipClientSideValidationPerGetResponse(ObjectMetadata)} for more details on the * criterion. * * @param request Original {@link GetObjectRequest} * @param returnedMetadata Metadata returned in {@link COSObject} * @return True if client side validation should be skipped, false otherwise. */ /* public boolean skipClientSideValidation(GetObjectRequest request, ObjectMetadata returnedMetadata) { return skipClientSideValidationPerRequest(request) || skipClientSideValidationPerGetResponse(returnedMetadata); } */ /** * Determines whether the client should use the {@link Headers#ETAG} header returned by COS to * validate the integrity of the message client side. We skip the client side check if any of * the following conditions are true: *
    *
  1. The system property {@value #DISABLE_PUT_OBJECT_MD5_VALIDATION_PROPERTY} is set
  2. *
  3. The request involves SSE-C or SSE-KMS
  4. *
* * @return True if client side validation should be skipped, false otherwise. */ public boolean skipClientSideValidationPerRequest(PutObjectRequest request) { if (isPutObjectMd5ValidationDisabledByProperty()) { return true; } return putRequestInvolvesSse(request) || metadataInvolvesSse(request.getMetadata()); } /** * Determines whether the client should use the {@link Headers#ETAG} header returned by COS to * validate the integrity of the message client side. We skip the client side check if any of * the following conditions are true: *
    *
  1. The system property {@value #DISABLE_PUT_OBJECT_MD5_VALIDATION_PROPERTY} is set
  2. *
  3. The request involves SSE-C or SSE-KMS
  4. *
* * @return True if client side validation should be skipped, false otherwise. */ public boolean skipClientSideValidationPerRequest(UploadPartRequest request) { if (isPutObjectMd5ValidationDisabledByProperty()) { return true; } return false; // return request.getSSECustomerKey() != null; } /** * Determines whether the client should calculate and send the {@link Headers#CONTENT_MD5} * header to be validated by COS per the request. *

* Currently we always try and do server side validation unless it's been explicitly disabled by * the {@value #DISABLE_PUT_OBJECT_MD5_VALIDATION_PROPERTY} property. Whether or not we actually * calculate the MD5 header is determined in the client based on the source of the data (i.e. if * it's a file we calculate, if not then we don't) *

*/ public boolean skipServerSideValidation(PutObjectRequest request) { if (isPutObjectMd5ValidationDisabledByProperty()) { return true; } return false; } /** * Determines whether the client should calculate and send the {@link Headers#CONTENT_MD5} * header to be validated by COS per the request. *

* Currently we always try and do server side validation unless it's been explicitly disabled by * the {@value #DISABLE_PUT_OBJECT_MD5_VALIDATION_PROPERTY} property. Whether or not we actually * calculate the MD5 header is determined in the client based on the source of the data (i.e. if * it's a file we calculate, if not then we don't) *

*/ /* public boolean skipServerSideValidation(UploadPartRequest request) { if (isPutObjectMd5ValidationDisabledByProperty()) { return true; } return false; } */ /** * Based on the given {@link GetObjectRequest}, returns whether the specified request should * skip MD5 check on the requested object content. Specifically, MD5 check should be skipped if * one of the following conditions are true: *
    *
  1. The system property {@value #DISABLE_GET_OBJECT_MD5_VALIDATION_PROPERTY} is set.
  2. *
  3. The request is a range-get operation
  4. *
  5. The request is a GET object operation that involves SSE-C
  6. *
* Otherwise, MD5 check should not be skipped. */ public boolean skipClientSideValidationPerRequest(GetObjectRequest request) { if (isGetObjectMd5ValidationDisabledByProperty()) { return true; } // Skip MD5 check for range get if (request.getRange() != null) { return true; } return false; } private boolean skipClientSideValidationPerResponse(ObjectMetadata metadata) { if (metadata == null) { return true; } // If Etag is not provided or was computed from a multipart upload then skip the check, the // etag won't be the MD5 of the original content if (metadata.getETag() == null || isMultipartUploadETag(metadata.getETag())) { return true; } return metadataInvolvesSse(metadata); } private boolean isGetObjectMd5ValidationDisabledByProperty() { return System.getProperty(DISABLE_GET_OBJECT_MD5_VALIDATION_PROPERTY) != null; } private boolean isPutObjectMd5ValidationDisabledByProperty() { return System.getProperty(DISABLE_PUT_OBJECT_MD5_VALIDATION_PROPERTY) != null; } /** * If SSE-C or SSE-KMS is involved then the Etag will be the MD5 of the ciphertext not the * plaintext so we can't validate it client side. Plain SSE with COS managed keys will return an * Etag that does match the MD5 of the plaintext so it's still eligible for client side * validation. * * @param metadata Metadata of request or response * @return True if the metadata indicates that SSE-C or SSE-KMS is used. False otherwise */ private boolean metadataInvolvesSse(ObjectMetadata metadata) { if (metadata == null) { return false; } // return containsNonNull(metadata.getSSECustomerAlgorithm(), // metadata.getSSECustomerKeyMd5(), // metadata.getSSECOSKmsKeyId()); return true; } /** * @param request * @return True if {@link PutObjectRequest} has been configured to use SSE-C or SSE-KMS */ private boolean putRequestInvolvesSse(PutObjectRequest request) { // return containsNonNull(request.getSSECustomerKey(), // request.getSSECOSKeyManagementParams()); return true; } /** * Returns true if the specified ETag was from a multipart upload. * * @param eTag The ETag to test. * @return True if the specified ETag was from a multipart upload, otherwise false it if belongs * to an object that was uploaded in a single part. */ private static boolean isMultipartUploadETag(String eTag) { return eTag.contains("-"); } /** * Helper method to avoid long chains of non null checks * * @param items * @return True if any of the provided items is not null. False if all items are null. */ private static boolean containsNonNull(Object... items) { for (Object item : items) { if (item != null) { return true; } } return false; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy