feat: 更新sign的模块
This commit is contained in:
parent
780d744a16
commit
926c0a09cd
5
.gitignore
vendored
5
.gitignore
vendored
@ -3,4 +3,7 @@ src/app.config.json5
|
||||
dist
|
||||
.npmrc
|
||||
|
||||
.turbo
|
||||
.turbo
|
||||
|
||||
https-cert.pem
|
||||
https-key.pem
|
35
demo/simple/src/apps-https/app.ts
Normal file
35
demo/simple/src/apps-https/app.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import { Route, App } from '@kevisual/router';
|
||||
import { readFileSync } from 'fs';
|
||||
const app = new App({
|
||||
serverOptions: {
|
||||
cors: {},
|
||||
isHTTPS: true,
|
||||
httpsKey: readFileSync('https-key.pem', 'utf8'),
|
||||
httpsCert: readFileSync('https-cert.pem', 'utf-8'),
|
||||
},
|
||||
});
|
||||
app.listen(4003, '0.0.0.0', () => {
|
||||
console.log(`http://localhost:4003/api/router?path=demo&key=02`);
|
||||
console.log(`http://localhost:4003/api/router?path=demo&key=01`);
|
||||
console.log(`https://192.168.31.220:4003/api/router?path=demo&key=01`);
|
||||
});
|
||||
const route01 = new Route('demo', '01');
|
||||
route01.run = async (ctx) => {
|
||||
ctx.body = '01';
|
||||
return ctx;
|
||||
};
|
||||
app.use(
|
||||
'demo',
|
||||
async (ctx) => {
|
||||
ctx.body = '01';
|
||||
return ctx;
|
||||
},
|
||||
{ key: '01' },
|
||||
);
|
||||
|
||||
const route02 = new Route('demo', '02');
|
||||
route02.run = async (ctx) => {
|
||||
ctx.body = '02';
|
||||
return ctx;
|
||||
};
|
||||
app.addRoute(route02);
|
6
demo/simple/src/apps-https/create-sign.ts
Normal file
6
demo/simple/src/apps-https/create-sign.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import { createCert } from '@kevisual/router/sign';
|
||||
import { writeFileSync } from 'fs';
|
||||
const { key, cert } = createCert();
|
||||
|
||||
writeFileSync('https-key.pem', key);
|
||||
writeFileSync('https-cert.pem', cert);
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package",
|
||||
"name": "@kevisual/router",
|
||||
"version": "0.0.4-alpha-8",
|
||||
"version": "0.0.4",
|
||||
"description": "",
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/index.js",
|
||||
@ -41,6 +41,7 @@
|
||||
"url": "git+https://github.com/abearxiong/kevisual-router.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"selfsigned": "^2.4.1",
|
||||
"ws": "^8.18.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
@ -54,6 +55,10 @@
|
||||
"./browser": {
|
||||
"import": "./dist/router-browser.js",
|
||||
"require": "./dist/router-browser.js"
|
||||
},
|
||||
"./sign": {
|
||||
"import": "./dist/router-sign.js",
|
||||
"require": "./dist/router-sign.js"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -51,4 +51,26 @@ export default [
|
||||
},
|
||||
plugins: [dts()],
|
||||
},
|
||||
{
|
||||
input: 'src/sign.ts',
|
||||
output: {
|
||||
file: 'dist/router-sign.js',
|
||||
format: 'es',
|
||||
},
|
||||
plugins: [
|
||||
resolve({
|
||||
browser: false,
|
||||
}),
|
||||
commonjs(),
|
||||
typescript(),
|
||||
],
|
||||
},
|
||||
{
|
||||
input: 'src/sign.ts',
|
||||
output: {
|
||||
file: 'dist/router-sign.d.ts',
|
||||
format: 'es',
|
||||
},
|
||||
plugins: [dts()],
|
||||
},
|
||||
];
|
||||
|
@ -14,6 +14,9 @@ type AppOptions<T = {}> = {
|
||||
path?: string;
|
||||
cors?: Cors;
|
||||
handle?: any;
|
||||
isHTTPS?: boolean;
|
||||
httpsKey?: string;
|
||||
httpsCert?: string;
|
||||
};
|
||||
io?: boolean;
|
||||
ioOpts?: { routerHandle?: RouterHandle; routerContext?: RouteContext<T>; path?: string };
|
||||
|
@ -1,6 +1,6 @@
|
||||
import http, { IncomingMessage, ServerResponse } from 'http';
|
||||
import https from 'https';
|
||||
import { handleServer } from './handle-server.ts';
|
||||
|
||||
export type Listener = (...args: any[]) => void;
|
||||
|
||||
export type Cors = {
|
||||
@ -9,12 +9,15 @@ export type Cors = {
|
||||
*/
|
||||
origin?: string | undefined;
|
||||
};
|
||||
type ServerOpts = {
|
||||
export type ServerOpts = {
|
||||
/**path default `/api/router` */
|
||||
path?: string;
|
||||
/**handle Fn */
|
||||
handle?: (msg?: { path: string; key?: string; [key: string]: any }) => any;
|
||||
cors?: Cors;
|
||||
isHTTPS?: boolean;
|
||||
httpsKey?: string;
|
||||
httpsCert?: string;
|
||||
};
|
||||
export const resultError = (error: string, code = 500) => {
|
||||
const r = {
|
||||
@ -31,10 +34,20 @@ export class Server {
|
||||
private _callback: any;
|
||||
private cors: Cors;
|
||||
private hasOn = false;
|
||||
private isHTTPS = false;
|
||||
private options = {
|
||||
key: '',
|
||||
cert: '',
|
||||
};
|
||||
constructor(opts?: ServerOpts) {
|
||||
this.path = opts?.path || '/api/router';
|
||||
this.handle = opts?.handle;
|
||||
this.cors = opts?.cors;
|
||||
this.isHTTPS = opts?.isHTTPS || false;
|
||||
this.options = {
|
||||
key: opts?.httpsKey || '',
|
||||
cert: opts?.httpsCert || '',
|
||||
};
|
||||
}
|
||||
listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void): void;
|
||||
listen(port: number, hostname?: string, listeningListener?: () => void): void;
|
||||
@ -45,11 +58,29 @@ export class Server {
|
||||
listen(handle: any, backlog?: number, listeningListener?: () => void): void;
|
||||
listen(handle: any, listeningListener?: () => void): void;
|
||||
listen(...args: any[]) {
|
||||
this._server = http.createServer();
|
||||
this._server = this.createServer();
|
||||
const callback = this.createCallback();
|
||||
this._server.on('request', callback);
|
||||
this._server.listen(...args);
|
||||
}
|
||||
createServer() {
|
||||
let server: http.Server | https.Server;
|
||||
if (this.isHTTPS) {
|
||||
if (this.options.key && this.options.cert) {
|
||||
server = https.createServer({
|
||||
key: this.options.key,
|
||||
cert: this.options.cert,
|
||||
});
|
||||
console.log('https server');
|
||||
return server;
|
||||
} else {
|
||||
console.error('https key and cert is required');
|
||||
console.log('downgrade to http');
|
||||
}
|
||||
}
|
||||
server = http.createServer();
|
||||
return server;
|
||||
}
|
||||
setHandle(handle?: any) {
|
||||
this.handle = handle;
|
||||
}
|
||||
@ -65,7 +96,7 @@ export class Server {
|
||||
if (req.url === '/favicon.ico') {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (res.headersSent) {
|
||||
// 程序已经在其他地方响应了
|
||||
return;
|
||||
@ -130,7 +161,7 @@ export class Server {
|
||||
* @param listener
|
||||
*/
|
||||
on(listener: Listener | Listener[]) {
|
||||
this._server = this._server || http.createServer();
|
||||
this._server = this._server || this.createServer();
|
||||
this._server.removeAllListeners('request');
|
||||
this.hasOn = true;
|
||||
if (Array.isArray(listener)) {
|
||||
|
46
src/sign.ts
Normal file
46
src/sign.ts
Normal file
@ -0,0 +1,46 @@
|
||||
import { generate } from 'selfsigned';
|
||||
|
||||
type Attributes = {
|
||||
name: string;
|
||||
value: string;
|
||||
};
|
||||
type AltNames = {
|
||||
type: number;
|
||||
value?: string;
|
||||
ip?: string;
|
||||
};
|
||||
export const createCert = (attrs: Attributes[] = [], altNames: AltNames[] = []) => {
|
||||
let attributes = [
|
||||
{ name: 'commonName', value: '*' }, // 通配符域名
|
||||
{ name: 'countryName', value: 'CN' }, // 国家代码
|
||||
{ name: 'stateOrProvinceName', value: 'ZheJiang' }, // 州名
|
||||
{ name: 'localityName', value: 'Hangzhou' }, // 城市名
|
||||
{ name: 'organizationName', value: 'Envision' }, // 组织名
|
||||
{ name: 'organizationalUnitName', value: 'IT' }, // 组织单位
|
||||
...attrs,
|
||||
];
|
||||
// attribute 根据name去重复, 后面的覆盖前面的
|
||||
attributes = attributes.filter((item, index, self) => {
|
||||
return self.findIndex((t) => t.name === item.name) === index;
|
||||
});
|
||||
|
||||
const options = {
|
||||
days: 365, // 证书有效期(天)
|
||||
extensions: [
|
||||
{
|
||||
name: 'subjectAltName',
|
||||
altNames: [
|
||||
{ type: 2, value: '*' }, // DNS 名称
|
||||
{ type: 2, value: 'localhost' }, // DNS
|
||||
{ type: 7, ip: '127.0.0.1' }, // IP 地址
|
||||
...altNames,
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
const pems = generate(attributes, options);
|
||||
return {
|
||||
key: pems.private,
|
||||
cert: pems.cert,
|
||||
};
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user