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!);
}
}
}
}