Spaces:
Running
Running
File size: 6,038 Bytes
262a183 2a2fa33 7bffa9f 2a2fa33 01e6a7a ad533eb c18cf88 956a293 47b9f31 2a2fa33 4c2e97f ad533eb 9e8330a c18cf88 9e8330a 9a9d9c6 9e8330a 4c2e97f 9e8330a b7f676f 9e8330a b7f676f 9e8330a 9a9d9c6 9e8330a 4c2e97f b7f676f 9e8330a 4c2e97f 9a9d9c6 9e8330a 4c2e97f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | FROM node:22-alpine
RUN apk add --no-cache sqlite sqlite-dev
WORKDIR /app
RUN npm install -g omniroute
# ๅบ็ก็ฝ็ปไธ็ฏๅข้
็ฝฎ
ENV PORT=7860
ENV OMNIROUTE_PORT=7860
ENV HOST=0.0.0.0
ENV NODE_ENV=production
# ๐ ่ฎพ็ฝฎๆฐๅฏ็
ENV INITIAL_PASSWORD=Amd3dnow!
# ๐ ไธ่ฝฝๆฅๅฃ็่ฎฟ้ฎไปค็๏ผๅจ HF Space Settings โ Variables ้่ฆ็่ฟไธชๅผ๏ผ๏ผ
ENV DOWNLOAD_TOKEN=change_me_please
EXPOSE 7860
# ๅๅ
ฅไธ่ฝฝๆๅก่ๆฌ๏ผ็บฏ Node.js๏ผๆ ้้ขๅคไพ่ต๏ผ
RUN cat > /app/download_server.js << 'EOF'
const http = require('http');
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
const PORT = 7861;
const TOKEN = process.env.DOWNLOAD_TOKEN || 'change_me_please';
// ๅ
่ฎธไธ่ฝฝ็ๅฎๅ
จ็ฎๅฝ็ฝๅๅ
const ALLOWED_DIRS = ['/data', '/root/.omniroute'];
function safeResolvePath(filename) {
// ๅชๅ
่ฎธ็บฏๆไปถๅ๏ผๆ็ปไปปไฝ่ทฏๅพๅ้็ฌฆ๏ผ้ฒ่ทฏๅพ็ฉฟ่ถ๏ผ
if (!filename || filename.includes('/') || filename.includes('\\') || filename.includes('..')) {
return null;
}
// ไพๆฌกๅจ็ฝๅๅ็ฎๅฝไธญๆฅๆพๆไปถ
for (const dir of ALLOWED_DIRS) {
const fullPath = path.join(dir, filename);
if (fs.existsSync(fullPath) && fs.statSync(fullPath).isFile()) {
return fullPath;
}
}
return null;
}
const server = http.createServer((req, res) => {
const url = new URL(req.url, `http://localhost:${PORT}`);
const token = url.searchParams.get('token') || '';
const route = url.pathname;
// โโ ็ปไธ้ดๆ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
// ไฝฟ็จ้ๅญ็ฌฆๆฏ่พ้ฒๆญขๆถๅบๆปๅป
const tokenValid =
token.length === TOKEN.length &&
token.split('').every((c, i) => c === TOKEN[i]);
if (!tokenValid) {
res.writeHead(403, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'Forbidden: invalid token' }));
return;
}
// โโ GET /list โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
if (route === '/list') {
const result = {};
for (const dir of ALLOWED_DIRS) {
try {
result[dir] = fs.readdirSync(dir).map(name => {
const stat = fs.statSync(path.join(dir, name));
return { name, size: stat.size, mtime: stat.mtime };
});
} catch (_) {
result[dir] = `directory not found`;
}
}
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify(result, null, 2));
return;
}
// โโ GET /download?token=...&file=omni_storage.sqlite โโโโโโ
if (route === '/download') {
const filename = url.searchParams.get('file') || '';
const fullPath = safeResolvePath(filename);
if (!fullPath) {
res.writeHead(404, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: `File not found: ${filename}` }));
return;
}
const stat = fs.statSync(fullPath);
res.writeHead(200, {
'Content-Type': 'application/octet-stream',
'Content-Disposition': `attachment; filename="${filename}"`,
'Content-Length': stat.size,
});
fs.createReadStream(fullPath).pipe(res);
console.log(`[download] ${fullPath} (${stat.size} bytes)`);
return;
}
// โโ 404 โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
res.writeHead(404, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'Unknown route', routes: ['/list', '/download'] }));
});
server.listen(PORT, '0.0.0.0', () => {
console.log(`[download-server] listening on port ${PORT}`);
console.log(`[download-server] routes: /list /download?file=<filename>`);
});
EOF
CMD \
# โโ 1. ๅฏๅจ่ฏๆญๆฅๅฟ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ \
echo "=== ๅญๅจ่ฏๆญๅผๅง ===" && \
echo "--- /data ็ฎๅฝ ---" && \
ls -lah /data 2>&1 || echo "/data ็ฎๅฝไธๅญๅจ" && \
echo "--- /root/.omniroute ็ฎๅฝ ---" && \
ls -lah /root/.omniroute 2>&1 || echo "OmniRoute ็ฎๅฝไธๅญๅจ" && \
echo "--- ็ฃ็ๆ่ฝฝๆ
ๅต ---" && \
df -h && \
echo "=== ๅญๅจ่ฏๆญ็ปๆ ===" && \
\
# โโ 2. ๅผๆบไปๆไน
ๅๅญๅจๆขๅคๆฐๆฎ โโโโโโโโโโโโโโโโโโโโโโโโโโโ \
if [ -f /data/omni_storage.sqlite ]; then \
mkdir -p /root/.omniroute && \
cp /data/omni_storage.sqlite /root/.omniroute/storage.sqlite && \
echo "โ
ๆขๅค storage.sqlite ๆๅ"; \
else \
echo "โ ๏ธ /data/omni_storage.sqlite ไธๅญๅจ๏ผ่ทณ่ฟๆขๅค"; \
fi && \
if [ -f /data/omni_settings.json ]; then \
mkdir -p /root/.omniroute && \
cp /data/omni_settings.json /root/.omniroute/settings.json && \
echo "โ
ๆขๅค settings.json ๆๅ"; \
else \
echo "โ ๏ธ /data/omni_settings.json ไธๅญๅจ๏ผ่ทณ่ฟๆขๅค"; \
fi && \
\
# โโ 3. ๅๅฐ๏ผๆฏ 60 ็งๆๆฐๆฎๅคไปฝๅฐ /data โโโโโโโโโโโโโโโโโโโ \
(while true; do \
sleep 60; \
mkdir -p /data; \
[ -f /root/.omniroute/storage.sqlite ] && \
cp /root/.omniroute/storage.sqlite /data/omni_storage.sqlite && \
echo "๐พ [backup] storage.sqlite โ /data"; \
[ -f /root/.omniroute/settings.json ] && \
cp /root/.omniroute/settings.json /data/omni_settings.json && \
echo "๐พ [backup] settings.json โ /data"; \
done) & \
\
# โโ 4. ๅๅฐ๏ผๅฏๅจไธ่ฝฝๆๅก๏ผ7861 ็ซฏๅฃ๏ผโโโโโโโโโโโโโโโโโโโโโ \
node /app/download_server.js & \
\
# โโ 5. ๅๅฐ๏ผๅฏๅจไธป็จๅบ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ \
PORT=7860 omniroute |