Files
CommunitySolidServer/src/storage/BasicConditions.ts
Joachim Van Herwegen b3da9c9fcf refactor: Restructure source code folder
This way the location of certain classes should make more sense
2021-10-12 12:51:02 +02:00

70 lines
2.2 KiB
TypeScript

import type { RepresentationMetadata } from '../http/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;
}
}