| 167 | } |
| 168 | |
| 169 | private readBody(req: IncomingMessage): Promise<Record<string, unknown>> { |
| 170 | return new Promise((resolve, reject) => { |
| 171 | const chunks: Buffer[] = [] |
| 172 | let size = 0 |
| 173 | const MAX_BODY_SIZE = 1024 * 1024 // 1MB |
| 174 | |
| 175 | req.on('data', (chunk: Buffer) => { |
| 176 | size += chunk.length |
| 177 | if (size > MAX_BODY_SIZE) { |
| 178 | reject(new Error('请求体过大')) |
| 179 | req.destroy() |
| 180 | return |
| 181 | } |
| 182 | chunks.push(chunk) |
| 183 | }) |
| 184 | |
| 185 | req.on('end', () => { |
| 186 | const raw = Buffer.concat(chunks).toString('utf-8') |
| 187 | if (!raw) { |
| 188 | resolve({}) |
| 189 | return |
| 190 | } |
| 191 | try { |
| 192 | resolve(JSON.parse(raw)) |
| 193 | } catch { |
| 194 | reject(new Error('无效的 JSON 格式')) |
| 195 | } |
| 196 | }) |
| 197 | |
| 198 | req.on('error', reject) |
| 199 | }) |
| 200 | } |
| 201 | |
| 202 | private async routeRequest(url: string, body: Record<string, unknown>): Promise<ApiResponse> { |
| 203 | switch (url) { |