CatPtain commited on
Commit
1e6a865
·
verified ·
1 Parent(s): 7a9a219

Update server.js

Browse files
Files changed (1) hide show
  1. server.js +43 -70
server.js CHANGED
@@ -3,41 +3,32 @@ const express = require('express');
3
  const bodyParser = require('body-parser');
4
  const cors = require('cors');
5
  const requestIp = require('request-ip');
6
- const crypto = require('crypto'); // 用于生成设备指纹的哈希值
7
- const { URL } = require('url'); // 用于验证 URL 格式
8
 
9
  const app = express();
10
 
11
  // === 配置常量 ===
12
- const PORT = process.env.PORT; // 动态端口由系统提供
13
- const HOST = '0.0.0.0'; // 允许来自外部的连接
 
14
 
15
  // === 中间件配置 ===
16
-
17
- // CORS 配置
18
  const corsOptions = {
19
- origin: '*', // 允许所有来源的请求
20
  methods: ['GET', 'POST', 'OPTIONS'],
21
  allowedHeaders: ['Content-Type'],
22
  };
23
  app.use(cors(corsOptions));
24
-
25
- // 使用 Body-Parser 解析 JSON 请求体
26
  app.use(bodyParser.json());
27
-
28
- // 使用 request-ip 中间件获取客户端 IP
29
  app.use(requestIp.mw());
30
 
31
- // === 内存存储及清理 ===
32
-
33
- // URL 存储字典(以用户唯一标识符为键)
34
  const urlMap = new Map();
35
-
36
- // 超时时间配置(以毫秒为单位)
37
  const EXPIRATION_TIME = 90 * 1000; // 90 秒
38
- const CLEANUP_INTERVAL = 60 * 1000; // 每 60 秒清理一次
39
 
