mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
feat: Generalize HTTP handler behaviour in BaseHttpHandler
This commit is contained in:
72
src/server/BaseHttpHandler.ts
Normal file
72
src/server/BaseHttpHandler.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
import type { ErrorHandler } from '../ldp/http/ErrorHandler';
|
||||
import type { RequestParser } from '../ldp/http/RequestParser';
|
||||
import type { ResponseDescription } from '../ldp/http/response/ResponseDescription';
|
||||
import type { ResponseWriter } from '../ldp/http/ResponseWriter';
|
||||
import type { Operation } from '../ldp/operations/Operation';
|
||||
import type { RepresentationPreferences } from '../ldp/representation/RepresentationPreferences';
|
||||
import { getLoggerFor } from '../logging/LogUtil';
|
||||
import { assertError } from '../util/errors/ErrorUtil';
|
||||
import type { HttpHandlerInput } from './HttpHandler';
|
||||
import { HttpHandler } from './HttpHandler';
|
||||
import type { HttpRequest } from './HttpRequest';
|
||||
import type { HttpResponse } from './HttpResponse';
|
||||
|
||||
export interface BaseHttpHandlerArgs {
|
||||
/**
|
||||
* Parses the incoming requests.
|
||||
*/
|
||||
requestParser: RequestParser;
|
||||
/**
|
||||
* Converts errors to a serializable format.
|
||||
*/
|
||||
errorHandler: ErrorHandler;
|
||||
/**
|
||||
* Writes out the response of the operation.
|
||||
*/
|
||||
responseWriter: ResponseWriter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses requests and sends the resulting Operation to the abstract `handleOperation` function.
|
||||
* Errors are caught and handled by the Errorhandler.
|
||||
* In case the `handleOperation` function returns a result it will be sent to the ResponseWriter.
|
||||
*/
|
||||
export abstract class BaseHttpHandler extends HttpHandler {
|
||||
protected readonly logger = getLoggerFor(this);
|
||||
|
||||
protected readonly requestParser: RequestParser;
|
||||
protected readonly errorHandler: ErrorHandler;
|
||||
protected readonly responseWriter: ResponseWriter;
|
||||
|
||||
protected constructor(args: BaseHttpHandlerArgs) {
|
||||
super();
|
||||
this.requestParser = args.requestParser;
|
||||
this.errorHandler = args.errorHandler;
|
||||
this.responseWriter = args.responseWriter;
|
||||
}
|
||||
|
||||
public async handle({ request, response }: HttpHandlerInput): Promise<void> {
|
||||
let result: ResponseDescription | undefined;
|
||||
let preferences: RepresentationPreferences = { type: { 'text/plain': 1 }};
|
||||
|
||||
try {
|
||||
const operation = await this.requestParser.handleSafe(request);
|
||||
({ preferences } = operation);
|
||||
result = await this.handleOperation(operation, request, response);
|
||||
this.logger.verbose(`Parsed ${operation.method} operation on ${operation.target.path}`);
|
||||
} catch (error: unknown) {
|
||||
assertError(error);
|
||||
result = await this.errorHandler.handleSafe({ error, preferences });
|
||||
}
|
||||
|
||||
if (result) {
|
||||
await this.responseWriter.handleSafe({ response, result });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the operation. Should return a ResponseDescription if it does not handle the response itself.
|
||||
*/
|
||||
protected abstract handleOperation(operation: Operation, request: HttpRequest, response: HttpResponse):
|
||||
Promise<ResponseDescription | undefined>;
|
||||
}
|
||||
Reference in New Issue
Block a user