diff --git a/http-server/errors.js b/http-server/errors.js index b88e4bb..0627431 100644 --- a/http-server/errors.js +++ b/http-server/errors.js @@ -36,6 +36,19 @@ export class NotFoundError extends HttpError { } } +export class MethodNotAllowedError extends HttpError { + /** + * @param {string} [message] + */ + constructor(message) { + super({ + name: "ERR_METHOD_NOT_ALLOWED", + message: message || "Method not allowed", + statusCode: 405 + }); + } +} + export class ServiceUnavailableError extends HttpError { /** * @param {string} [message] diff --git a/http-server/request.js b/http-server/request.js index 7c6f3ab..d9c3f65 100644 --- a/http-server/request.js +++ b/http-server/request.js @@ -13,10 +13,14 @@ export function createRequest(req) { /** @type {Buffer[]} */ const body = []; - this.req.on("data", (chunk) => body.push(chunk)); + this.req.on("data", (chunk) => { + // TODO: make body size limit + body.push(chunk); + }); this.req.on("end", () => { try { - const parsedJson = JSON.parse(Buffer.concat(body).toString()); + const buffer = Buffer.concat(body); + const parsedJson = JSON.parse(buffer.toString()); resolve(parsedJson); } catch (error) { reject(error); diff --git a/http-server/route.js b/http-server/route.js index 1682829..e9fb372 100644 --- a/http-server/route.js +++ b/http-server/route.js @@ -1,6 +1,6 @@ import { serializeError } from "serialize-error"; import formidable from "formidable"; -import { BadRequestError, HttpError, NotFoundError } from "./errors.js"; +import { BadRequestError, HttpError, MethodNotAllowedError, NotFoundError } from "./errors.js"; /** * @param {URL} url @@ -15,10 +15,13 @@ export async function routeHandler(url, ctxStorage, routeMap) { const { req, res } = ctx; try { + // TODO: create router based on URLPattern if (url.pathname in routeMap) { const route = routeMap[url.pathname]; - if (req.req.headers["content-type"] === "application/json") { + if (route.method !== req.req.method) throw new MethodNotAllowedError(); + + if (req.req.headers["content-type"]?.includes("application/json")) { ctx.data = await ctx.req.parseJson(); } @@ -30,10 +33,9 @@ export async function routeHandler(url, ctxStorage, routeMap) { ctx.data = await formidable(route.incomingForm).parse(req.req); } - if (route.method === req.req.method) { - await route.handle(ctx); - return; - } + await route.handle(ctx); + + return; } throw new NotFoundError("Route not found"); diff --git a/index.js b/index.js index 705d0be..cc75720 100644 --- a/index.js +++ b/index.js @@ -39,7 +39,7 @@ export const routeMap = { } }; -createServer({ routeMap }).listen(SERVER_PORT, async () => { +createServer({ routeMap, enableCors: true }).listen(SERVER_PORT, async () => { console.log(`Service ${packageJson.name} is running at port ${SERVER_PORT}.`); await db.connect().then(() => console.log("Database connected!")); });