40
- // 定时清理过期数据
41
  setInterval(() => {
42
  const now = Date.now();
43
  const expiredTime = now - EXPIRATION_TIME;
@@ -45,91 +36,73 @@ setInterval(() => {
45
  for (const [userId, { timestamp }] of urlMap) {
46
  if (timestamp < expiredTime) {
47
  console.log(`Deleting expired data for user: ${userId}`);
48
- urlMap.delete(userId); // 删除过期数据
49
  }
50
  }
51
  }, CLEANUP_INTERVAL);
52
 
53
- // === 辅助函数 ===
54
-
55
- // 生成设备指纹
56
- const generateDeviceFingerprint = (req) => {
57
- const ip = req.clientIp || '';
58
- const userAgent = req.headers['user-agent'] || '';
59
- const acceptLanguage = req.headers['accept-language'] || '';
60
- const connection = req.headers['connection'] || '';
61
- const encoding = req.headers['accept-encoding'] || '';
62
- const forwardedFor = req.headers['x-forwarded-for'] || '';
63
-
64
- // 将关键信息合并生成唯一指纹
65
- const rawFingerprint = `${ip}-${userAgent}-${acceptLanguage}-${connection}-${encoding}-${forwardedFor}`;
66
-
67
- // 使用 SHA-256 哈希算法生成指纹
68
- const fingerprint = crypto.createHash('sha256').update(rawFingerprint).digest('hex');
69
- return fingerprint;
70
- };
71
-
72
  // === 路由 ===
73
 
74
- // 存储 URL(POST 请求)
 
 
 
 
 
75
  app.post('/storeURL', (req, res) => {
76
- const url = req.body.url; // 从请求体中解析 URL
77
- const ip = req.clientIp; // 获取客户端 IP
78
 
79
- // 验证 URL 是否存在并合法
80
  if (!url) {
81
- return res.status(400).json({ error: 'URL is required.' });
82
  }
83
  try {
84
- new URL(url); // 验证 URL 格式
85
  } catch (err) {
86
- return res.status(400).json({ error: 'Invalid URL format.' });
87
  }
88
 
89
- // 生成用户唯一标识符(包括 IP 和设备指纹)
90
- const deviceFingerprint = generateDeviceFingerprint(req);
91
- const userId = `${ip}-${deviceFingerprint}`; // 结合 IP 和设备指纹生成唯一标识符
92
-
93
- // 存储到字典中
94
  urlMap.set(userId, { url, timestamp: Date.now() });
95
- console.log(`Stored URL for user: ${userId}`);
96
 
97
- // 返回成功响应
98
- res.json({ message: 'URL stored successfully.', userId });
99
  });
100
 
101
- // 获取 URL(GET 请求)
102
  app.get('/getURL', (req, res) => {
103
- const ip = req.clientIp; // 获取客户端 IP
104
-
105
- // 生成用户唯一标识符(包括 IP 和设备指纹)
106
- const deviceFingerprint = generateDeviceFingerprint(req);
107
- const userId = `${ip}-${deviceFingerprint}`;
108
 
109
- // 查询字典获取存储的 URL
110
  if (urlMap.has(userId)) {
111
  const storedData = urlMap.get(userId);
112
- storedData.timestamp = Date.now(); // 更新数据时间戳
113
- urlMap.set(userId, storedData); // 保存更新后的数据
114
 
115
  console.log(`Retrieved URL for user: ${userId}`);
116
- return res.json({ url: storedData.url });
117
  } else {
118
  console.error(`No URL found for user: ${userId}`);
119
- return res.status(404).json({ error: 'URL not found for this user.' });
120
  }
121
  });
122
 
123
- // 测试路由
124
- app.get("/", (req, res) => {
125
- res.send("Welcome to the URL Server! The server is running.");
126
- });
127
-
128
  // === 启动服务器 ===
129
  app.listen(PORT, HOST, (err) => {
130
  if (err) {
131
  console.error(`Error starting server: ${err}`);
132
- return;
133
  }
134
  console.log(`Server running on http://${HOST}:${PORT}`);
135
  });
 
 
 
 
 
 
 
 
 
 
3
  const bodyParser = require('body-parser');
4
  const cors = require('cors');
5
  const requestIp = require('request-ip');
6
+ const crypto = require('crypto');
7
+ const { URL } = require('url');
8
 
9
  const app = express();
10
 
11
  // === 配置常量 ===
12
+ const PORT = process.env.PORT || 3000;
13
+ const HOST = '0.0.0.0';
14
+ console.log(`Starting server! PORT: ${PORT}`);
15
 
16
  // === 中间件配置 ===
 
 
17
  const corsOptions = {
18
+ origin: '*',
19
  methods: ['GET', 'POST', 'OPTIONS'],
20
  allowedHeaders: ['Content-Type'],
21
  };
22
  app.use(cors(corsOptions));
 
 
23
  app.use(bodyParser.json());
 
 
24
  app.use(requestIp.mw());
25
 
26
+ // === 内存存储 ===
 
 
27
  const urlMap = new Map();
 
 
28
  const EXPIRATION_TIME = 90 * 1000; // 90 秒
29
+ const CLEANUP_INTERVAL = 60 * 1000;
30
 
31
+ // 定期清理任务
32
  setInterval(() => {
33
  const now = Date.now();
34
  const expiredTime = now - EXPIRATION_TIME;
 
36
  for (const [userId, { timestamp }] of urlMap) {
37
  if (timestamp < expiredTime) {
38
  console.log(`Deleting expired data for user: ${userId}`);
39
+ urlMap.delete(userId);
40
  }
41
  }
42
  }, CLEANUP_INTERVAL);
43
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  // === 路由 ===
45
 
46
+ // 健康检查
47
+ app.get("/", (req, res) => {
48
+ res.status(200).send({ message: "Server is healthy and running." });
49
+ });
50
+
51
+ // 存储 URL
52
  app.post('/storeURL', (req, res) => {
53
+ const url = req.body.url;
54
+ const ip = req.clientIp;
55
 
 
56
  if (!url) {
57
+ return res.status(400).json({ success: false, message: 'URL is required.' });
58
  }
59
  try {
60
+ new URL(url);
61
  } catch (err) {
62
+ return res.status(400).json({ success: false, message: 'Invalid URL format.' });
63
  }
64
 
65
+ const fingerprint = crypto.createHash('sha256').update(`${ip}-${req.headers['user-agent']}`).digest('hex');
66
+ const userId = `${ip}-${fingerprint}`;
 
 
 
67
  urlMap.set(userId, { url, timestamp: Date.now() });
 
68
 
69
+ console.log(`Stored URL for user: ${userId}`);
70
+ res.json({ success: true, message: 'URL stored successfully.', userId });
71
  });
72
 
73
+ // 获取 URL
74
  app.get('/getURL', (req, res) => {
75
+ const ip = req.clientIp;
76
+ const fingerprint = crypto.createHash('sha256').update(`${ip}-${req.headers['user-agent']}`).digest('hex');
77
+ const userId = `${ip}-${fingerprint}`;
 
 
78
 
 
79
  if (urlMap.has(userId)) {
80
  const storedData = urlMap.get(userId);
81
+ storedData.timestamp = Date.now();
82
+ urlMap.set(userId, storedData);
83
 
84
  console.log(`Retrieved URL for user: ${userId}`);
85
+ res.json({ success: true, url: storedData.url });
86
  } else {
87
  console.error(`No URL found for user: ${userId}`);
88
+ res.status(404).json({ success: false, message: 'URL not found for this user.' });
89
  }
90
  });
91
 
 
 
 
 
 
92
  // === 启动服务器 ===
93
  app.listen(PORT, HOST, (err) => {
94
  if (err) {
95
  console.error(`Error starting server: ${err}`);
96
+ process.exit(1);
97
  }
98
  console.log(`Server running on http://${HOST}:${PORT}`);
99
  });
100
+
101
+ // === 全局错误处理 ===
102
+ process.on('uncaughtException', (err) => {
103
+ console.error('Uncaught Exception:', err);
104
+ });
105
+
106
+ process.on('unhandledRejection', (reason, promise) => {
107
+ console.error('Unhandled Rejection at:', promise, 'reason:', reason);
108
+ });