mirror of
https://github.com/ZHANGTIANYAO1/teamspeak-music-bot.git
synced 2026-10-02 04:52:50 +08:00
Fix 7 corner cases found in second review pass
Critical:
- Persist serverProtocol/ts6ApiKey in database schema so TS6 config
survives restarts (added columns + manager save/load)
Medium:
- Clear udpErrorTimer on disconnect to prevent memory leak and stale
log messages from firing after teardown
- Guard against double connect() by disconnecting old client first
- Add settled guard in TS6HttpQuery.request() to prevent double
reject when both res error and req error fire
- Add res.on("error") handler to TS6HttpQuery response stream
Low:
- Cap probeTS3Query banner buffer at 256 bytes to prevent memory abuse
from non-TS3 services sending large data on port 10011
- Remove unnecessary EventEmitter inheritance from TS6HttpQuery
- Update database test fixtures with new serverProtocol/ts6ApiKey fields
https://claude.ai/code/session_016WhH58avUD9xy2dgADJgTh
This commit is contained in:
6 files changed
+54
-15
No files matched your search
@@ -1,6 +1,5 @@
|
||||
import http from "node:http";
|
||||
import https from "node:https";
|
||||
import { EventEmitter } from "node:events";
|
||||
|
||||
export interface HttpQueryOptions {
|
||||
host: string;
|
||||
@@ -31,11 +30,10 @@ export interface HttpQueryResult {
|
||||
* GET /1/channellist?sid={sid} → list channels
|
||||
* POST /1/clientupdate → update client properties
|
||||
*/
|
||||
export class TS6HttpQuery extends EventEmitter {
|
||||
export class TS6HttpQuery {
|
||||
private options: Required<HttpQueryOptions>;
|
||||
|
||||
constructor(options: HttpQueryOptions) {
|
||||
super();
|
||||
this.options = {
|
||||
host: options.host,
|
||||
port: options.port,
|
||||
@@ -68,6 +66,13 @@ export class TS6HttpQuery extends EventEmitter {
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
let settled = false;
|
||||
const fail = (err: Error) => {
|
||||
if (settled) return;
|
||||
settled = true;
|
||||
reject(err);
|
||||
};
|
||||
|
||||
const req = transport.request(
|
||||
{
|
||||
hostname: host,
|
||||
@@ -82,8 +87,10 @@ export class TS6HttpQuery extends EventEmitter {
|
||||
let data = "";
|
||||
res.setEncoding("utf-8");
|
||||
res.on("data", (chunk: string) => (data += chunk));
|
||||
res.on("error", reject);
|
||||
res.on("error", fail);
|
||||
res.on("end", () => {
|
||||
if (settled) return;
|
||||
settled = true;
|
||||
let parsed: unknown;
|
||||
try {
|
||||
parsed = JSON.parse(data);
|
||||
@@ -98,10 +105,10 @@ export class TS6HttpQuery extends EventEmitter {
|
||||
},
|
||||
);
|
||||
|
||||
req.on("error", reject);
|
||||
req.on("error", fail);
|
||||
req.on("timeout", () => {
|
||||
req.destroy();
|
||||
reject(new Error("TS6 HTTP Query timeout"));
|
||||
fail(new Error("TS6 HTTP Query timeout"));
|
||||
});
|
||||
|
||||
if (bodyStr) {
|
||||
|
||||
Reference in new issue
Block a user