feat: Create conditions based on input headers

This commit is contained in:
Joachim Van Herwegen
2021-08-16 15:51:32 +02:00
parent 77d695c8b6
commit 20f783a581
26 changed files with 406 additions and 34 deletions

View File

@@ -0,0 +1,69 @@
import type { RepresentationMetadata } from '../ldp/representation/RepresentationMetadata';
import { DC } from '../util/Vocabularies';
import { getETag } from './Conditions';
import type { Conditions } from './Conditions';
export interface BasicConditionsOptions {
matchesETag?: string[];
notMatchesETag?: string[];
modifiedSince?: Date;
unmodifiedSince?: Date;
}
/**
* Stores all the relevant Conditions values and matches them based on RFC7232.
*/
export class BasicConditions implements Conditions {
public readonly matchesETag?: string[];
public readonly notMatchesETag?: string[];
public readonly modifiedSince?: Date;
public readonly unmodifiedSince?: Date;
public constructor(options: BasicConditionsOptions) {
this.matchesETag = options.matchesETag;
this.notMatchesETag = options.notMatchesETag;
this.modifiedSince = options.modifiedSince;
this.unmodifiedSince = options.unmodifiedSince;
}
public matchesMetadata(metadata?: RepresentationMetadata): boolean {
if (!metadata) {
// RFC7232: ...If-Match... If the field-value is "*", the condition is false if the origin server
// does not have a current representation for the target resource.
return !this.matchesETag?.includes('*');
}
const modified = metadata.get(DC.terms.modified);
const modifiedDate = modified ? new Date(modified.value) : undefined;
const etag = getETag(metadata);
return this.matches(etag, modifiedDate);
}
public matches(eTag?: string, lastModified?: Date): boolean {
// RFC7232: ...If-None-Match... If the field-value is "*", the condition is false if the origin server
// has a current representation for the target resource.
if (this.notMatchesETag?.includes('*')) {
return false;
}
if (eTag) {
if (this.matchesETag && !this.matchesETag.includes(eTag) && !this.matchesETag.includes('*')) {
return false;
}
if (this.notMatchesETag?.includes(eTag)) {
return false;
}
}
if (lastModified) {
if (this.modifiedSince && lastModified < this.modifiedSince) {
return false;
}
if (this.unmodifiedSince && lastModified > this.unmodifiedSince) {
return false;
}
}
return true;
}
}