mirror of https://github.com/keeweb/keeweb
fix #1535: network errors in Dropbox and GDrive on Windows
parent
a424c3286a
commit
af8d94d102
|
@ -7,7 +7,6 @@ import { StorageOAuthListener } from 'storage/storage-oauth-listener';
|
|||
import { UrlFormat } from 'util/formatting/url-format';
|
||||
import { Launcher } from 'comp/launcher';
|
||||
import { omitEmpty } from 'util/fn';
|
||||
import { Timeouts } from 'const/timeouts';
|
||||
import { Features } from 'util/features';
|
||||
import { createOAuthSession } from 'storage/pkce';
|
||||
|
||||
|
@ -138,47 +137,11 @@ class StorageBase {
|
|||
}
|
||||
|
||||
_httpRequestLauncher(config, onLoad) {
|
||||
const net = Launcher.remReq('electron').net;
|
||||
|
||||
const opts = Launcher.req('url').parse(config.url);
|
||||
|
||||
opts.method = config.method || 'GET';
|
||||
opts.headers = {
|
||||
'User-Agent': navigator.userAgent,
|
||||
...config.headers
|
||||
};
|
||||
opts.timeout = Timeouts.DefaultHttpRequest;
|
||||
|
||||
let data;
|
||||
if (config.data) {
|
||||
if (config.dataIsMultipart) {
|
||||
data = Buffer.concat(config.data.map((chunk) => Buffer.from(chunk)));
|
||||
} else {
|
||||
data = Buffer.from(config.data);
|
||||
}
|
||||
// Electron's API doesn't like that, while node.js needs it
|
||||
// opts.headers['Content-Length'] = data.byteLength;
|
||||
}
|
||||
|
||||
const req = net.request(opts);
|
||||
|
||||
let closed = false;
|
||||
req.on('close', () => {
|
||||
closed = true;
|
||||
});
|
||||
|
||||
req.on('response', (res) => {
|
||||
const chunks = [];
|
||||
const onClose = () => {
|
||||
this.logger.debug(
|
||||
'HTTP response',
|
||||
opts.method,
|
||||
config.url,
|
||||
res.statusCode,
|
||||
res.headers
|
||||
);
|
||||
|
||||
let response = Buffer.concat(chunks);
|
||||
Launcher.remoteApp().httpRequest(
|
||||
config,
|
||||
(level, ...args) => this.logger[level](...args),
|
||||
({ status, response, headers }) => {
|
||||
response = Buffer.from(response, 'hex');
|
||||
if (config.responseType === 'json') {
|
||||
try {
|
||||
response = JSON.parse(response.toString('utf8'));
|
||||
|
@ -192,33 +155,12 @@ class StorageBase {
|
|||
);
|
||||
}
|
||||
onLoad({
|
||||
status: res.statusCode,
|
||||
status,
|
||||
response,
|
||||
getResponseHeader: (name) => res.headers[name.toLowerCase()]
|
||||
getResponseHeader: (name) => headers[name.toLowerCase()]
|
||||
});
|
||||
};
|
||||
res.on('data', (chunk) => {
|
||||
chunks.push(chunk);
|
||||
if (closed && !res.readable) {
|
||||
// sometimes 'close' event arrives faster in Electron
|
||||
onClose();
|
||||
}
|
||||
});
|
||||
// in Electron it's not res.on('end'), like in node.js, which is a bit weird
|
||||
req.on('close', onClose);
|
||||
});
|
||||
req.on('error', (e) => {
|
||||
this.logger.error('HTTP error', opts.method, config.url, e);
|
||||
return config.error && config.error('network error', {});
|
||||
});
|
||||
req.on('timeout', () => {
|
||||
req.abort();
|
||||
return config.error && config.error('timeout', {});
|
||||
});
|
||||
if (data) {
|
||||
req.write(data);
|
||||
}
|
||||
req.end();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
_openPopup(url, title, width, height, extras) {
|
||||
|
|
|
@ -198,6 +198,7 @@ app.loadConfig = loadConfig;
|
|||
app.saveConfig = saveConfig;
|
||||
app.getAppMainRoot = getAppMainRoot;
|
||||
app.getAppContentRoot = getAppContentRoot;
|
||||
app.httpRequest = httpRequest;
|
||||
|
||||
function logProgress(name) {
|
||||
perfTimestamps?.push({ name, ts: process.hrtime() });
|
||||
|
@ -889,3 +890,58 @@ function migrateOldConfigs(key) {
|
|||
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
function httpRequest(config, log, onLoad) {
|
||||
// eslint-disable-next-line node/no-deprecated-api
|
||||
const opts = url.parse(config.url);
|
||||
|
||||
opts.method = config.method || 'GET';
|
||||
opts.headers = {
|
||||
'User-Agent': mainWindow.webContents.userAgent,
|
||||
...config.headers
|
||||
};
|
||||
opts.timeout = 60000;
|
||||
|
||||
let data;
|
||||
if (config.data) {
|
||||
if (config.dataIsMultipart) {
|
||||
data = Buffer.concat(config.data.map((chunk) => Buffer.from(chunk)));
|
||||
} else {
|
||||
data = Buffer.from(config.data);
|
||||
}
|
||||
// Electron's API doesn't like that, while node.js needs it
|
||||
// opts.headers['Content-Length'] = data.byteLength;
|
||||
}
|
||||
|
||||
const req = electron.net.request(opts);
|
||||
|
||||
req.on('response', (res) => {
|
||||
const chunks = [];
|
||||
const onClose = () => {
|
||||
log('info', 'HTTP response', opts.method, config.url, res.statusCode, res.headers);
|
||||
onLoad({
|
||||
status: res.statusCode,
|
||||
response: Buffer.concat(chunks).toString('hex'),
|
||||
headers: res.headers
|
||||
});
|
||||
};
|
||||
res.on('data', (chunk) => {
|
||||
chunks.push(chunk);
|
||||
});
|
||||
res.on('end', () => {
|
||||
onClose();
|
||||
});
|
||||
});
|
||||
req.on('error', (e) => {
|
||||
log('error', 'HTTP error', opts.method, config.url, e);
|
||||
return config.error && config.error('network error', {});
|
||||
});
|
||||
req.on('timeout', () => {
|
||||
req.abort();
|
||||
return config.error && config.error('timeout', {});
|
||||
});
|
||||
if (data) {
|
||||
req.write(data);
|
||||
}
|
||||
req.end();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
Release notes
|
||||
-------------
|
||||
##### v1.15.3 (2020-06-11)
|
||||
`-` fix #1535: network errors in Dropbox and GDrive on Windows
|
||||
|
||||
##### v1.15.2 (2020-06-09)
|
||||
`-` fix #1530: recursive creation of the portable directory
|
||||
`-` fix #1530: running from directories with hash symbols
|
||||
|
|
Loading…
Reference in New Issue