Skip to content

Commit 17d3add

Browse files
committed
Fix GooseMod#184: Use electron/net instead of https to download updates.
At least I can confirm that `versions.json` retrieval uses proxy now (so that I can boot discord). But I do not know how to force a self-update or modules update, so rest of the update functionalities are untested, for now.
1 parent 5c875eb commit 17d3add

File tree

3 files changed

+43
-56
lines changed

3 files changed

+43
-56
lines changed

src/asarUpdate.js

+4-20
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,18 @@
1-
const { get } = require('https');
1+
const { get } = require('./utils/get');
22
const fs = require('original-fs'); // Use original-fs, not Electron's modified fs
33
const { join } = require('path');
44

55
const asarPath = join(__filename, '..');
66

77
const asarUrl = `https://github.com/GooseMod/OpenAsar/releases/download/${oaVersion.split('-')[0]}/app.asar`;
88

9-
// todo: have these https utils centralised?
10-
const redirs = url => new Promise(res => get(url, r => { // Minimal wrapper around https.get to follow redirects
11-
const loc = r.headers.location;
12-
if (loc) return redirs(loc).then(res);
13-
14-
res(r);
15-
}));
16-
179
module.exports = async () => { // (Try) update asar
1810
if (!oaVersion.includes('-')) return;
1911
log('AsarUpdate', 'Updating...');
2012

21-
const res = (await redirs(asarUrl));
22-
23-
let data = [];
24-
res.on('data', d => {
25-
data.push(d);
26-
});
13+
const buf = (await get(asarUrl))[1];
2714

28-
res.on('end', () => {
29-
const buf = Buffer.concat(data);
30-
if (!buf.toString('hex').startsWith('04000000')) return log('AsarUpdate', 'Download error'); // Not like ASAR header
15+
if (!buf || !buf.toString('hex').startsWith('04000000')) return log('AsarUpdate', 'Download error'); // Request failed or ASAR header not present
3116

32-
fs.writeFile(asarPath, buf, e => log('AsarUpdate', 'Downloaded', e ?? ''));
33-
});
17+
fs.writeFile(asarPath, buf, e => log('AsarUpdate', 'Downloaded', e ?? ''));
3418
};

src/updater/moduleUpdater.js

+22-36
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ const fs = require('fs');
33
const Module = require('module');
44
const { execFile } = require('child_process');
55
const { app, autoUpdater } = require('electron');
6-
const { get } = require('https');
6+
const { get } = require('../utils/get');
77

88
const paths = require('../paths');
99

@@ -32,20 +32,6 @@ const resetTracking = () => {
3232
installing = Object.assign({}, base);
3333
};
3434

35-
const req = url => new Promise(res => get(url, r => { // Minimal wrapper around https.get to include body
36-
let dat = '';
37-
r.on('data', b => dat += b.toString());
38-
39-
r.on('end', () => res([ r, dat ]));
40-
}));
41-
42-
const redirs = url => new Promise(res => get(url, r => { // Minimal wrapper around https.get to follow redirects
43-
const loc = r.headers.location;
44-
if (loc) return redirs(loc).then(res);
45-
46-
res(r);
47-
}));
48-
4935
exports.init = (endpoint, { releaseChannel, version }) => {
5036
skipHost = settings.get('SKIP_HOST_UPDATE');
5137
skipModule = settings.get('SKIP_MODULE_UPDATE');
@@ -77,10 +63,10 @@ exports.init = (endpoint, { releaseChannel, version }) => {
7763
}
7864

7965
checkForUpdates() {
80-
req(this.url).then(([ r, b ]) => {
81-
if (r.statusCode === 204) return this.emit('update-not-available');
66+
get(this.url).then(([r, b]) => {
67+
if (!b || r === 204) return this.emit('update-not-available');
8268

83-
this.emit('update-manually', b);
69+
this.emit('update-manually', b.toString());
8470
});
8571
}
8672

@@ -111,7 +97,12 @@ exports.init = (endpoint, { releaseChannel, version }) => {
11197
};
11298

11399
const checkModules = async () => {
114-
remote = JSON.parse((await req(baseUrl + '/versions.json' + qs))[1]);
100+
const buf = (await get(baseUrl + '/versions.json' + qs))[1];
101+
if (!buf) {
102+
log('Modules', 'versions.json retrieval failure.');
103+
return;
104+
}
105+
remote = JSON.parse(buf.toString());
115106

116107
for (const name in installed) {
117108
const inst = installed[name].installedVersion;
@@ -131,27 +122,22 @@ const downloadModule = async (name, ver) => {
131122
downloading.total++;
132123

133124
const path = join(downloadPath, name + '-' + ver + '.zip');
134-
const file = fs.createWriteStream(path);
135125

136126
// log('Modules', 'Downloading', `${name}@${ver}`);
137127

138-
let success, total, cur = 0;
139-
const res = await redirs(baseUrl + '/' + name + '/' + ver + qs);
140-
success = res.statusCode === 200;
141-
total = parseInt(res.headers['content-length'] ?? 1, 10);
142-
143-
res.pipe(file);
128+
let success, total, cur = 0;
129+
const res = await get(baseUrl + '/' + name + '/' + ver + qs);
130+
success = res[0] === 200;
144131

145-
res.on('data', c => {
146-
cur += c.length;
147-
148-
events.emit('downloading-module', { name, cur, total });
149-
});
150-
151-
await new Promise((res) => file.on('close', res));
152-
153-
if (success) commitManifest();
154-
else downloading.fail++;
132+
// todo: if a progress-bar-like interface and stream-like file writing are still wanted, implement
133+
if (success) {
134+
total = parseInt(res[2].get('content-length') ?? 1, 10);
135+
events.emit('downloading-module', { name, total, total });
136+
fs.writeFile(path, res[1], e => log('ModuleUpdate', 'Writing to file failed:', e));
137+
commitManifest();
138+
} else {
139+
downloading.fail++;
140+
}
155141

156142
events.emit('downloaded-module', {
157143
name

src/utils/get.js

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
const { net } = require('electron');
2+
3+
// returns a promise that resolves to [statusCode, arrayBuffer, headers]
4+
// [code, null, null] if request failed
5+
module.exports = async (url) => {
6+
const request = new Request(url, {
7+
method: 'GET',
8+
redirect: 'follow'
9+
});
10+
const response = await net.fetch(request);
11+
12+
if (response.ok) {
13+
return [response.status, await response.arrayBuffer(), response.headers()];
14+
} else {
15+
return [response.status, null, null];
16+
}
17+
};

0 commit comments

Comments
 (0)