public validate()

in src/blob/conditions/WriteConditionalHeadersValidator.ts [85:181]


  public validate(
    context: Context,
    conditionalHeaders: IConditionalHeaders,
    resource: IConditionResource
  ): void {
    this.validateCombinations(context, conditionalHeaders);
    if (!resource.exist) {
      if (
        conditionalHeaders.ifNoneMatch &&
        conditionalHeaders.ifNoneMatch.length > 0
      ) {
        // If a request specifies both the If-None-Match and If-Modified-Since headers,
        // the request is evaluated based on the criteria specified in If-None-Match.
        // Skip for non exist blob
        return;
      }

      if (conditionalHeaders.ifMatch && conditionalHeaders.ifMatch.length > 0) {
        // If a request specifies both the If-Match and If-Unmodified-Since headers,
        // the request is evaluated based on the criteria specified in If-Match.
        if (conditionalHeaders.ifMatch[0] !== "*") {
          throw StorageErrorFactory.getConditionNotMet(context.contextId!);
        }
        return;
      }

      if (conditionalHeaders.ifModifiedSince) {
        // Skip for non exist blob
        return;
      }

      if (conditionalHeaders.ifUnmodifiedSince) {
        // Skip for non exist blob
        return;
      }
    } else {
      if (
        conditionalHeaders.ifNoneMatch &&
        conditionalHeaders.ifNoneMatch.length > 0
      ) {
        if (conditionalHeaders.ifNoneMatch[0] === "*") {
          // According to restful doc, specify the wildcard character (*) to perform the operation
          // only if the resource does not exist, and fail the operation if it does exist.
          // However, Azure Storage Set Blob Properties Operation for an existing blob doesn't return 412 with *
          // TODO: Check accurate behavior for different write operations
          // Put Blob, Commit Block List has special logic for ifNoneMatch equals *, will return 409 conflict for existing blob, will handled in createBlob metadata store.
          // throw StorageErrorFactory.getConditionNotMet(context.contextId!);
          return;
        }
        if (conditionalHeaders.ifNoneMatch[0] === resource.etag) {
          throw StorageErrorFactory.getConditionNotMet(context.contextId!);
        }

        // Stop processing
        // If a request specifies both the If-None-Match and If-Modified-Since headers,
        // the request is evaluated based on the criteria specified in If-None-Match.
        return;
      }

      if (conditionalHeaders.ifMatch && conditionalHeaders.ifMatch.length > 0) {
        if (
          conditionalHeaders.ifMatch[0] !== "*" &&
          conditionalHeaders.ifMatch[0] !== resource.etag
        ) {
          throw StorageErrorFactory.getConditionNotMet(context.contextId!);
        }

        // Stop processing
        // If a request specifies both the If-Match and If-Unmodified-Since headers,
        // the request is evaluated based on the criteria specified in If-Match.
        return;
      }

      if (conditionalHeaders.ifModifiedSince) {
        if (resource.lastModified <= conditionalHeaders.ifModifiedSince) {
          throw StorageErrorFactory.getConditionNotMet(context.contextId!);
        }
        return;
      }

      if (conditionalHeaders.ifUnmodifiedSince) {
        if (conditionalHeaders.ifUnmodifiedSince < resource.lastModified) {
          throw StorageErrorFactory.getConditionNotMet(context.contextId!);
        }
        return;
      }

      if (conditionalHeaders.ifTags) {
        const validateFunction = generateQueryBlobWithTagsWhereFunction(context, conditionalHeaders.ifTags, 'x-ms-if-tags');

        if (conditionalHeaders?.ifTags !== undefined
          && validateFunction(resource.blobItemWithTags).length === 0) {
          throw StorageErrorFactory.getConditionNotMet(context.contextId!);
        }
      }
    }
  }