UNPKG

@nodefony/http-bundle

Version:

Nodefony Framework Bundle HTTP

217 lines (202 loc) 6.67 kB
let http2 = null; const https = require('https'); try { http2 = require('http2'); } catch (e) { http2 = null; } let quic = null; try { quic = require('net').createQuicSocket; } catch (e) { quic = null; } const protocol = { "1.1": https, "2.0": http2, "3.0": quic }; module.exports = class httpsServer extends nodefony.Service { constructor(httpKernel) { super("HTTPS", httpKernel.container, httpKernel.notificationsCenter); this.httpKernel = httpKernel; this.port = this.httpKernel.kernel.httpsPort; this.domain = this.httpKernel.kernel.settings.system.domain; this.ready = false; this.protocol = "2.0"; this.key = null; this.cert = null; this.ca = null; this.address = null; this.family = null; this.type = "HTTPS"; this.server = null; this.once("onBoot", async () => { this.bundle.on("onServersReady", (type) => { if (type === this.type) { let addr = this.server.address(); this.domain = addr.address; this.kernel.hostname = addr.address; this.port = addr.port; this.kernel.httpsPort = addr.port; this.kernel.hostHttps = this.kernel.hostname + ":" + addr.port; this.family = addr.family; this.log("Listening on DOMAIN : https://" + this.domain + ":" + this.port, "INFO"); /*dns.lookup(this.domain, (err, addresses, family) => { if (err) { throw err; } this.address = addresses; this.family = family; });*/ } }); }); } getCertificats() { this.settings = this.getParameters("bundles.http").https || null; this.settings.certificats = nodefony.extend(true, {}, this.settings.certificats, this.kernel.settings.system.servers.certificats); let bundleOptions = this.getParameters("bundles.http").https.certificats || null; let opt = nodefony.extend(true, { keyPath: this.kernel.checkPath(this.settings.certificats.key), certPath: this.kernel.checkPath(this.settings.certificats.cert), caPath: this.kernel.checkPath(this.settings.certificats.ca), key: null, cert: null, ca: null }, bundleOptions); try { this.key = fs.readFileSync(opt.keyPath); opt.key = this.key; this.cert = fs.readFileSync(opt.certPath); opt.cert = this.cert; if (opt.caPath) { this.ca = fs.readFileSync(opt.caPath); opt.ca = this.ca; } } catch (e) { throw e; } return opt; } createServer() { if (this.kernel.settings.system.servers.protocol in protocol) { this.protocol = this.kernel.settings.system.servers.protocol; } else { if (this.kernel.settings.system.servers.protocol) { this.log(this.kernel.settings.system.servers.protocol + " not implemented ", 'WARNING'); } else { this.log("BAD config servers https protocol not defined !! check framework config", 'WARNING'); } this.protocol = "1.1"; } if (!http2) { this.protocol = "1.1"; } try { this.options = this.getCertificats(); for (let ele in this.options) { switch (ele) { case "keyPath": this.log(" READ CERTIFICATE KEY : " + this.options[ele], "DEBUG"); break; case "certPath": this.log(" READ CERTIFICATE CERT : " + this.options[ele], "DEBUG"); break; case "caPath": if (this.options[ele]) { this.log(" READ CERTIFICATE CA : " + this.options[ele], "DEBUG"); } else { this.log(" NO CERTIFICATE CA : " + this.options[ele], "WARNING"); } break; } } } catch (e) { this.log(e); throw e; } try { switch (this.protocol) { case "1.1": this.server = https.createServer(this.options); this.bundle.fire("onCreateServer", this.type, this); break; case "2.0": this.options.allowHTTP1 = true; this.settings2 = this.getParameters("bundles.http").http2 || {}; let buf = http2.getPackedSettings(this.settings2); this.defaultSetting2 = nodefony.extend({}, http2.getDefaultSettings(), http2.getUnpackedSettings(buf) || {}); this.server = http2.createSecureServer(this.options); this.bundle.fire("onCreateServer", this.type, this); this.server.on("sessionError", (error) => { this.log(error, "ERROR", "HTTP2 Server sessionError"); }); this.server.on("streamError", (error) => { this.log(error, "ERROR", "HTTP2 Server streamError"); }); break; default: } } catch (e) { this.log(e, "CRITIC"); throw e; } this.server.on('request', (request, response) => { const { socket: { alpnProtocol } } = request.httpVersion === '2.0' ? request.stream.session : request; if (alpnProtocol === "h2") { return this.httpKernel.onHttpRequest(request, response, "HTTP2"); } else { return this.httpKernel.onHttpRequest(request, response, this.type); } }); if (this.settings.timeout) { this.server.timeout = this.settings.timeout; } if (this.settings.maxHeadersCount) { this.server.maxHeadersCount = this.settings.maxHeadersCount; } /*this.server.on('stream', (stream, hearder) => { //console.log("pass stream ") });*/ // LISTEN ON PORT this.server.listen(this.port, this.domain, () => { this.ready = true; this.bundle.fire("onServersReady", this.type, this); }); this.server.on("error", (error) => { let myError = new nodefony.Error(error); switch (error.errno) { case "ENOTFOUND": this.log("CHECK DOMAIN IN /etc/hosts or config unable to connect to : " + this.domain, "ERROR"); this.log(myError, "CRITIC"); break; case "EADDRINUSE": this.log("Domain : " + this.domain + " Port : " + this.port + " ==> ALREADY USE ", "ERROR"); this.log(myError, "CRITIC"); setTimeout(() => { this.server.close(); }, 1000); break; default: this.log(myError, "CRITIC"); } }); this.server.on("clientError", (e, socket) => { this.fire("onClientError", e, socket); }); this.on("onTerminate", () => { if (this.server) { this.server.close(() => { this.log(this.type + " SHUTDOWN Server is listening on DOMAIN : " + this.domain + " PORT : " + this.port, "INFO"); }); } }); return this.server; } };