From 4ca78860904e17e728f4ca1011c979c9d37f1faf Mon Sep 17 00:00:00 2001 From: azivner Date: Sun, 16 Dec 2018 23:30:53 +0100 Subject: [PATCH] uniform requests through electron's net and node http/https to support different proxy setups --- package-lock.json | 156 +++++++++++++---------------------- src/services/sync.js | 127 +++++++++++++++------------- src/services/sync_options.js | 2 +- 3 files changed, 130 insertions(+), 155 deletions(-) diff --git a/package-lock.json b/package-lock.json index ba2538980..a0e892e68 100644 --- a/package-lock.json +++ b/package-lock.json @@ -671,9 +671,9 @@ "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" }, "asar": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/asar/-/asar-0.14.5.tgz", - "integrity": "sha512-2Di/TnY1sridHFKMFgxBh0Wk0gVxSZN4qQhRhjJn3UywZAvP5MHI0RNVSkpzmJ+n6t0BC8w/+1257wtSgQ3Kdg==", + "version": "0.14.6", + "resolved": "https://registry.npmjs.org/asar/-/asar-0.14.6.tgz", + "integrity": "sha512-ZqybKcdO5At6y3ge2RHxVImc6Eltb2t3sxT7lk4T4zjZBSFUuIGCIZY6f41dCjlvJSizN5QPRr8YTgMhpgBjLg==", "dev": true, "requires": { "chromium-pickle-js": "^0.2.0", @@ -682,7 +682,7 @@ "glob": "^6.0.4", "minimatch": "^3.0.3", "mkdirp": "^0.5.0", - "mksnapshot": "^0.3.0", + "mksnapshot": "^0.3.4", "tmp": "0.0.28" }, "dependencies": { @@ -2034,7 +2034,7 @@ }, "string_decoder": { "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true } @@ -2526,10 +2526,20 @@ } } }, + "electron-notarize": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/electron-notarize/-/electron-notarize-0.0.5.tgz", + "integrity": "sha512-YzrqZ6RDQ7Wt2RWlxzRoQUuxnTeXrfp7laH7XKcmQqrZ6GaAr50DMPvFMpqDKdrZSHSbcgZgB7ktIQbjvITmCQ==", + "dev": true, + "requires": { + "debug": "^4.1.0", + "fs-extra": "^7.0.0" + } + }, "electron-osx-sign": { - "version": "0.4.10", - "resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.4.10.tgz", - "integrity": "sha1-vk87ibKnWh3F8eckkIGrKSnKOiY=", + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.4.11.tgz", + "integrity": "sha512-VVd40nrnVqymvFrY9ZkOYgHJOvexHHYTR3di/SN+mjJ0OWhR1I8BRVj3U+Yamw6hnkZZNKZp52rqL5EFAAPFkQ==", "dev": true, "requires": { "bluebird": "^3.5.0", @@ -2537,7 +2547,7 @@ "debug": "^2.6.8", "isbinaryfile": "^3.0.2", "minimist": "^1.2.0", - "plist": "^2.1.0" + "plist": "^3.0.1" }, "dependencies": { "debug": { @@ -2552,69 +2562,50 @@ } }, "electron-packager": { - "version": "12.2.0", - "resolved": "https://registry.npmjs.org/electron-packager/-/electron-packager-12.2.0.tgz", - "integrity": "sha512-T5W/FIK4VXhYIOWxkehmz6zXt2S/sA9JZ3AL+/jeKCicQY6QVQ0K8B7W801L+GPTwbgTPycHjO+iqEf1BhZ+Iw==", + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/electron-packager/-/electron-packager-13.0.1.tgz", + "integrity": "sha512-fXfldaZ1wihpPaMTSGMxvCeETJwVArlnMmKafVXLJbbZwS+WTjY4iL7ju9WMQ0LNGuiiIwSMCQFxt5iA087mqg==", "dev": true, "requires": { "asar": "^0.14.0", - "debug": "^3.0.0", + "debug": "^4.0.1", "electron-download": "^4.1.1", - "electron-osx-sign": "^0.4.1", + "electron-notarize": "^0.0.5", + "electron-osx-sign": "^0.4.11", "extract-zip": "^1.0.3", - "fs-extra": "^5.0.0", + "fs-extra": "^7.0.0", "galactus": "^0.2.1", "get-package-info": "^1.0.0", - "nodeify": "^1.0.1", "parse-author": "^2.0.0", - "pify": "^3.0.0", - "plist": "^2.0.0", + "pify": "^4.0.0", + "plist": "^3.0.0", "rcedit": "^1.0.0", "resolve": "^1.1.6", "sanitize-filename": "^1.6.0", "semver": "^5.3.0", - "yargs-parser": "^10.0.0" + "yargs-parser": "^11.0.0" }, "dependencies": { "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", + "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==", "dev": true }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "fs-extra": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz", - "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true }, "yargs-parser": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", - "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", + "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", "dev": true, "requires": { - "camelcase": "^4.1.0" + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" } } } @@ -4305,7 +4296,7 @@ }, "pify": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true }, @@ -5608,12 +5599,6 @@ "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=" }, - "is-promise": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-1.0.1.tgz", - "integrity": "sha1-MVc3YcBX4zwukaq56W2gjO++duU=", - "dev": true - }, "is-proto-prop": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-proto-prop/-/is-proto-prop-1.0.1.tgz", @@ -6542,19 +6527,19 @@ "dev": true }, "mksnapshot": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/mksnapshot/-/mksnapshot-0.3.1.tgz", - "integrity": "sha1-JQHAVldDbXQs6Vik/5LHfkDdN+Y=", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/mksnapshot/-/mksnapshot-0.3.4.tgz", + "integrity": "sha512-FgUTiWiY+35LgL95P/MDYrBuQO5o0s3MmaWKX6ZJWoX4vMOY9vPsAv763l1OSSelL9jPsBQ/wf4bzfqTLNPSFg==", "dev": true, "requires": { "decompress-zip": "0.3.0", "fs-extra": "0.26.7", - "request": "^2.79.0" + "request": "2.x" }, "dependencies": { "fs-extra": { "version": "0.26.7", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz", + "resolved": "http://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz", "integrity": "sha1-muH92UiXeY7at20JGM9C0MMYT6k=", "dev": true, "requires": { @@ -6582,9 +6567,9 @@ "integrity": "sha1-mi3sg4Bvuy2XXyK+7IWcoms5OqE=" }, "moment": { - "version": "2.22.2", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz", - "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=" + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.23.0.tgz", + "integrity": "sha512-3IE39bHVqFbWWaPOMHZF98Q9c3LDKGTmypMiTM2QygGXXElkFWIH7GxfmlwmY2vwa+wmNsoYZmG2iusf1ZjJoA==" }, "mozjpeg": { "version": "6.0.1", @@ -7286,16 +7271,6 @@ "resolved": "https://registry.npmjs.org/node-status-codes/-/node-status-codes-1.0.0.tgz", "integrity": "sha1-WuVUHQJGRdMqWPzdyc7s6nrjrC8=" }, - "nodeify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/nodeify/-/nodeify-1.0.1.tgz", - "integrity": "sha1-ZKtpp7268DzhB7TwM1yHwLnpGx0=", - "dev": true, - "requires": { - "is-promise": "~1.0.0", - "promise": "~1.3.0" - } - }, "nopt": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", @@ -8041,26 +8016,20 @@ "integrity": "sha512-TuvHS8AOIZNAlE77WUDiR4rySV/VMptyMfcfeoMgs4P8apaZM3JrnbzBiixKUv+XR6i+BXrQh8WAnjaSPFO65Q==" }, "plist": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/plist/-/plist-2.1.0.tgz", - "integrity": "sha1-V8zbeggh3yGDEhejytVOPhRqECU=", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.1.tgz", + "integrity": "sha512-GpgvHHocGRyQm74b6FWEZZVRroHKE1I0/BTjAmySaohK+cUn+hZpbqXkc3KWgW3gQYkqcQej35FohcT0FRlkRQ==", "dev": true, "requires": { - "base64-js": "1.2.0", - "xmlbuilder": "8.2.2", + "base64-js": "^1.2.3", + "xmlbuilder": "^9.0.7", "xmldom": "0.1.x" }, "dependencies": { "base64-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.0.tgz", - "integrity": "sha1-o5mS1yNYSBGYK+XikLtqU9hnAPE=", - "dev": true - }, - "xmlbuilder": { - "version": "8.2.2", - "resolved": "http://registry.npmjs.org/xmlbuilder/-/xmlbuilder-8.2.2.tgz", - "integrity": "sha1-aSSGc0ELS6QuGmE2VR0pIjNap3M=", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", "dev": true } } @@ -8490,15 +8459,6 @@ } } }, - "promise": { - "version": "1.3.0", - "resolved": "http://registry.npmjs.org/promise/-/promise-1.3.0.tgz", - "integrity": "sha1-5cyaTIJ45GZP/twBx9qEhCsEAXU=", - "dev": true, - "requires": { - "is-promise": "~1" - } - }, "proto-list": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", diff --git a/src/services/sync.js b/src/services/sync.js index ee6d047ad..ecf3e0fbb 100644 --- a/src/services/sync.js +++ b/src/services/sync.js @@ -1,7 +1,7 @@ "use strict"; +const url = require('url'); const log = require('./log'); -const rp = require('request-promise'); const sql = require('./sql'); const sqlInit = require('./sql_init'); const optionService = require('./options'); @@ -49,7 +49,7 @@ async function sync() { catch (e) { proxyToggle = !proxyToggle; - if (e.message.indexOf('ECONNREFUSED') !== -1) { + if (e.message && e.message.indexOf('ECONNREFUSED') !== -1) { log.info("No connection to sync server."); return { @@ -216,68 +216,83 @@ async function checkContentHash(syncContext) { await contentHashService.checkContentHashes(resp.hashes); } -async function syncRequest(syncContext, method, uri, body) { - const fullUri = await syncOptions.getSyncServerHost() + uri; - +async function getClient() { if (utils.isElectron()) { - return new Promise((resolve, reject) => { - try { - const { net } = require('electron'); - - const request = net.request({ - method, - url: fullUri, - headers: { - Cookie: syncContext.cookieJar.header || "", - 'Content-Type': 'application/json' - } - }); - - request.on('response', response => { - if (response.headers['set-cookie']) { - syncContext.cookieJar.header = response.headers['set-cookie']; - } - - let data = ''; - - response.on('data', chunk => data += chunk); - - response.on('end', () => resolve(data.trim() ? JSON.parse(data) : null)); - }); - - request.end(JSON.stringify(body)); - } - catch (e) { - console.log(e); - - reject(e.message); - } - }); + return require('electron').net; } else { - try { - const options = { - method: method, - uri: fullUri, - jar: syncContext.cookieJar, - json: true, - body: body, - timeout: await syncOptions.getSyncTimeout() - }; + const {protocol} = url.parse(await syncOptions.getSyncServerHost()); - const syncProxy = await syncOptions.getSyncProxy(); - - if (syncProxy && proxyToggle) { - options.proxy = syncProxy; - } - - return await rp(options); - } catch (e) { - throw new Error(`Request to ${method} ${fullUri} failed, error: ${e.message}`); + if (protocol === 'http:' || protocol === 'https:') { + return require(protocol.substr(0, protocol.length - 1)); + } + else { + throw new Error(`Unrecognized protocol "${protocol}"`); } } } +async function syncRequest(syncContext, method, requestPath, body) { + const client = await getClient(); + const syncServerHost = await syncOptions.getSyncServerHost(); + + function generateError(e) { + return new Error(`Request to ${method} ${syncServerHost}${requestPath} failed, error: ${e.message}`); + } + + const parsedUrl = url.parse(syncServerHost); + + // TODO: add proxy support - see https://stackoverflow.com/questions/3862813/how-can-i-use-an-http-proxy-with-node-js-http-client + + return new Promise(async (resolve, reject) => { + try { + const request = client.request({ + method, + // url is used by electron net module + url: syncServerHost + requestPath, + // 4 fields below are used by http and https node modules + protocol: parsedUrl.protocol, + host: parsedUrl.hostname, + port: parsedUrl.port, + path: requestPath, + timeout: await syncOptions.getSyncTimeout(), + headers: { + Cookie: syncContext.cookieJar.header || "", + 'Content-Type': 'application/json' + } + }); + + request.on('response', response => { + if (response.headers['set-cookie']) { + syncContext.cookieJar.header = response.headers['set-cookie']; + } + + let responseStr = ''; + + response.on('data', chunk => responseStr += chunk); + + response.on('end', () => { + try { + const jsonObj = responseStr.trim() ? JSON.parse(responseStr) : null; + + resolve(jsonObj); + } + catch (e) { + log.error("Failed to deserialize sync response: " + responseStr); + + reject(generateError(e)); + } + }); + }); + + request.end(JSON.stringify(body)); + } + catch (e) { + reject(generateError(e)); + } + }); +} + const primaryKeys = { "notes": "noteId", "branches": "branchId", diff --git a/src/services/sync_options.js b/src/services/sync_options.js index d1f3ab9a1..c114260a4 100644 --- a/src/services/sync_options.js +++ b/src/services/sync_options.js @@ -17,6 +17,6 @@ async function get(name) { module.exports = { getSyncServerHost: async () => await get('syncServerHost'), isSyncSetup: async () => !!await get('syncServerHost'), - getSyncTimeout: async () => await get('syncServerTimeout'), + getSyncTimeout: async () => parseInt(await get('syncServerTimeout')), getSyncProxy: async () => await get('syncProxy') }; \ No newline at end of file