mirror of https://github.com/laurent22/joplin.git
parent
2c4cf9fbdb
commit
8bb5b4a557
|
@ -325,6 +325,7 @@
|
|||
"homenote",
|
||||
"hotfolder",
|
||||
"Howver",
|
||||
"hpagent",
|
||||
"Hrvatska",
|
||||
"htmlentities",
|
||||
"htmlfile",
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import Setting, { Env } from './models/Setting';
|
||||
import Logger, { TargetType, LoggerWrapper } from './Logger';
|
||||
import shim from './shim';
|
||||
const { setupProxySettings } = require('./shim-init-node');
|
||||
import BaseService from './services/BaseService';
|
||||
import reducer, { setStore } from './reducer';
|
||||
import KeychainServiceDriver from './services/keychain/KeychainServiceDriver.node';
|
||||
|
@ -456,6 +457,14 @@ export default class BaseApplication {
|
|||
syswidecas.addCAs(f);
|
||||
}
|
||||
},
|
||||
'net.proxyEnabled': async () => {
|
||||
setupProxySettings({
|
||||
maxConcurrentConnections: Setting.value('sync.maxConcurrentConnections'),
|
||||
proxyTimeout: Setting.value('net.proxyTimeout'),
|
||||
proxyEnabled: Setting.value('net.proxyEnabled'),
|
||||
proxyUrl: Setting.value('net.proxyUrl'),
|
||||
});
|
||||
},
|
||||
|
||||
// Note: this used to run when "encryption.enabled" was changed, but
|
||||
// now we run it anytime any property of the sync target info is
|
||||
|
@ -491,6 +500,9 @@ export default class BaseApplication {
|
|||
sideEffects['locale'] = sideEffects['dateFormat'];
|
||||
sideEffects['encryption.passwordCache'] = sideEffects['syncInfoCache'];
|
||||
sideEffects['encryption.masterPassword'] = sideEffects['syncInfoCache'];
|
||||
sideEffects['sync.maxConcurrentConnections'] = sideEffects['net.proxyEnabled'];
|
||||
sideEffects['sync.proxyTimeout'] = sideEffects['net.proxyEnabled'];
|
||||
sideEffects['sync.proxyUrl'] = sideEffects['net.proxyEnabled'];
|
||||
|
||||
if (action) {
|
||||
const effect = sideEffects[action.key];
|
||||
|
|
|
@ -1384,7 +1384,37 @@ class Setting extends BaseModel {
|
|||
label: () => _('Ignore TLS certificate errors'),
|
||||
storage: SettingStorage.File,
|
||||
},
|
||||
|
||||
'net.proxyEnabled': {
|
||||
value: false,
|
||||
type: SettingItemType.Bool,
|
||||
advanced: true,
|
||||
section: 'sync',
|
||||
isGlobal: true,
|
||||
public: true,
|
||||
label: () => _('Proxy enabled (beta)'),
|
||||
storage: SettingStorage.File,
|
||||
},
|
||||
'net.proxyUrl': {
|
||||
value: '',
|
||||
type: SettingItemType.String,
|
||||
advanced: true,
|
||||
section: 'sync',
|
||||
isGlobal: true,
|
||||
public: true,
|
||||
label: () => _('Proxy URL (beta)'),
|
||||
description: () => _('e.g "http://my.proxy.com:80". You can also set via environment variables'),
|
||||
storage: SettingStorage.File,
|
||||
},
|
||||
'net.proxyTimeout': {
|
||||
value: 1,
|
||||
type: SettingItemType.Int,
|
||||
advanced: true,
|
||||
section: 'sync',
|
||||
isGlobal: true,
|
||||
public: true,
|
||||
label: () => _('proxy timeout (seconds) (beta)'),
|
||||
storage: SettingStorage.File,
|
||||
},
|
||||
'sync.wipeOutFailSafe': {
|
||||
value: true,
|
||||
type: SettingItemType.Bool,
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
"follow-redirects": "^1.2.4",
|
||||
"form-data": "^2.1.4",
|
||||
"fs-extra": "^5.0.0",
|
||||
"hpagent": "^1.0.0",
|
||||
"html-entities": "^1.2.1",
|
||||
"html-minifier": "^3.5.15",
|
||||
"image-data-uri": "^2.0.0",
|
||||
|
|
|
@ -13,12 +13,15 @@ const urlValidator = require('valid-url');
|
|||
const { _ } = require('./locale');
|
||||
const http = require('http');
|
||||
const https = require('https');
|
||||
const { HttpProxyAgent, HttpsProxyAgent } = require('hpagent');
|
||||
const toRelative = require('relative');
|
||||
const timers = require('timers');
|
||||
const zlib = require('zlib');
|
||||
const dgram = require('dgram');
|
||||
const { basename, fileExtension, safeFileExtension } = require('./path-utils');
|
||||
|
||||
const proxySettings = {};
|
||||
|
||||
function fileExists(filePath) {
|
||||
try {
|
||||
return fs.statSync(filePath).isFile();
|
||||
|
@ -27,6 +30,20 @@ function fileExists(filePath) {
|
|||
}
|
||||
}
|
||||
|
||||
function isUrlHttps(url) {
|
||||
return url.startsWith('https');
|
||||
}
|
||||
|
||||
function resolveProxyUrl(proxyUrl) {
|
||||
return (
|
||||
proxyUrl ||
|
||||
process.env['http_proxy'] ||
|
||||
process.env['https_proxy'] ||
|
||||
process.env['HTTP_PROXY'] ||
|
||||
process.env['HTTPS_PROXY']
|
||||
);
|
||||
}
|
||||
|
||||
// https://github.com/sindresorhus/callsites/blob/main/index.js
|
||||
function callsites() {
|
||||
const _prepareStackTrace = Error.prepareStackTrace;
|
||||
|
@ -64,6 +81,13 @@ const gunzipFile = function(source, destination) {
|
|||
});
|
||||
};
|
||||
|
||||
function setupProxySettings(options) {
|
||||
proxySettings.maxConcurrentConnections = options.maxConcurrentConnections;
|
||||
proxySettings.proxyTimeout = options.proxyTimeout;
|
||||
proxySettings.proxyEnabled = options.proxyEnabled;
|
||||
proxySettings.proxyUrl = options.proxyUrl;
|
||||
}
|
||||
|
||||
function shimInit(options = null) {
|
||||
options = {
|
||||
sharp: null,
|
||||
|
@ -79,6 +103,7 @@ function shimInit(options = null) {
|
|||
const keytar = (shim.isWindows() || shim.isMac()) && !shim.isPortable() ? options.keytar : null;
|
||||
const appVersion = options.appVersion;
|
||||
|
||||
|
||||
shim.setNodeSqlite(options.nodeSqlite);
|
||||
|
||||
shim.fsDriver = () => {
|
||||
|
@ -420,10 +445,11 @@ function shimInit(options = null) {
|
|||
return new Buffer(data).toString('base64');
|
||||
};
|
||||
|
||||
shim.fetch = async function(url, options = null) {
|
||||
shim.fetch = async function(url, options = {}) {
|
||||
const validatedUrl = urlValidator.isUri(url);
|
||||
if (!validatedUrl) throw new Error(`Not a valid URL: ${url}`);
|
||||
|
||||
const resolvedProxyUrl = resolveProxyUrl(proxySettings.proxyUrl);
|
||||
options.agent = (resolvedProxyUrl && proxySettings.proxyEnabled) ? shim.proxyAgent(url, resolvedProxyUrl) : null;
|
||||
return shim.fetchWithRetry(() => {
|
||||
return nodeFetch(url, options);
|
||||
}, options);
|
||||
|
@ -466,6 +492,9 @@ function shimInit(options = null) {
|
|||
headers: headers,
|
||||
};
|
||||
|
||||
const resolvedProxyUrl = resolveProxyUrl(proxySettings.proxyUrl);
|
||||
requestOptions.agent = (resolvedProxyUrl && proxySettings.proxyEnabled) ? shim.proxyAgent(url, resolvedProxyUrl) : null;
|
||||
|
||||
const doFetchOperation = async () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let file = null;
|
||||
|
@ -572,6 +601,27 @@ function shimInit(options = null) {
|
|||
return url.startsWith('https') ? shim.httpAgent_.https : shim.httpAgent_.http;
|
||||
};
|
||||
|
||||
shim.proxyAgent = (serverUrl, proxyUrl) => {
|
||||
const proxyAgentConfig = {
|
||||
keepAlive: true,
|
||||
maxSockets: proxySettings.maxConcurrentConnections,
|
||||
keepAliveMsecs: 5000,
|
||||
proxy: proxyUrl,
|
||||
timeout: proxySettings.proxyTimeout * 1000,
|
||||
};
|
||||
|
||||
// Based on https://github.com/delvedor/hpagent#usage
|
||||
if (!isUrlHttps(proxyUrl) && !isUrlHttps(serverUrl)) {
|
||||
return new HttpProxyAgent(proxyAgentConfig);
|
||||
} else if (isUrlHttps(proxyUrl) && !isUrlHttps(serverUrl)) {
|
||||
return new HttpProxyAgent(proxyAgentConfig);
|
||||
} else if (!isUrlHttps(proxyUrl) && isUrlHttps(serverUrl)) {
|
||||
return new HttpsProxyAgent(proxyAgentConfig);
|
||||
} else {
|
||||
return new HttpsProxyAgent(proxyAgentConfig);
|
||||
}
|
||||
};
|
||||
|
||||
shim.openOrCreateFile = (filepath, defaultContents) => {
|
||||
// If the file doesn't exist, create it
|
||||
if (!fs.existsSync(filepath)) {
|
||||
|
@ -634,4 +684,4 @@ function shimInit(options = null) {
|
|||
};
|
||||
}
|
||||
|
||||
module.exports = { shimInit };
|
||||
module.exports = { shimInit, setupProxySettings };
|
||||
|
|
|
@ -16,7 +16,7 @@ let isTestingEnv_ = false;
|
|||
// (app-desktop, app-mobile, etc.) since we are sure they won't be dependency to
|
||||
// other packages (unlike the lib which can be included anywhere).
|
||||
//
|
||||
// Regarding the type - althought we import React, we only use it as a type
|
||||
// Regarding the type - although we import React, we only use it as a type
|
||||
// using `typeof React`. This is just to get types in hooks.
|
||||
//
|
||||
// https://stackoverflow.com/a/42816077/561309
|
||||
|
|
|
@ -3436,6 +3436,7 @@ __metadata:
|
|||
follow-redirects: ^1.2.4
|
||||
form-data: ^2.1.4
|
||||
fs-extra: ^5.0.0
|
||||
hpagent: ^1.0.0
|
||||
html-entities: ^1.2.1
|
||||
html-minifier: ^3.5.15
|
||||
image-data-uri: ^2.0.0
|
||||
|
@ -16672,6 +16673,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"hpagent@npm:^1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "hpagent@npm:1.0.0"
|
||||
checksum: 911a9ba612747f5c9403fb60c1abd0c47a27fa634826caad9aecad41b899533489da36c92758b5cd83576e2bf9e84e23a4374a40aa513106d5450f62856c4b2d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"html-encoding-sniffer@npm:^1.0.2":
|
||||
version: 1.0.2
|
||||
resolution: "html-encoding-sniffer@npm:1.0.2"
|
||||
|
|
Loading…
Reference in New Issue