diff --git a/project/src/di/Serializer.ts b/project/src/di/Serializer.ts index 38aa5f5b..8bbb8569 100644 --- a/project/src/di/Serializer.ts +++ b/project/src/di/Serializer.ts @@ -1,7 +1,7 @@ import { IncomingMessage, ServerResponse } from "node:http"; export class Serializer { - public serialize(sessionID: string, req: IncomingMessage, resp: ServerResponse, body: any): void { + public async serialize(sessionID: string, req: IncomingMessage, resp: ServerResponse, body: any): Promise { throw new Error("Should be extended and overrode"); } diff --git a/project/src/routers/ImageRouter.ts b/project/src/routers/ImageRouter.ts index 1958ad9a..911ca3e0 100644 --- a/project/src/routers/ImageRouter.ts +++ b/project/src/routers/ImageRouter.ts @@ -16,13 +16,13 @@ export class ImageRouter { this.imageRouteService.addRoute(key, valueToAdd); } - public sendImage(sessionID: string, req: IncomingMessage, resp: ServerResponse, body: any): void { + public async sendImage(sessionID: string, req: IncomingMessage, resp: ServerResponse, body: any): Promise { // remove file extension const url = this.vfs.stripExtension(req.url); // send image if (this.imageRouteService.existsByKey(url)) { - this.httpFileUtil.sendFile(resp, this.imageRouteService.getByKey(url)); + await this.httpFileUtil.sendFileAsync(resp, this.imageRouteService.getByKey(url)); } } diff --git a/project/src/routers/serializers/BundleSerializer.ts b/project/src/routers/serializers/BundleSerializer.ts index 14e6756f..6cf1a6f7 100644 --- a/project/src/routers/serializers/BundleSerializer.ts +++ b/project/src/routers/serializers/BundleSerializer.ts @@ -15,7 +15,7 @@ export class BundleSerializer extends Serializer { super(); } - public override serialize(sessionID: string, req: IncomingMessage, resp: ServerResponse, body: any): void { + public override async serialize(sessionID: string, req: IncomingMessage, resp: ServerResponse, body: any): Promise { const key = decodeURI(req.url.split("/bundle/")[1]); const bundle = this.bundleLoader.getBundle(key); if (!bundle) { @@ -29,7 +29,7 @@ export class BundleSerializer extends Serializer { return; } - this.httpFileUtil.sendFile(resp, `${bundle.modpath}/bundles/${bundle.filename}`); + await this.httpFileUtil.sendFileAsync(resp, `${bundle.modpath}/bundles/${bundle.filename}`); } public override canHandle(route: string): boolean { diff --git a/project/src/routers/serializers/ImageSerializer.ts b/project/src/routers/serializers/ImageSerializer.ts index 690c15e7..b1be27e0 100644 --- a/project/src/routers/serializers/ImageSerializer.ts +++ b/project/src/routers/serializers/ImageSerializer.ts @@ -9,8 +9,8 @@ export class ImageSerializer extends Serializer { super(); } - public override serialize(sessionID: string, req: IncomingMessage, resp: ServerResponse, body: any): void { - this.imageRouter.sendImage(sessionID, req, resp, body); + public override async serialize(sessionID: string, req: IncomingMessage, resp: ServerResponse, body: any): Promise { + await this.imageRouter.sendImage(sessionID, req, resp, body); } public override canHandle(route: string): boolean { diff --git a/project/src/routers/serializers/NotifySerializer.ts b/project/src/routers/serializers/NotifySerializer.ts index b27b9d80..54a51fa0 100644 --- a/project/src/routers/serializers/NotifySerializer.ts +++ b/project/src/routers/serializers/NotifySerializer.ts @@ -15,7 +15,7 @@ export class NotifySerializer extends Serializer { super(); } - public override serialize(_sessionID: string, req: IncomingMessage, resp: ServerResponse, _: any): void { + public override async serialize(_sessionID: string, req: IncomingMessage, resp: ServerResponse, _: any): Promise { const splittedUrl = req.url.split("/"); const tmpSessionID = splittedUrl[splittedUrl.length - 1].split("?last_id")[0]; @@ -23,7 +23,7 @@ export class NotifySerializer extends Serializer { * Take our array of JSON message objects and cast them to JSON strings, so that they can then * be sent to client as NEWLINE separated strings... yup. */ - this.notifierController + await this.notifierController .notifyAsync(tmpSessionID) .then((messages: any) => messages.map((message: any) => this.jsonUtil.serialize(message)).join("\n")) .then((text) => this.httpServerHelper.sendTextJson(resp, text)); diff --git a/project/src/servers/http/SptHttpListener.ts b/project/src/servers/http/SptHttpListener.ts index 67e2faa8..bc5b89d6 100644 --- a/project/src/servers/http/SptHttpListener.ts +++ b/project/src/servers/http/SptHttpListener.ts @@ -107,7 +107,7 @@ export class SptHttpListener implements IHttpListener { // Not debug, minority of requests need a serializer to do the job (IMAGE/BUNDLE/NOTIFY) const serialiser = this.serializers.find((x) => x.canHandle(output)); if (serialiser) { - serialiser.serialize(sessionID, req, resp, bodyInfo); + await serialiser.serialize(sessionID, req, resp, bodyInfo); } else { // No serializer can handle the request (majority of requests dont), zlib the output and send response back await this.sendZlibJson(resp, output, sessionID); diff --git a/project/src/utils/HttpFileUtil.ts b/project/src/utils/HttpFileUtil.ts index 980cb442..f425db8d 100644 --- a/project/src/utils/HttpFileUtil.ts +++ b/project/src/utils/HttpFileUtil.ts @@ -2,21 +2,20 @@ import fs from "node:fs"; import { ServerResponse } from "node:http"; import { HttpServerHelper } from "@spt/helpers/HttpServerHelper"; import { inject, injectable } from "tsyringe"; +import { pipeline } from 'stream/promises'; @injectable() export class HttpFileUtil { constructor(@inject("HttpServerHelper") protected httpServerHelper: HttpServerHelper) {} - public sendFile(resp: ServerResponse, filePath: string): void { - const pathSlic = filePath.split("/"); + public async sendFileAsync(resp: ServerResponse, filePath: string): Promise { + const pathSlice = filePath.split("/"); const type = - this.httpServerHelper.getMimeText(pathSlic[pathSlic.length - 1].split(".").at(-1) ?? "") || + this.httpServerHelper.getMimeText(pathSlice[pathSlice.length - 1].split(".").at(-1) ?? "") || this.httpServerHelper.getMimeText("txt"); - const fileStream = fs.createReadStream(filePath); - fileStream.on("open", () => { - resp.setHeader("Content-Type", type); - fileStream.pipe(resp); - }); + resp.setHeader("Content-Type", type); + + await pipeline(fs.createReadStream(filePath), resp); } }