feat: Use ETagHandler for ETag generation and comparison

This commit is contained in:
Joachim Van Herwegen
2023-07-27 09:38:46 +02:00
parent 5ec6eddbfa
commit afcbfdaacf
31 changed files with 367 additions and 234 deletions

View File

@@ -3,11 +3,12 @@ import type { HttpRequest } from '../../../server/HttpRequest';
import type { BasicConditionsOptions } from '../../../storage/conditions/BasicConditions';
import { BasicConditions } from '../../../storage/conditions/BasicConditions';
import type { Conditions } from '../../../storage/conditions/Conditions';
import type { ETagHandler } from '../../../storage/conditions/ETagHandler';
import { splitCommaSeparated } from '../../../util/StringUtil';
import { ConditionsParser } from './ConditionsParser';
/**
* Creates a Conditions object based on the the following headers:
* Creates a Conditions object based on the following headers:
* - If-Modified-Since
* - If-Unmodified-Since
* - If-Match
@@ -18,6 +19,13 @@ import { ConditionsParser } from './ConditionsParser';
export class BasicConditionsParser extends ConditionsParser {
protected readonly logger = getLoggerFor(this);
protected readonly eTagHandler: ETagHandler;
public constructor(eTagHandler: ETagHandler) {
super();
this.eTagHandler = eTagHandler;
}
public async handle(request: HttpRequest): Promise<Conditions | undefined> {
const options: BasicConditionsOptions = {
matchesETag: this.parseTagHeader(request, 'if-match'),
@@ -38,7 +46,7 @@ export class BasicConditionsParser extends ConditionsParser {
// Only return a Conditions object if there is at least one condition; undefined otherwise
this.logger.debug(`Found the following conditions: ${JSON.stringify(options)}`);
if (Object.values(options).some((val): boolean => typeof val !== 'undefined')) {
return new BasicConditions(options);
return new BasicConditions(this.eTagHandler, options);
}
}

View File

@@ -1,4 +1,4 @@
import { getETag } from '../../storage/conditions/Conditions';
import type { ETagHandler } from '../../storage/conditions/ETagHandler';
import type { ResourceStore } from '../../storage/ResourceStore';
import { NotImplementedHttpError } from '../../util/errors/NotImplementedHttpError';
import { assertReadConditions } from '../../util/ResourceUtil';
@@ -14,10 +14,12 @@ import { OperationHandler } from './OperationHandler';
*/
export class GetOperationHandler extends OperationHandler {
private readonly store: ResourceStore;
private readonly eTagHandler: ETagHandler;
public constructor(store: ResourceStore) {
public constructor(store: ResourceStore, eTagHandler: ETagHandler) {
super();
this.store = store;
this.eTagHandler = eTagHandler;
}
public async canHandle({ operation }: OperationHandlerInput): Promise<void> {
@@ -33,7 +35,7 @@ export class GetOperationHandler extends OperationHandler {
assertReadConditions(body, operation.conditions);
// Add the ETag of the returned representation
const etag = getETag(body.metadata);
const etag = this.eTagHandler.getETag(body.metadata);
body.metadata.set(HH.terms.etag, etag);
return new OkResponseDescription(body.metadata, body.data);

View File

@@ -1,4 +1,4 @@
import { getETag } from '../../storage/conditions/Conditions';
import type { ETagHandler } from '../../storage/conditions/ETagHandler';
import type { ResourceStore } from '../../storage/ResourceStore';
import { NotImplementedHttpError } from '../../util/errors/NotImplementedHttpError';
import { assertReadConditions } from '../../util/ResourceUtil';
@@ -14,10 +14,12 @@ import { OperationHandler } from './OperationHandler';
*/
export class HeadOperationHandler extends OperationHandler {
private readonly store: ResourceStore;
private readonly eTagHandler: ETagHandler;
public constructor(store: ResourceStore) {
public constructor(store: ResourceStore, eTagHandler: ETagHandler) {
super();
this.store = store;
this.eTagHandler = eTagHandler;
}
public async canHandle({ operation }: OperationHandlerInput): Promise<void> {
@@ -37,7 +39,7 @@ export class HeadOperationHandler extends OperationHandler {
assertReadConditions(body, operation.conditions);
// Add the ETag of the returned representation
const etag = getETag(body.metadata);
const etag = this.eTagHandler.getETag(body.metadata);
body.metadata.set(HH.terms.etag, etag);
return new OkResponseDescription(body.metadata);