azurite
Version:
An open source Azure Storage API compatible server
170 lines • 5.3 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.ServerStatus = void 0;
const tslib_1 = require("tslib");
const stoppable_1 = tslib_1.__importDefault(require("stoppable"));
var ServerStatus;
(function (ServerStatus) {
ServerStatus["Closed"] = "Closed";
ServerStatus["Starting"] = "Starting";
ServerStatus["Running"] = "Running";
ServerStatus["Closing"] = "Closing";
})(ServerStatus || (exports.ServerStatus = ServerStatus = {}));
/**
* Abstract Server class for Azurite HTTP or HTTPS Servers.
*
* @export
* @abstract
* @class Server
*/
class ServerBase {
/**
* Creates an instance of HTTP or HTTPS server.
*
* @param {string} host Server host,for example, "127.0.0.1"
* @param {number} port Server port, for example, 10000
* @param {http.Server | https.Server} httpServer A HTTP or HTTPS server instance without request listener bound
* @param {IRequestListenerFactory} requestListenerFactory A request listener factory
* @param config ConfigurationBase configuration
* @memberof ServerBase
*/
constructor(host, port, httpServer, requestListenerFactory, config) {
this.host = host;
this.port = port;
this.config = config;
this.status = ServerStatus.Closed;
if (this.config.keepAliveTimeout > 0) {
httpServer.keepAliveTimeout = this.config.keepAliveTimeout * 1000;
}
// Remove predefined request listeners to avoid double request handling
this.httpServer = (0, stoppable_1.default)(httpServer);
this.httpServer.removeAllListeners("request");
this.httpServer.on("request", requestListenerFactory.createRequestListener());
}
/**
* Get HTTP server listening address and port string.
* Note this may be different from host and port parameters values, because
* when port is 0, system will select a rand port number for listening.
* This method will return the port and address being used.
*
* @returns {string}
* @memberof ServerBase
*/
getHttpServerAddress() {
const address = this.httpServer.address();
const protocol = `http${this.config.hasCert() ? "s" : ""}://`;
if (typeof address === "string") {
return protocol + address;
}
else if (address === null) {
return "";
}
else {
return `${protocol}${address.address}:${address.port}`;
}
}
getStatus() {
return this.status;
}
/**
* Initialize and start the server to server incoming HTTP requests.
* beforeStart() and afterStart() will be executed before and after start().
*
* @abstract
* @returns {Promise<void>}
* @memberof Server
*/
async start() {
if (this.status !== ServerStatus.Closed) {
throw Error(`Cannot start server in status ${ServerStatus[this.status]}`);
}
this.status = ServerStatus.Starting;
try {
await this.beforeStart();
await new Promise((resolve, reject) => {
this.httpServer
.listen(this.port, this.host, resolve)
.on("error", reject);
});
this.status = ServerStatus.Running;
}
catch (err) {
this.status = ServerStatus.Closed;
throw err;
}
await this.afterStart();
}
/**
* Dispose HTTP server and clean up other resources.
*
* beforeClose() and afterClose() will be executed before and after close().
*
* We name this method as close instead of dispose, because in practices, usually we cannot re-open the resources
* disposed, but can re-open the resources closed.
*
* @abstract
* @returns {Promise<void>}
* @memberof Server
*/
async close() {
if (this.status !== ServerStatus.Running) {
throw Error(`Cannot close server in status ${ServerStatus[this.status]}`);
}
this.status = ServerStatus.Closing;
await this.beforeClose();
// Remove request listener to reject incoming requests
this.httpServer.removeAllListeners("request");
this.httpServer.stop();
await this.afterClose();
this.status = ServerStatus.Closed;
}
async clean() {
/** NOOP */
}
/**
* Async task before server starts.
*
* @protected
* @abstract
* @returns {Promise<void>}
* @memberof Server
*/
async beforeStart() {
/** NOOP */
}
/**
* Async task after server starts.
*
* @protected
* @abstract
* @returns {Promise<void>}
* @memberof Server
*/
async afterStart() {
/** NOOP */
}
/**
* Async task before server closes.
*
* @protected
* @abstract
* @returns {Promise<void>}
* @memberof Server
*/
async beforeClose() {
/** NOOP */
}
/**
* Async task after server closes.
*
* @protected
* @abstract
* @returns {Promise<void>}
* @memberof Server
*/
async afterClose() {
/** NOOP */
}
}
exports.default = ServerBase;
//# sourceMappingURL=ServerBase.js.map
;