StarrySkyWorld commited on
Commit
72eebaa
·
verified ·
1 Parent(s): 803b30f

Create server.mjs

Browse files
Files changed (1) hide show
  1. server.mjs +115 -0
server.mjs ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import http from 'node:http';
2
+ import {Client} from 'itdog-web-api';
3
+
4
+ const port = Number.parseInt(process.env.PORT || '7860', 10);
5
+
6
+ const client = new Client();
7
+
8
+ const sendJson = (res, statusCode, payload) => {
9
+ const body = JSON.stringify(payload, null, 2);
10
+ res.writeHead(statusCode, {
11
+ 'content-type': 'application/json; charset=utf-8',
12
+ 'access-control-allow-origin': '*',
13
+ 'access-control-allow-methods': 'GET,POST,OPTIONS',
14
+ 'access-control-allow-headers': 'content-type',
15
+ });
16
+ res.end(body);
17
+ };
18
+
19
+ const readJsonBody = (req) => new Promise((resolve, reject) => {
20
+ let data = '';
21
+ req.on('data', (chunk) => {
22
+ data += chunk;
23
+ if (data.length > 2 * 1024 * 1024) {
24
+ reject(new Error('Request body too large'));
25
+ req.destroy();
26
+ }
27
+ });
28
+ req.on('end', () => { if (!data) {
29
+ resolve({});
30
+ return;
31
+ }
32
+ try {
33
+ resolve(JSON.parse(data));
34
+ } catch {
35
+ reject(new Error('Invalid JSON body'));
36
+ }
37
+ });
38
+ req.on('error', (err) => reject(err));
39
+ }); const pickAPIResult = (result) => ({
40
+ task_id: result.task_id,
41
+ wss_url: result.wss_url,
42
+ taskToken: result.taskToken,
43
+ });
44
+
45
+ const runWS = async (runner) => {
46
+ const messages = [];
47
+ const final = await runner((data) => {
48
+ messages.push(data);
49
+ });
50
+ return {
51
+ result: pickAPIResult(final.result),
52
+ messages,
53
+ };
54
+ };
55
+ const routes = {
56
+ 'POST /ping': (body) => runWS((onMessage) => client.ping(body, onMessage)),
57
+ 'POST /pingv6': (body) => runWS((onMessage) => client.pingV6(body, onMessage)),
58
+ 'POST /tcping': (body) => runWS((onMessage) => client.tcping(body, onMessage)),
59
+ 'POST /tcpingv6': (body) => runWS((onMessage) => client.tcpingV6(body, onMessage)),
60
+ 'POST /http': (body) => runWS((onMessage) => client.http(body, onMessage)),
61
+ 'POST /httpv6': (body) => runWS((onMessage) => client.httpV6(body, onMessage)),
62
+ 'POST /httping': (body) => runWS((onMessage) => client.httping(body, onMessage)),
63
+ 'POST /httpingv6': (body) => runWS((onMessage) => client.httpingV6(body, onMessage)),
64
+ 'POST /traceroute': (body) => runWS((onMessage) => client.traceRoute(body, onMessage)),
65
+ 'POST /traceroutev6': (body) => runWS((onMessage) => client.traceRouteV6(body, onMessage)),
66
+ 'POST /dns': (body) => runWS((onMessage) => client.dns(body, onMessage)),
67
+ 'POST /batch-tcping': (body) => runWS((onMessage) => client.batchTCPing(body, onMessage)),
68
+ 'POST /generic': async (body) => {
69
+ if (!body?.endpoint) {
70
+ throw new Error('Missing "endpoint" in body');
71
+ }
72
+ const method = body.method || 'POST';
73
+ const params = body.params || {};
74
+ return runWS((onMessage) => client.generic(body.endpoint, method, params, onMessage));
75
+ },
76
+ };
77
+
78
+ const server = http.createServer(async (req, res) => {
79
+ if (!req.url || !req.method) {
80
+ sendJson(res, 400, {error: 'Invalid request'});
81
+ return;
82
+ }
83
+
84
+ if (req.method === 'OPTIONS') {
85
+ sendJson(res, 204, {});
86
+ return;
87
+ }
88
+
89
+ if (req.method === 'GET' && req.url === '/') {
90
+ sendJson(res, 200, {
91
+ ok: true,
92
+ service: 'itdog-web-api',
93
+ endpoints: Object.keys(routes).map((key) => key.replace('POST ', '')),
94
+ });
95
+ return;
96
+ }
97
+
98
+ const routeKey = `${req.method} ${req.url}`;
99
+ const handler = routes[routeKey];
100
+ if (!handler) {
101
+ sendJson(res, 404, {error: 'Not found'});
102
+ return;
103
+ }
104
+
105
+ try {
106
+ const body = await readJsonBody(req);
107
+ const data = await handler(body);
108
+ sendJson(res, 200, data);
109
+ } catch (error) {
110
+ sendJson(res, 400, {error: error instanceof Error ? error.message : 'Unknown error'});
111
+ }
112
+ });
113
+
114
+ server.listen(port, () => { console.log(`Server listening on http://0.0.0.0:${port}`);
115
+ });