Add General.proxy setting, supports HTTP & SOCKS5

This commit is contained in:
miruka 2021-03-02 12:11:54 -04:00
parent b0d31af3c0
commit f6f0a0c1ee
5 changed files with 44 additions and 1 deletions

View File

@ -540,7 +540,8 @@ class Backend:
# We just want that client's aiohttp session, that way we don't have # We just want that client's aiohttp session, that way we don't have
# to depend ourselves on aiohttp + aiohttp-socks # to depend ourselves on aiohttp + aiohttp-socks
client = nio.AsyncClient(homeserver="") proxy = self.settings.General.proxy
client = nio.AsyncClient(homeserver="", proxy=proxy)
await have_session_be_created(client) await have_session_be_created(client)
session = type(client.client_session)( session = type(client.client_session)(

View File

@ -167,11 +167,18 @@ class MatrixClient(nio.AsyncClient):
store = Path(backend.appdirs.user_data_dir) / "encryption" store = Path(backend.appdirs.user_data_dir) / "encryption"
store.mkdir(parents=True, exist_ok=True) store.mkdir(parents=True, exist_ok=True)
proxy = backend.settings.General.proxy
host = re.sub(r":\d+$", "", urlparse(homeserver).netloc)
if host in ("127.0.0.1", "localhost", "::1"):
proxy = None
super().__init__( super().__init__(
homeserver = homeserver, homeserver = homeserver,
user = user, user = user,
device_id = device_id, device_id = device_id,
store_path = store, store_path = store,
proxy = proxy,
config = nio.AsyncClientConfig( config = nio.AsyncClientConfig(
max_timeout_retry_wait_time = 10, max_timeout_retry_wait_time = 10,
# TODO: pass a custom encryption DB pickle key? # TODO: pass a custom encryption DB pickle key?

View File

@ -33,6 +33,12 @@ class General:
# Interface scale multiplier, e.g. 0.5 makes everything half-size. # Interface scale multiplier, e.g. 0.5 makes everything half-size.
zoom: float = 1.0 zoom: float = 1.0
# Adress of an HTTP or SOCKS5 proxy to pass network traffic through.
# Example adresses: "socks5://localhost:9050" (TOR with default port),
# "http://username:password@123.456.7.8:80" (HTTP with authentication).
# The application must be restarted to apply changes for this setting.
proxy: Optional[str] = None
class Presence: class Presence:
# Automatically set your presence to unavailable after this number of # Automatically set your presence to unavailable after this number of
# seconds without any mouse or keyboard activity. # seconds without any mouse or keyboard activity.

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: LGPL-3.0-or-later // SPDX-License-Identifier: LGPL-3.0-or-later
import QtQuick 2.12 import QtQuick 2.12
import CppUtils 0.1
import "." import "."
PythonBridge { PythonBridge {
@ -22,6 +23,8 @@ PythonBridge {
importNames("backend.qml_bridge", ["BRIDGE"], () => { importNames("backend.qml_bridge", ["BRIDGE"], () => {
callCoro("get_settings", [], ([settings, state, hist, theme, themeRules]) => { callCoro("get_settings", [], ([settings, state, hist, theme, themeRules]) => {
CppUtils.setProxy(settings.General.proxy || "")
window.settings = settings window.settings = settings
window.uiState = state window.uiState = state
window.history = hist window.history = hist

View File

@ -11,6 +11,9 @@
#include <QLocale> #include <QLocale>
#include <QObject> #include <QObject>
#include <QUuid> #include <QUuid>
#include <QNetworkProxy>
#include <QDebug>
#include <QDebug>
#ifdef Q_OS_LINUX #ifdef Q_OS_LINUX
#ifndef NO_X11 #ifndef NO_X11
@ -88,6 +91,29 @@ public slots:
#endif #endif
} }
void setProxy(QUrl url) const {
if (url.isEmpty()) return;
const QString scheme = url.scheme();
if (scheme != "socks5" && scheme != "http") {
qCritical() << "Unsupported proxy type on the Qt side:" << scheme;
return;
}
QNetworkProxy proxy;
proxy.setType(
scheme == "socks5" ?
QNetworkProxy::Socks5Proxy :
QNetworkProxy::HttpProxy
);
proxy.setHostName(url.host());
proxy.setPort(url.port() == -1 ? 0 : url.port());
proxy.setUser(url.userName());
proxy.setPassword(url.password());
QNetworkProxy::setApplicationProxy(proxy);
}
private: private:
QLocale appLocale; QLocale appLocale;
QString waylandDisplay = qEnvironmentVariable("WAYLAND_DISPLAY"); QString waylandDisplay = qEnvironmentVariable("WAYLAND_DISPLAY");