feat: Support creation of HTTPS server

This commit is contained in:
Joachim Van Herwegen
2021-05-27 13:00:52 +02:00
parent afc662ca9a
commit 7faad0aef0
9 changed files with 246 additions and 55 deletions

View File

@@ -1,11 +1,33 @@
import { readFileSync } from 'fs';
import type { Server, IncomingMessage, ServerResponse } from 'http';
import { createServer } from 'http';
import { createServer as createHttpServer } from 'http';
import { createServer as createHttpsServer } from 'https';
import { URL } from 'url';
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';
/**
* Options to be used when creating the server.
* Due to Components.js not supporting external types, this has been simplified (for now?).
* The common https keys here (key/cert/pfx) will be interpreted as file paths that need to be read
* before passing the options to the `createServer` function.
*/
export interface BaseHttpServerOptions {
/**
* If the server should start as an http or https server.
*/
https?: boolean;
key?: string;
cert?: string;
pfx?: string;
passphrase?: string;
}
/**
* HttpServerFactory based on the native Node.js http module
*/
@@ -14,19 +36,26 @@ export class BaseHttpServerFactory implements HttpServerFactory {
/** The main HttpHandler */
private readonly handler: HttpHandler;
private readonly options: BaseHttpServerOptions;
public constructor(handler: HttpHandler) {
public constructor(handler: HttpHandler, options: BaseHttpServerOptions = { https: false }) {
this.handler = handler;
this.options = { ...options };
}
/**
* Creates and starts an HTTP server
* Creates and starts an HTTP(S) server
* @param port - Port on which the server listens
*/
public startServer(port: number): Server {
this.logger.info(`Starting server at http://localhost:${port}/`);
const protocol = this.options.https ? 'https' : 'http';
const url = new URL(`${protocol}://localhost:${port}/`).href;
this.logger.info(`Starting server at ${url}`);
const server = createServer(
const createServer = this.options.https ? createHttpsServer : createHttpServer;
const options = this.createServerOptions();
const server = createServer(options,
async(request: IncomingMessage, response: ServerResponse): Promise<void> => {
try {
this.logger.info(`Received ${request.method} request for ${request.url}`);
@@ -45,9 +74,19 @@ export class BaseHttpServerFactory implements HttpServerFactory {
response.writeHead(404).end();
}
}
},
);
});
return server.listen(port);
}
private createServerOptions(): BaseHttpServerOptions {
const options = { ...this.options };
for (const id of [ 'key', 'cert', 'pfx' ] as const) {
const val = options[id];
if (val) {
options[id] = readFileSync(val, 'utf8');
}
}
return options;
}
}