-
-
Notifications
You must be signed in to change notification settings - Fork 450
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add HTTP & SOCKS5 proxy support (#4321)
This can be configured using the `CHATTERINO2_PROXY_URL` environment variable. The behaviour is similar to curl's CURLOPT_PROXY
- Loading branch information
Showing
11 changed files
with
166 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
#include "providers/NetworkConfigurationProvider.hpp" | ||
|
||
#include "common/Env.hpp" | ||
#include "common/QLogging.hpp" | ||
|
||
#include <QNetworkProxy> | ||
#include <QSslConfiguration> | ||
#include <QUrl> | ||
|
||
namespace { | ||
/** | ||
* Creates a QNetworkProxy from a given URL. | ||
* | ||
* Creates an HTTP proxy by default, a Socks5 will be created if the scheme is 'socks5'. | ||
*/ | ||
QNetworkProxy createProxyFromUrl(const QUrl &url) | ||
{ | ||
QNetworkProxy proxy; | ||
proxy.setHostName(url.host(QUrl::FullyEncoded)); | ||
proxy.setUser(url.userName(QUrl::FullyEncoded)); | ||
proxy.setPassword(url.password(QUrl::FullyEncoded)); | ||
proxy.setPort(url.port(1080)); | ||
|
||
if (url.scheme().compare(QStringLiteral("socks5"), Qt::CaseInsensitive) == | ||
0) | ||
{ | ||
proxy.setType(QNetworkProxy::Socks5Proxy); | ||
} | ||
else | ||
{ | ||
proxy.setType(QNetworkProxy::HttpProxy); | ||
if (!proxy.user().isEmpty() || !proxy.password().isEmpty()) | ||
{ | ||
// for some reason, Qt doesn't set the Proxy-Authorization header | ||
const auto auth = proxy.user() + ":" + proxy.password(); | ||
const auto base64 = auth.toUtf8().toBase64(); | ||
proxy.setRawHeader("Proxy-Authorization", | ||
QByteArray("Basic ").append(base64)); | ||
} | ||
} | ||
|
||
return proxy; | ||
} | ||
|
||
/** | ||
* Attempts to apply the proxy specified by `url` as the application proxy. | ||
*/ | ||
void applyProxy(const QString &url) | ||
{ | ||
auto proxyUrl = QUrl(url); | ||
if (!proxyUrl.isValid() || proxyUrl.isEmpty()) | ||
{ | ||
qCDebug(chatterinoNetwork) | ||
<< "Invalid or empty proxy url: " << proxyUrl; | ||
return; | ||
} | ||
|
||
const auto proxy = createProxyFromUrl(proxyUrl); | ||
|
||
QNetworkProxy::setApplicationProxy(proxy); | ||
qCDebug(chatterinoNetwork) << "Set application proxy to" << proxy; | ||
} | ||
|
||
} // namespace | ||
|
||
namespace chatterino { | ||
|
||
void NetworkConfigurationProvider::applyFromEnv(const Env &env) | ||
{ | ||
if (env.proxyUrl) | ||
{ | ||
applyProxy(env.proxyUrl.get()); | ||
} | ||
} | ||
|
||
} // namespace chatterino |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
#pragma once | ||
|
||
#include "common/QLogging.hpp" | ||
|
||
#include <QNetworkProxy> | ||
#include <websocketpp/connection.hpp> | ||
|
||
#include <string> | ||
|
||
namespace chatterino { | ||
|
||
class Env; | ||
|
||
/** This class manipulates the global network configuration (e.g. proxies). */ | ||
class NetworkConfigurationProvider | ||
{ | ||
public: | ||
/** This class should never be instantiated. */ | ||
NetworkConfigurationProvider() = delete; | ||
|
||
/** | ||
* Applies the configuration requested from the environment variables. | ||
* | ||
* Currently a proxy is applied if configured. | ||
*/ | ||
static void applyFromEnv(const Env &env); | ||
|
||
template <class C> | ||
static void applyToWebSocket( | ||
const std::shared_ptr<websocketpp::connection<C>> &connection) | ||
{ | ||
const auto applicationProxy = QNetworkProxy::applicationProxy(); | ||
if (applicationProxy.type() != QNetworkProxy::HttpProxy) | ||
{ | ||
return; | ||
} | ||
std::string url = "http://"; | ||
url += applicationProxy.hostName().toStdString(); | ||
url += ":"; | ||
url += std::to_string(applicationProxy.port()); | ||
websocketpp::lib::error_code ec; | ||
connection->set_proxy(url, ec); | ||
if (ec) | ||
{ | ||
qCDebug(chatterinoNetwork) | ||
<< "Couldn't set websocket proxy:" << ec.value(); | ||
return; | ||
} | ||
|
||
connection->set_proxy_basic_auth( | ||
applicationProxy.user().toStdString(), | ||
applicationProxy.password().toStdString(), ec); | ||
if (ec) | ||
{ | ||
qCDebug(chatterinoNetwork) | ||
<< "Couldn't set websocket proxy auth:" << ec.value(); | ||
} | ||
} | ||
}; | ||
|
||
} // namespace chatterino |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters