11111
This commit is contained in:
parent
db2c953ae6
commit
d0b5151228
42
index.js
42
index.js
@ -29,20 +29,17 @@ if (!fs.existsSync(cacheDir)) {
|
|||||||
fs.mkdirSync(cacheDir);
|
fs.mkdirSync(cacheDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 定时清理过期缓存数据
|
||||||
// 定时清理过期缓存数据并更新请求
|
setInterval(() => {
|
||||||
setInterval(async () => {
|
|
||||||
const currentTime = Date.now();
|
const currentTime = Date.now();
|
||||||
for (const key in pathIndex) {
|
for (const key in pathIndex) {
|
||||||
const { timestamp } = pathIndex[key];
|
if (currentTime - pathIndex[key].timestamp > 24 * 60 * 60 * 1000) {
|
||||||
// 24小时
|
|
||||||
if (currentTime - timestamp > 24 * 60 * 60 * 1000) {
|
|
||||||
delete pathIndex[key];
|
delete pathIndex[key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 1 * 60 * 60 * 1000); // 每隔 1 小时执行一次
|
}, 60 * 60 * 1000); // 每隔 1 小时执行一次
|
||||||
|
|
||||||
|
|
||||||
|
// 处理请求并返回数据
|
||||||
const server = http.createServer(async (req, res) => {
|
const server = http.createServer(async (req, res) => {
|
||||||
if (req.url === '/favicon.ico') {
|
if (req.url === '/favicon.ico') {
|
||||||
res.writeHead(204);
|
res.writeHead(204);
|
||||||
@ -50,6 +47,21 @@ const server = http.createServer(async (req, res) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 返回 endpoint, 缓存目录, 缓存数量, 用于监听服务是否正常运行
|
||||||
|
if (req.url === '/endpoint') {
|
||||||
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||||
|
res.end(JSON.stringify({
|
||||||
|
code: 200,
|
||||||
|
data: {
|
||||||
|
api: apiEndpoint,
|
||||||
|
port: port,
|
||||||
|
cacheDir: cacheDir,
|
||||||
|
pathIndexCount: Object.keys(pathIndex).length,
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const parsedUrl = url.parse(req.url, true);
|
const parsedUrl = url.parse(req.url, true);
|
||||||
const reqPath = parsedUrl.pathname;
|
const reqPath = parsedUrl.pathname;
|
||||||
const sign = parsedUrl.query.sign || '';
|
const sign = parsedUrl.query.sign || '';
|
||||||
@ -83,7 +95,6 @@ const server = http.createServer(async (req, res) => {
|
|||||||
// 修改 pathIndex 记录时,添加时间戳
|
// 修改 pathIndex 记录时,添加时间戳
|
||||||
pathIndex[uniqidhex] = { uniqid: data.uniqid, timestamp: Date.now() };
|
pathIndex[uniqidhex] = { uniqid: data.uniqid, timestamp: Date.now() };
|
||||||
|
|
||||||
|
|
||||||
cacheMetaFile = pathModule.join(cacheDir, `${data.uniqid}.meta`);
|
cacheMetaFile = pathModule.join(cacheDir, `${data.uniqid}.meta`);
|
||||||
cacheContentFile = pathModule.join(cacheDir, `${data.uniqid}.content`);
|
cacheContentFile = pathModule.join(cacheDir, `${data.uniqid}.content`);
|
||||||
tempCacheContentFile = pathModule.join(cacheDir, `${data.uniqid}_${crypto.randomBytes(16).toString('hex')}.temp`);
|
tempCacheContentFile = pathModule.join(cacheDir, `${data.uniqid}_${crypto.randomBytes(16).toString('hex')}.temp`);
|
||||||
@ -94,9 +105,9 @@ const server = http.createServer(async (req, res) => {
|
|||||||
// 如果内容缓存存在, 则直接调用
|
// 如果内容缓存存在, 则直接调用
|
||||||
if (fs.existsSync(cacheContentFile)) {
|
if (fs.existsSync(cacheContentFile)) {
|
||||||
serveFromCache(cacheMetaFile, cacheContentFile, res);
|
serveFromCache(cacheMetaFile, cacheContentFile, res);
|
||||||
return;
|
} else {
|
||||||
}
|
|
||||||
fetchAndServe(data, tempCacheContentFile, cacheContentFile, res);
|
fetchAndServe(data, tempCacheContentFile, cacheContentFile, res);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
res.writeHead(502, { 'Content-Type': 'text/plain' });
|
res.writeHead(502, { 'Content-Type': 'text/plain' });
|
||||||
res.end(apiData.message || 'Bad Gateway');
|
res.end(apiData.message || 'Bad Gateway');
|
||||||
@ -108,6 +119,7 @@ const server = http.createServer(async (req, res) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 检查缓存是否有效
|
||||||
const isCacheValid = (cacheMetaFile, cacheContentFile) => {
|
const isCacheValid = (cacheMetaFile, cacheContentFile) => {
|
||||||
if (!fs.existsSync(cacheMetaFile) || !fs.existsSync(cacheContentFile)) return false;
|
if (!fs.existsSync(cacheMetaFile) || !fs.existsSync(cacheContentFile)) return false;
|
||||||
|
|
||||||
@ -115,6 +127,7 @@ const isCacheValid = (cacheMetaFile, cacheContentFile) => {
|
|||||||
return cacheData.expiration > Date.now();
|
return cacheData.expiration > Date.now();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 从 API 获取数据
|
||||||
const fetchApiData = (reqPath, sign) => {
|
const fetchApiData = (reqPath, sign) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const postData = querystring.stringify({ path: reqPath, sign });
|
const postData = querystring.stringify({ path: reqPath, sign });
|
||||||
@ -146,6 +159,7 @@ const fetchApiData = (reqPath, sign) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 从真实 URL 获取数据并写入缓存
|
||||||
const fetchAndServe = (data, tempCacheContentFile, cacheContentFile, res) => {
|
const fetchAndServe = (data, tempCacheContentFile, cacheContentFile, res) => {
|
||||||
https.get(data.realUrl, { timeout: requestTimeout * 10 }, (realRes) => {
|
https.get(data.realUrl, { timeout: requestTimeout * 10 }, (realRes) => {
|
||||||
const cacheStream = fs.createWriteStream(tempCacheContentFile, { flags: 'w' });
|
const cacheStream = fs.createWriteStream(tempCacheContentFile, { flags: 'w' });
|
||||||
@ -188,6 +202,7 @@ const fetchAndServe = (data, tempCacheContentFile, cacheContentFile, res) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 从缓存中读取数据并返回
|
||||||
const serveFromCache = (cacheMetaFile, cacheContentFile, res) => {
|
const serveFromCache = (cacheMetaFile, cacheContentFile, res) => {
|
||||||
const cacheData = JSON.parse(fs.readFileSync(cacheMetaFile, 'utf8'));
|
const cacheData = JSON.parse(fs.readFileSync(cacheMetaFile, 'utf8'));
|
||||||
const readStream = fs.createReadStream(cacheContentFile);
|
const readStream = fs.createReadStream(cacheContentFile);
|
||||||
@ -217,6 +232,7 @@ const serveFromCache = (cacheMetaFile, cacheContentFile, res) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 处理响应错误
|
||||||
const handleResponseError = (res, tempCacheContentFile, realUrl) => {
|
const handleResponseError = (res, tempCacheContentFile, realUrl) => {
|
||||||
if (!res.headersSent) {
|
if (!res.headersSent) {
|
||||||
res.writeHead(502, { 'Content-Type': 'text/plain' });
|
res.writeHead(502, { 'Content-Type': 'text/plain' });
|
||||||
@ -227,6 +243,7 @@ const handleResponseError = (res, tempCacheContentFile, realUrl) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 处理缓存读取错误
|
||||||
const handleCacheReadError = (res) => {
|
const handleCacheReadError = (res) => {
|
||||||
if (!res.headersSent) {
|
if (!res.headersSent) {
|
||||||
res.writeHead(500, { 'Content-Type': 'text/plain' });
|
res.writeHead(500, { 'Content-Type': 'text/plain' });
|
||||||
@ -234,11 +251,12 @@ const handleCacheReadError = (res) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 启动服务器
|
||||||
server.listen(port, () => {
|
server.listen(port, () => {
|
||||||
console.log(`Proxy server is running on http://localhost:${port}`);
|
console.log(`Proxy server is running on http://localhost:${port}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Graceful shutdown
|
// 处理 SIGINT 信号(Ctrl+C)
|
||||||
process.on('SIGINT', () => {
|
process.on('SIGINT', () => {
|
||||||
console.log('Received SIGINT. Shutting down gracefully...');
|
console.log('Received SIGINT. Shutting down gracefully...');
|
||||||
server.close(() => {
|
server.close(() => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user