xshell 1.1.3 → 1.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/server.d.ts +11 -1
- package/server.js +62 -42
package/package.json
CHANGED
package/server.d.ts
CHANGED
|
@@ -27,6 +27,11 @@ export declare class Server {
|
|
|
27
27
|
/** proxy 时需要丢弃的 resposne headers */
|
|
28
28
|
static drop_response_headers: Set<string>;
|
|
29
29
|
name: string;
|
|
30
|
+
print: {
|
|
31
|
+
info: boolean;
|
|
32
|
+
logs: boolean;
|
|
33
|
+
errors: boolean;
|
|
34
|
+
};
|
|
30
35
|
/** sea 下最后修改时间,用于 http 资源缓存 */
|
|
31
36
|
last_modified_str?: string;
|
|
32
37
|
UAParser: typeof UAParser;
|
|
@@ -61,8 +66,13 @@ export declare class Server {
|
|
|
61
66
|
/** 原始 process.stdout.write 函数 bind 后的备份 */
|
|
62
67
|
stdout_write: Function;
|
|
63
68
|
stderr_write: Function;
|
|
64
|
-
constructor({ name, http, http2, http_port, http2_port, fpd_certs, default_hostnames, remote, funcs, stdio_subscribable, log_date }: {
|
|
69
|
+
constructor({ name, print, http, http2, http_port, http2_port, fpd_certs, default_hostnames, remote, funcs, stdio_subscribable, log_date }: {
|
|
65
70
|
name: string;
|
|
71
|
+
print?: boolean | {
|
|
72
|
+
info?: boolean;
|
|
73
|
+
logs?: boolean;
|
|
74
|
+
errors: boolean;
|
|
75
|
+
};
|
|
66
76
|
http?: boolean;
|
|
67
77
|
http2?: boolean;
|
|
68
78
|
http_port?: number;
|
package/server.js
CHANGED
|
@@ -24,6 +24,11 @@ export class Server {
|
|
|
24
24
|
'x-powered-by'
|
|
25
25
|
]);
|
|
26
26
|
name;
|
|
27
|
+
print = {
|
|
28
|
+
info: true,
|
|
29
|
+
logs: true,
|
|
30
|
+
errors: true
|
|
31
|
+
};
|
|
27
32
|
/** sea 下最后修改时间,用于 http 资源缓存 */
|
|
28
33
|
last_modified_str;
|
|
29
34
|
UAParser;
|
|
@@ -55,8 +60,13 @@ export class Server {
|
|
|
55
60
|
/** 原始 process.stdout.write 函数 bind 后的备份 */
|
|
56
61
|
stdout_write;
|
|
57
62
|
stderr_write;
|
|
58
|
-
constructor({ name, http, http2, http_port, http2_port, fpd_certs, default_hostnames, remote, funcs, stdio_subscribable, log_date }) {
|
|
63
|
+
constructor({ name, print, http, http2, http_port, http2_port, fpd_certs, default_hostnames, remote, funcs, stdio_subscribable, log_date }) {
|
|
59
64
|
this.name = name;
|
|
65
|
+
if (print !== undefined) {
|
|
66
|
+
if (typeof print === 'boolean')
|
|
67
|
+
print = { info: print, logs: print, errors: print };
|
|
68
|
+
this.print = print;
|
|
69
|
+
}
|
|
60
70
|
if (http)
|
|
61
71
|
this.http = http;
|
|
62
72
|
if (http2)
|
|
@@ -75,7 +85,7 @@ export class Server {
|
|
|
75
85
|
if (remote)
|
|
76
86
|
this.remote = remote;
|
|
77
87
|
else if (funcs)
|
|
78
|
-
this.remote = new Remote({ funcs });
|
|
88
|
+
this.remote = new Remote({ funcs, print: this.print.errors });
|
|
79
89
|
if (stdio_subscribable !== undefined) {
|
|
80
90
|
check(remote || funcs);
|
|
81
91
|
this.stdio_subscribable = stdio_subscribable;
|
|
@@ -236,13 +246,14 @@ export class Server {
|
|
|
236
246
|
this.http2_server.listen(this.http2_port, resolve);
|
|
237
247
|
}),
|
|
238
248
|
]);
|
|
239
|
-
|
|
240
|
-
name
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
249
|
+
if (this.print.info)
|
|
250
|
+
console.log(t('{{name}} 启动成功,正在监听 {{ports}} 端口', {
|
|
251
|
+
name: this.name,
|
|
252
|
+
ports: [
|
|
253
|
+
...http ? [this.http_port] : [],
|
|
254
|
+
...http2 ? [this.http2_port] : []
|
|
255
|
+
].join(', ')
|
|
256
|
+
}));
|
|
246
257
|
}
|
|
247
258
|
stop() {
|
|
248
259
|
this.http_server.close();
|
|
@@ -251,34 +262,38 @@ export class Server {
|
|
|
251
262
|
}
|
|
252
263
|
/** 可被子类重写定义错误处理逻辑 */
|
|
253
264
|
on_error(error, ctx) {
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
265
|
+
if (this.print.errors) {
|
|
266
|
+
const code = error?.code;
|
|
267
|
+
if (code === 'EPIPE' || code === 'ECONNRESET')
|
|
268
|
+
console.log(`${error.code}:`, ctx?.request?.url);
|
|
269
|
+
else {
|
|
270
|
+
console.error(error);
|
|
271
|
+
if (ctx)
|
|
272
|
+
console.log('ctx:', ctx);
|
|
273
|
+
}
|
|
261
274
|
}
|
|
262
275
|
}
|
|
263
276
|
on_upgrade(request, socket, head) {
|
|
264
277
|
// url 只有路径部分
|
|
265
278
|
const { url, headers, headers: { host = '' }, } = request;
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
279
|
+
if (this.print.logs) {
|
|
280
|
+
const ip = request.socket.remoteAddress.replace(/^::ffff:/, '');
|
|
281
|
+
console.log(
|
|
282
|
+
// 时间
|
|
283
|
+
`${this.log_date ? new Date().to_str() : new Date().to_time_str()} ` +
|
|
284
|
+
// ip(位置)
|
|
285
|
+
(ip || '').limit(40) + ' ' +
|
|
286
|
+
// ua
|
|
287
|
+
this.format_ua(headers).limit(56) + ' ' +
|
|
288
|
+
// https/2.0
|
|
289
|
+
`${this.colors ? 'websocket'.limit(10).magenta : 'websocket'.limit(10)} ` +
|
|
290
|
+
// method
|
|
291
|
+
''.limit(6) + ' ' +
|
|
292
|
+
// host
|
|
293
|
+
`${host.limit(24)} ` +
|
|
294
|
+
// path
|
|
295
|
+
(this.colors ? url.yellow : url));
|
|
296
|
+
}
|
|
282
297
|
switch (url) {
|
|
283
298
|
case '/':
|
|
284
299
|
this.websocket_server.handleUpgrade(request, socket, head, ws => {
|
|
@@ -287,7 +302,8 @@ export class Server {
|
|
|
287
302
|
});
|
|
288
303
|
return;
|
|
289
304
|
default:
|
|
290
|
-
|
|
305
|
+
if (this.print.logs)
|
|
306
|
+
console.log(`${' '.repeat(13)} connect 404: ${url}`.red);
|
|
291
307
|
socket.destroy();
|
|
292
308
|
}
|
|
293
309
|
}
|
|
@@ -339,7 +355,8 @@ export class Server {
|
|
|
339
355
|
writable: true
|
|
340
356
|
});
|
|
341
357
|
// ------------ log
|
|
342
|
-
this.
|
|
358
|
+
if (this.print.logs)
|
|
359
|
+
this.logger(ctx);
|
|
343
360
|
// ------------ repl_router hook
|
|
344
361
|
if (await globalThis.repl_router?.(ctx))
|
|
345
362
|
return;
|
|
@@ -358,7 +375,8 @@ export class Server {
|
|
|
358
375
|
let { response } = ctx;
|
|
359
376
|
response.redirect(url);
|
|
360
377
|
response.status = code;
|
|
361
|
-
|
|
378
|
+
if (this.print.logs)
|
|
379
|
+
console.log(`${code} 重定向 ${_path} -> ${url}`.yellow);
|
|
362
380
|
return true;
|
|
363
381
|
}
|
|
364
382
|
logger(ctx) {
|
|
@@ -512,20 +530,22 @@ export class Server {
|
|
|
512
530
|
catch (error) {
|
|
513
531
|
if (throw_error)
|
|
514
532
|
throw error;
|
|
515
|
-
if (error.response?.status !== 404)
|
|
533
|
+
if (error.response?.status !== 404 && this.print.errors)
|
|
516
534
|
console.log(error);
|
|
517
535
|
if (error.response) {
|
|
518
536
|
const { status, headers, body } = error.response;
|
|
519
|
-
if (
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
537
|
+
if (this.print.errors)
|
|
538
|
+
if (status === 404)
|
|
539
|
+
console.log(method, '404:', path_url);
|
|
540
|
+
else
|
|
541
|
+
console.log(error);
|
|
523
542
|
response.status = status;
|
|
524
543
|
response.set(Server.filter_response_headers(headers));
|
|
525
544
|
response.body = body;
|
|
526
545
|
}
|
|
527
546
|
else {
|
|
528
|
-
|
|
547
|
+
if (this.print.errors)
|
|
548
|
+
console.log(error);
|
|
529
549
|
response.status = 500;
|
|
530
550
|
response.body = inspect(error, { colors: false });
|
|
531
551
|
}
|
|
@@ -559,7 +579,7 @@ export class Server {
|
|
|
559
579
|
catch (error) {
|
|
560
580
|
if (error.status !== 404)
|
|
561
581
|
throw error;
|
|
562
|
-
if (log_404) {
|
|
582
|
+
if (log_404 && this.print.logs) {
|
|
563
583
|
let s = `${' '.repeat(11)} ${method.toLowerCase()} 404: ${path}`;
|
|
564
584
|
if (_path !== path)
|
|
565
585
|
s += ` ${_path.bracket()}`;
|