feat: Replace express with native http module

* refactor: replace express with native http module

* fix: 404 when unhandled

* chore: removed express dependency

* chore: updated package-lock.json

* docs: added documentation for BaseHttpServerFactory

* chore: updated package-lock.json

Co-authored-by: Arthur Joppart <arthur@digita.ai>
This commit is contained in:
Stijn Taelemans
2021-02-11 10:15:40 +01:00
committed by GitHub
parent 0ffd332828
commit ce1f4300ff
9 changed files with 90 additions and 400 deletions

View File

@@ -113,7 +113,7 @@ export * from './pods/PodManager';
export * from './pods/PodManagerHttpHandler';
// Server
export * from './server/ExpressHttpServerFactory';
export * from './server/BaseHttpServerFactory';
export * from './server/HttpHandler';
export * from './server/HttpRequest';
export * from './server/HttpResponse';

View File

@@ -0,0 +1,53 @@
import type { Server, IncomingMessage, ServerResponse } from 'http';
import { createServer } from 'http';
import { getLoggerFor } from '../logging/LogUtil';
import { isNativeError } from '../util/errors/ErrorUtil';
import { guardStream } from '../util/GuardedStream';
import type { HttpHandler } from './HttpHandler';
import type { HttpServerFactory } from './HttpServerFactory';
/**
* HttpServerFactory based on the native Node.js http module
*/
export class BaseHttpServerFactory implements HttpServerFactory {
protected readonly logger = getLoggerFor(this);
/** The main HttpHandler */
private readonly handler: HttpHandler;
public constructor(handler: HttpHandler) {
this.handler = handler;
}
/**
* Creates and starts an HTTP server
* @param port - Port on which the server listens
*/
public startServer(port: number): Server {
this.logger.info(`Starting server at http://localhost:${port}/`);
const server = createServer(
async(request: IncomingMessage, response: ServerResponse): Promise<void> => {
try {
this.logger.info(`Received request for ${request.url}`);
await this.handler.handleSafe({ request: guardStream(request), response });
} catch (error: unknown) {
const errMsg = isNativeError(error) ? `${error.name}: ${error.message}\n${error.stack}` : 'Unknown error.';
this.logger.error(errMsg);
if (response.headersSent) {
response.end();
} else {
response.setHeader('Content-Type', 'text/plain; charset=utf-8');
response.writeHead(500).end(errMsg);
}
} finally {
if (!response.headersSent) {
response.writeHead(404).end();
}
}
},
);
return server.listen(port);
}
}

View File

@@ -1,42 +0,0 @@
import type { Server } from 'http';
import type { Express } from 'express';
import express from 'express';
import { getLoggerFor } from '../logging/LogUtil';
import { isNativeError } from '../util/errors/ErrorUtil';
import { guardStream } from '../util/GuardedStream';
import type { HttpHandler } from './HttpHandler';
import type { HttpServerFactory } from './HttpServerFactory';
export class ExpressHttpServerFactory implements HttpServerFactory {
protected readonly logger = getLoggerFor(this);
private readonly handler: HttpHandler;
public constructor(handler: HttpHandler) {
this.handler = handler;
}
public startServer(port: number): Server {
this.logger.info(`Starting server at http://localhost:${port}/`);
return this.createApp().listen(port);
}
protected createApp(): Express {
return express().use(async(request, response, done): Promise<void> => {
try {
this.logger.info(`Received request for ${request.url}`);
await this.handler.handleSafe({ request: guardStream(request), response });
} catch (error: unknown) {
const errMsg = isNativeError(error) ? `${error.name}: ${error.message}\n${error.stack}` : 'Unknown error.';
this.logger.error(errMsg);
if (response.headersSent) {
response.end();
} else {
response.status(500).contentType('text/plain').send(errMsg);
}
} finally {
done();
}
});
}
}