perf: 支持同时监听https端口,7002

pull/229/head
xiaojunnuo 2024-10-26 16:36:57 +08:00
parent 4b09a0a27f
commit d5a17f9e6a
7 changed files with 132 additions and 3 deletions

View File

@ -16,6 +16,7 @@ process.env.VITE_APP_VERSION = require("./package.json").version;
process.env.VITE_APP_BUILD_TIME = require("dayjs")().format("YYYY-M-D HH:mm:ss");
import { theme } from "ant-design-vue";
import * as https from "node:https";
const { defaultAlgorithm, defaultSeed } = theme;
@ -103,7 +104,9 @@ export default ({ command, mode }) => {
// with options
"/api": {
//配套后端 https://github.com/fast-crud/fs-server-js
target: "http://127.0.0.1:7001"
target: "https://127.0.0.1:7002",
//忽略证书
agent: new https.Agent({ rejectUnauthorized: false })
}
}
}

View File

@ -74,6 +74,7 @@
"md5": "^2.3.0",
"mwtsc": "^1.4.0",
"nanoid": "^5.0.7",
"node-forge": "^1.3.1",
"nodemailer": "^6.9.3",
"pg": "^8.12.0",
"psl": "^1.9.0",

View File

@ -24,6 +24,12 @@ const development = {
koa: {
port: 7001,
},
https: {
enabled: true,
port: 7002,
key: './data/ssl/cert.key',
cert: './data/ssl/cert.crt',
},
staticFile: {
usePrecompiledGzip: true,
buffer: true,

View File

@ -1,5 +1,6 @@
import { App, Configuration } from '@midwayjs/core';
import * as koa from '@midwayjs/koa';
import { IMidwayKoaContext, NextFunction } from '@midwayjs/koa';
import * as orm from '@midwayjs/typeorm';
import * as cache from '@midwayjs/cache';
import * as validate from '@midwayjs/validate';
@ -18,7 +19,7 @@ import * as libServer from '@certd/lib-server';
import * as commercial from '@certd/commercial-core';
import * as upload from '@midwayjs/upload';
import { setLogger } from '@certd/acme-client';
import { IMidwayKoaContext, NextFunction } from '@midwayjs/koa';
process.on('uncaughtException', error => {
console.error('未捕获的异常:', error);
// 在这里可以添加日志记录、发送错误通知等操作

View File

@ -1,8 +1,10 @@
import { Autoload, Init, Inject, Scope, ScopeEnum } from '@midwayjs/core';
import { App, Autoload, Config, Init, Inject, Scope, ScopeEnum } from '@midwayjs/core';
import { getPlusInfo, isPlus, logger } from '@certd/pipeline';
import { SysInstallInfo, SysSettingsService } from '@certd/lib-server';
import { getVersion } from '../../utils/version.js';
import dayjs from 'dayjs';
import { Application } from '@midwayjs/koa';
import { HttpsServerOptions, startHttpsServer } from './https/server.js';
@Autoload()
@Scope(ScopeEnum.Singleton)
@ -10,8 +12,17 @@ export class AutoZPrint {
@Inject()
sysSettingsService: SysSettingsService;
@App()
app: Application;
@Config('https')
httpsConfig: HttpsServerOptions;
@Init()
async init() {
//监听https
this.startHttpsServer();
const installInfo: SysInstallInfo = await this.sysSettingsService.getSetting(SysInstallInfo);
logger.info('=========================================');
logger.info('当前站点ID:', installInfo.siteId);
@ -24,4 +35,15 @@ export class AutoZPrint {
logger.info('Certd已启动');
logger.info('=========================================');
}
async startHttpsServer() {
if (!this.httpsConfig.enabled) {
logger.info('Https server is not enabled');
return;
}
await startHttpsServer({
...this.httpsConfig,
app: this.app,
});
}
}

View File

@ -0,0 +1,44 @@
import { logger } from '@certd/pipeline';
import fs from 'fs';
// @ts-ignore
import forge from 'node-forge';
export function createSelfCertificate(opts: { crtPath: string; keyPath: string }) {
// 生成密钥对
const keypair = forge.pki.rsa.generateKeyPair(2048);
// 创建自签名证书
const cert = forge.pki.createCertificate();
cert.publicKey = keypair.publicKey;
cert.serialNumber = '01';
cert.validFrom = new Date(Date.now() - 1000 * 60 * 60 * 24).toISOString(); // 1天前
cert.validTo = new Date(Date.now() + 1000 * 60 * 60 * 24 * 365 * 10).toISOString(); // 10年后
// 创建主题
const attrs = [
{
name: 'commonName',
value: 'self-certificate.certd', // 或者你的域名
},
];
cert.setSubject(attrs);
cert.setIssuer(attrs);
cert.sign(keypair.privateKey, forge.md.sha256.create());
// 导出证书和私钥
const pemCert = forge.pki.certificateToPem(cert);
const pemKey = forge.pki.privateKeyToPem(keypair.privateKey);
// 写入文件
logger.info('生成自签名证书成功');
logger.info(`自签证书保存路径: ${opts.crtPath}`);
logger.info(`自签私钥保存路径: ${opts.keyPath}`);
fs.writeFileSync(opts.crtPath, pemCert);
fs.writeFileSync(opts.keyPath, pemKey);
return {
crtPath: opts.crtPath,
keyPath: opts.keyPath,
crt: pemCert,
key: pemKey,
};
}

View File

@ -0,0 +1,52 @@
import https from 'node:https';
import fs from 'fs';
import { Application } from '@midwayjs/koa';
import { createSelfCertificate } from './self-certificate.js';
import { logger } from '@certd/pipeline';
export type HttpsServerOptions = {
enabled: boolean;
app?: Application;
port: number;
key: string;
cert: string;
};
export async function startHttpsServer(opts: HttpsServerOptions) {
// const httpsServer = https.createServer({
// key: fs.readFileSync(path.join(__dirname, '../ssl/2_certd.cn.key')),
// cert
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()
);
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);
} catch (e) {
logger.error('启动https服务失败', e);
}
}