import https from 'node:https'; import fs from 'fs'; import { Application } from '@midwayjs/koa'; import { createSelfCertificate } from './self-certificate.js'; import { logger } from '@certd/basic'; export type HttpsServerOptions = { enabled: boolean; app?: Application; port: number; key: string; cert: string; }; export class HttpsServer { server: https.Server; opts: HttpsServerOptions; constructor() {} async restart() { await this.close(); return this.start(this.opts); } async close() { return new Promise((resolve, reject) => { this.server.close(() => { resolve(true); }); }); } start(opts: HttpsServerOptions) { if (!opts) { logger.error('https配置不能为空'); return; } this.opts = opts; logger.info('========================================='); if (!opts.key || !opts.cert) { logger.error('证书路径未配置,无法启动https服务,请先配置:koa.https.key和koa.https.cert'); return; } if (!fs.existsSync(opts.key) || !fs.existsSync(opts.cert)) { logger.info('证书文件不存在,将生成自签名证书'); createSelfCertificate({ crtPath: opts.cert, keyPath: opts.key, }); } logger.info('准备启动https服务'); const httpServer = https.createServer( { cert: fs.readFileSync(opts.cert), key: fs.readFileSync(opts.key), }, opts.app.callback() ); this.server = httpServer; const hostname = '0.0.0.0'; // A function that runs in the context of the http server // and reports what type of server listens on which port function listeningReporter() { // `this` refers to the http server here logger.info(`Https server is listening on https://${hostname}:${opts.port}`); } try { httpServer.listen(opts.port, hostname, listeningReporter); return httpServer; } catch (e) { logger.error('启动https服务失败', e); } } } export const httpsServer = new HttpsServer();