bridge-update-server 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/bridge-updater.js +20 -10
- package/package.json +1 -1
- package/public/index.html +2 -2
- package/src/cache.js +3 -17
- package/src/mdns.js +7 -7
- package/src/router.js +30 -8
- package/src/server.js +4 -8
package/bin/bridge-updater.js
CHANGED
|
@@ -20,20 +20,30 @@ if (args.includes('--help') || args.includes('-h')) {
|
|
|
20
20
|
'用法: bridge-updater [options]',
|
|
21
21
|
'',
|
|
22
22
|
'选项:',
|
|
23
|
-
' --port <number>
|
|
24
|
-
' --
|
|
25
|
-
' --
|
|
26
|
-
' --
|
|
27
|
-
' --
|
|
23
|
+
' --port <number> HTTP 端口 (默认: 51145)',
|
|
24
|
+
' --svr-proto <string> 服务对外的协议 (如 https)',
|
|
25
|
+
' --svr-host <string> 服务对外的域名或IP',
|
|
26
|
+
' --svr-port <number> 服务对外的端口',
|
|
27
|
+
' --svr-path <string> 服务对外的路径前缀',
|
|
28
|
+
' --help, -h 显示帮助信息',
|
|
28
29
|
''
|
|
29
30
|
].join('\n'));
|
|
30
31
|
process.exit(0);
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
const port = parseInt(getArg('--port', '51145'), 10);
|
|
34
|
-
const
|
|
35
|
-
const
|
|
36
|
-
const
|
|
37
|
-
const
|
|
35
|
+
const svrProto = getArg('--svr-proto', '') || '';
|
|
36
|
+
const svrHost = getArg('--svr-host', '') || '';
|
|
37
|
+
const svrPort = parseInt(getArg('--svr-port', '0'), 10) || 0;
|
|
38
|
+
const svrPath = (getArg('--svr-path', '') || '').replace(/^\/+/, '').replace(/\/+$/, '');
|
|
39
|
+
const normalizedSvrPath = svrPath ? '/' + svrPath : '';
|
|
38
40
|
|
|
39
|
-
startServer({
|
|
41
|
+
startServer({
|
|
42
|
+
port,
|
|
43
|
+
svrOptions: {
|
|
44
|
+
proto: svrProto,
|
|
45
|
+
host: svrHost,
|
|
46
|
+
port: svrPort,
|
|
47
|
+
path: normalizedSvrPath
|
|
48
|
+
}
|
|
49
|
+
});
|
package/package.json
CHANGED
package/public/index.html
CHANGED
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
<span class="status" id="status-text">正在获取版本信息…</span>
|
|
99
99
|
</div>
|
|
100
100
|
<div id="buttons" style="display: none;">
|
|
101
|
-
<a id="btn-cache" class="btn btn-cache">本地下载</a>
|
|
101
|
+
<a id="btn-cache" class="btn btn-cache" target="_blank" rel="noopener">本地下载</a>
|
|
102
102
|
<a id="btn-github" class="btn btn-github" target="_blank" rel="noopener">GitHub 下载</a>
|
|
103
103
|
</div>
|
|
104
104
|
<div id="sha256"></div>
|
|
@@ -124,7 +124,7 @@
|
|
|
124
124
|
const btnGithub = document.getElementById('btn-github');
|
|
125
125
|
|
|
126
126
|
if (downUrl.local) {
|
|
127
|
-
btnCache.href =
|
|
127
|
+
btnCache.href = downUrl.local;
|
|
128
128
|
} else {
|
|
129
129
|
btnCache.removeAttribute('href');
|
|
130
130
|
btnCache.classList.add('btn-disabled');
|
package/src/cache.js
CHANGED
|
@@ -17,11 +17,6 @@ export function getCachedApkPath() {
|
|
|
17
17
|
return existsSync(filePath) ? filePath : null;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
// 是否已有APK缓存
|
|
21
|
-
export function hasCachedApk() {
|
|
22
|
-
return getCachedApkPath() !== null;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
20
|
// 获取APK文件流
|
|
26
21
|
export function getCachedApkStream() {
|
|
27
22
|
const filePath = getCachedApkPath();
|
|
@@ -51,17 +46,6 @@ function computeSha256(filePath) {
|
|
|
51
46
|
});
|
|
52
47
|
}
|
|
53
48
|
|
|
54
|
-
// 验证本地缓存文件的SHA256是否匹配
|
|
55
|
-
export async function verifyCachedApk() {
|
|
56
|
-
const info = getVersionInfo();
|
|
57
|
-
const filePath = getCachedApkPath();
|
|
58
|
-
if (!filePath || !info?.sha256) {
|
|
59
|
-
return false;
|
|
60
|
-
}
|
|
61
|
-
const actual = await computeSha256(filePath);
|
|
62
|
-
return actual === info.sha256;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
49
|
async function downloadFromUrl(url, destPath) {
|
|
66
50
|
const res = await fetch(url, {
|
|
67
51
|
headers: {'User-Agent': 'bridge-update-server'}
|
|
@@ -151,7 +135,9 @@ export async function triggerRebuild(discoverPeers) {
|
|
|
151
135
|
// 确保APK缓存可用。返回true表示已就绪,false表示正在同步中
|
|
152
136
|
export async function syncApk(discoverPeers) {
|
|
153
137
|
const info = getVersionInfo();
|
|
154
|
-
if (!info || downloading)
|
|
138
|
+
if (!info || downloading) {
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
155
141
|
|
|
156
142
|
const filePath = getCachedApkPath();
|
|
157
143
|
if (!filePath) {
|
package/src/mdns.js
CHANGED
|
@@ -11,19 +11,19 @@ let publishedService = null;
|
|
|
11
11
|
const instanceId = randomUUID();
|
|
12
12
|
|
|
13
13
|
// 启动mDNS广播
|
|
14
|
-
export async function startMdns(port,
|
|
14
|
+
export async function startMdns(port, svrOptions = {}) {
|
|
15
15
|
bonjourInstance = new Bonjour();
|
|
16
16
|
ciaoResponder = ciao.getResponder();
|
|
17
17
|
|
|
18
18
|
const txt = {instance: instanceId};
|
|
19
|
-
if (
|
|
20
|
-
txt.path =
|
|
19
|
+
if (svrOptions.path) {
|
|
20
|
+
txt.path = svrOptions.path;
|
|
21
21
|
}
|
|
22
|
-
if (
|
|
23
|
-
txt.host =
|
|
22
|
+
if (svrOptions.host) {
|
|
23
|
+
txt.host = svrOptions.host;
|
|
24
24
|
}
|
|
25
|
-
if (
|
|
26
|
-
txt.port = String(
|
|
25
|
+
if (svrOptions.port) {
|
|
26
|
+
txt.port = String(svrOptions.port);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
publishedService = ciaoResponder.createService({
|
package/src/router.js
CHANGED
|
@@ -2,17 +2,22 @@ import {fileURLToPath} from 'node:url';
|
|
|
2
2
|
import {dirname, join} from 'node:path';
|
|
3
3
|
import express, {Router} from 'express';
|
|
4
4
|
import {getVersionInfo} from './github.js';
|
|
5
|
-
import {getCachedApkSize, getCachedApkStream,
|
|
5
|
+
import {getCachedApkSize, getCachedApkStream, syncApk} from './cache.js';
|
|
6
6
|
|
|
7
7
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
8
|
|
|
9
9
|
// 创建REST API路由
|
|
10
|
-
export function createRouter(
|
|
10
|
+
export function createRouter(discoverPeers, svrOptions = {}, serverPort = 0) {
|
|
11
11
|
const router = Router();
|
|
12
12
|
|
|
13
13
|
// 静态文件
|
|
14
14
|
router.use(express.static(join(__dirname, '../public')));
|
|
15
15
|
|
|
16
|
+
// 连通性探测
|
|
17
|
+
router.get('/hello', (req, res) => {
|
|
18
|
+
res.send('hello');
|
|
19
|
+
});
|
|
20
|
+
|
|
16
21
|
// 获取最新版本信息
|
|
17
22
|
router.get('/version', (req, res) => {
|
|
18
23
|
const info = getVersionInfo();
|
|
@@ -23,12 +28,28 @@ export function createRouter(mdnsPath, discoverPeers) {
|
|
|
23
28
|
});
|
|
24
29
|
}
|
|
25
30
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
const proto = svrOptions.proto
|
|
32
|
+
|| req.get('X-Forwarded-Proto')
|
|
33
|
+
|| req.protocol
|
|
34
|
+
|| 'http';
|
|
35
|
+
|
|
36
|
+
const fwdHost = req.get('X-Forwarded-Host') || '';
|
|
37
|
+
const fwdHostName = fwdHost.split(':')[0];
|
|
38
|
+
const fwdHostPort = fwdHost.split(':')[1] || '';
|
|
39
|
+
const host = svrOptions.host || fwdHostName || req.hostname;
|
|
40
|
+
|
|
41
|
+
const rawPort = svrOptions.port
|
|
42
|
+
|| parseInt(req.get('X-Forwarded-Port') || fwdHostPort || '0', 10)
|
|
43
|
+
|| serverPort;
|
|
44
|
+
const isDefaultPort = (proto === 'https' && rawPort === 443)
|
|
45
|
+
|| (proto === 'http' && rawPort === 80);
|
|
46
|
+
const portStr = (!rawPort || isDefaultPort) ? '' : ':' + rawPort;
|
|
47
|
+
|
|
48
|
+
const path = svrOptions.path
|
|
49
|
+
|| req.get('X-Forwarded-Prefix')
|
|
50
|
+
|| '';
|
|
51
|
+
|
|
52
|
+
const localUrl = proto + '://' + host + portStr + path + '/download';
|
|
32
53
|
|
|
33
54
|
res.json({
|
|
34
55
|
state: true,
|
|
@@ -42,6 +63,7 @@ export function createRouter(mdnsPath, discoverPeers) {
|
|
|
42
63
|
sha256: info.sha256
|
|
43
64
|
}
|
|
44
65
|
});
|
|
66
|
+
console.log('[Version]', '返回版本信息', 'localUrl=', localUrl, 'githubUrl=', info.apkUrl);
|
|
45
67
|
});
|
|
46
68
|
|
|
47
69
|
// 下载APK
|
package/src/server.js
CHANGED
|
@@ -6,18 +6,14 @@ import {syncApk} from './cache.js';
|
|
|
6
6
|
import {discoverPeers, startMdns} from './mdns.js';
|
|
7
7
|
|
|
8
8
|
export async function startServer(options) {
|
|
9
|
-
const {port,
|
|
9
|
+
const {port, svrOptions} = options;
|
|
10
10
|
|
|
11
11
|
const app = express();
|
|
12
12
|
const server = createServer(app);
|
|
13
13
|
|
|
14
14
|
// 挂载路由
|
|
15
|
-
const router = createRouter(
|
|
16
|
-
|
|
17
|
-
app.use(mdnsPath, router);
|
|
18
|
-
} else {
|
|
19
|
-
app.use(router);
|
|
20
|
-
}
|
|
15
|
+
const router = createRouter(discoverPeers, svrOptions, port);
|
|
16
|
+
app.use(router);
|
|
21
17
|
|
|
22
18
|
// 每次轮询成功后同步APK
|
|
23
19
|
onPollComplete(() => syncApk(discoverPeers));
|
|
@@ -31,7 +27,7 @@ export async function startServer(options) {
|
|
|
31
27
|
});
|
|
32
28
|
|
|
33
29
|
// 启动mDNS广播
|
|
34
|
-
await startMdns(port,
|
|
30
|
+
await startMdns(port, svrOptions);
|
|
35
31
|
|
|
36
32
|
return server;
|
|
37
33
|
}
|