From 914dee8571c0af6290fad6b1a71b17247c9e2e7b Mon Sep 17 00:00:00 2001 From: Jonas Kvinge Date: Wed, 4 Nov 2020 22:16:20 +0100 Subject: [PATCH] Pass network proxy settings to gstreamer Fixes #558 --- src/engine/enginebase.cpp | 27 +++++++++++++++++++++++ src/engine/enginebase.h | 6 +++++ src/engine/gstengine.cpp | 1 + src/engine/gstenginepipeline.cpp | 21 ++++++++++++++++++ src/engine/gstenginepipeline.h | 7 ++++++ src/settings/networkproxysettingspage.cpp | 2 ++ src/settings/networkproxysettingspage.ui | 7 ++++++ 7 files changed, 71 insertions(+) diff --git a/src/engine/enginebase.cpp b/src/engine/enginebase.cpp index 0b2ba56eb..5b21d7921 100644 --- a/src/engine/enginebase.cpp +++ b/src/engine/enginebase.cpp @@ -34,6 +34,7 @@ #include "engine_fwd.h" #include "enginebase.h" #include "settings/backendsettingspage.h" +#include "settings/networkproxysettingspage.h" Engine::Base::Base() : volume_(100), @@ -56,6 +57,7 @@ Engine::Base::Base() fadeout_pause_enabled_(false), fadeout_duration_(2), fadeout_duration_nanosec_(2 * kNsecPerSec), + proxy_authentication_(false), about_to_end_emitted_(false) {} Engine::Base::~Base() {} @@ -127,6 +129,31 @@ void Engine::Base::ReloadSettings() { s.endGroup(); + s.beginGroup(NetworkProxySettingsPage::kSettingsGroup); + if (s.contains("engine") && s.value("engine").toBool()) { + QString proxy_host = s.value("hostname").toString(); + int proxy_port = s.value("port").toInt(); + if (proxy_host.isEmpty() || proxy_port <= 0) { + proxy_address_.clear(); + proxy_authentication_ = false; + proxy_user_.clear(); + proxy_pass_.clear(); + } + else { + proxy_address_ = QString("%1:%2").arg(proxy_host).arg(proxy_port); + proxy_authentication_ = s.value("use_authentication").toBool(); + proxy_user_ = s.value("username").toString(); + proxy_pass_ = s.value("password").toString(); + } + } + else { + proxy_address_.clear(); + proxy_authentication_ = false; + proxy_user_.clear(); + proxy_pass_.clear(); + } + s.endGroup(); + } void Engine::Base::EmitAboutToEnd() { diff --git a/src/engine/enginebase.h b/src/engine/enginebase.h index ba103ebf0..2aeb1b4ba 100644 --- a/src/engine/enginebase.h +++ b/src/engine/enginebase.h @@ -200,6 +200,12 @@ public: qint64 fadeout_pause_duration_; qint64 fadeout_pause_duration_nanosec_; + // Proxy + QString proxy_address_; + bool proxy_authentication_; + QString proxy_user_; + QString proxy_pass_; + private: bool about_to_end_emitted_; Q_DISABLE_COPY(Base) diff --git a/src/engine/gstengine.cpp b/src/engine/gstengine.cpp index 827c595bd..1f040a6c4 100644 --- a/src/engine/gstengine.cpp +++ b/src/engine/gstengine.cpp @@ -811,6 +811,7 @@ std::shared_ptr GstEngine::CreatePipeline() { ret->set_buffer_duration_nanosec(buffer_duration_nanosec_); ret->set_buffer_low_watermark(buffer_low_watermark_); ret->set_buffer_high_watermark(buffer_high_watermark_); + ret->set_proxy_settings(proxy_address_, proxy_authentication_, proxy_user_, proxy_pass_); ret->AddBufferConsumer(this); for (GstBufferConsumer *consumer : buffer_consumers_) { diff --git a/src/engine/gstenginepipeline.cpp b/src/engine/gstenginepipeline.cpp index cab2ff5b2..335c26b48 100644 --- a/src/engine/gstenginepipeline.cpp +++ b/src/engine/gstenginepipeline.cpp @@ -84,6 +84,7 @@ GstEnginePipeline::GstEnginePipeline(GstEngine *engine) buffer_low_watermark_(BackendSettingsPage::kDefaultBufferLowWatermark), buffer_high_watermark_(BackendSettingsPage::kDefaultBufferHighWatermark), buffering_(false), + proxy_authentication_(false), segment_start_(0), segment_start_received_(false), end_offset_nanosec_(-1), @@ -196,6 +197,13 @@ void GstEnginePipeline::set_buffer_high_watermark(const double value) { buffer_high_watermark_ = value; } +void GstEnginePipeline::set_proxy_settings(const QString &address, const bool authentication, const QString &user, const QString &pass) { + proxy_address_ = address; + proxy_authentication_ = authentication; + proxy_user_ = user; + proxy_pass_ = pass; +} + bool GstEnginePipeline::InitFromUrl(const QByteArray &stream_url, const QUrl original_url, const qint64 end_nanosec) { stream_url_ = stream_url; @@ -491,6 +499,19 @@ void GstEnginePipeline::SourceSetupCallback(GstPlayBin *bin, GParamSpec*, gpoint g_object_set(element, "ssl-strict", FALSE, nullptr); } + if (!instance->proxy_address_.isEmpty() && g_object_class_find_property(G_OBJECT_GET_CLASS(element), "proxy")) { + qLog(Debug) << "Setting proxy to" << instance->proxy_address_; + g_object_set(element, "proxy", instance->proxy_address_.toUtf8().constData(), nullptr); + if (instance->proxy_authentication_ && + g_object_class_find_property(G_OBJECT_GET_CLASS(element), "proxy-id") && + g_object_class_find_property(G_OBJECT_GET_CLASS(element), "proxy-pw") && + !instance->proxy_user_.isEmpty() && + !instance->proxy_pass_.isEmpty()) + { + g_object_set(element, "proxy-id", instance->proxy_user_.toUtf8().constData(), "proxy-pw", instance->proxy_pass_.toUtf8().constData(), nullptr); + } + } + // If the pipeline was buffering we stop that now. if (instance->buffering_) { instance->buffering_ = false; diff --git a/src/engine/gstenginepipeline.h b/src/engine/gstenginepipeline.h index 85fa84ffe..6758c8521 100644 --- a/src/engine/gstenginepipeline.h +++ b/src/engine/gstenginepipeline.h @@ -73,6 +73,7 @@ class GstEnginePipeline : public QObject { void set_buffer_duration_nanosec(const qint64 duration_nanosec); void set_buffer_low_watermark(const double value); void set_buffer_high_watermark(const double value); + void set_proxy_settings(const QString &address, const bool authentication, const QString &user, const QString &pass); // Creates the pipeline, returns false on error bool InitFromUrl(const QByteArray &stream_url, const QUrl original_url, const qint64 end_nanosec); @@ -213,6 +214,12 @@ class GstEnginePipeline : public QObject { double buffer_high_watermark_; bool buffering_; + // Proxy + QString proxy_address_; + bool proxy_authentication_; + QString proxy_user_; + QString proxy_pass_; + // These get called when there is a new audio buffer available QList buffer_consumers_; QMutex buffer_consumers_mutex_; diff --git a/src/settings/networkproxysettingspage.cpp b/src/settings/networkproxysettingspage.cpp index 4c6c23a3d..f6923404d 100644 --- a/src/settings/networkproxysettingspage.cpp +++ b/src/settings/networkproxysettingspage.cpp @@ -75,6 +75,7 @@ void NetworkProxySettingsPage::Load() { ui_->proxy_auth->setChecked(s.value("use_authentication", false).toBool()); ui_->proxy_username->setText(s.value("username").toString()); ui_->proxy_password->setText(s.value("password").toString()); + ui_->proxy_engine->setChecked(s.value("engine", true).toBool()); s.endGroup(); Init(ui_->layout_networkproxysettingspage->parentWidget()); @@ -100,6 +101,7 @@ void NetworkProxySettingsPage::Save() { s.setValue("use_authentication", ui_->proxy_auth->isChecked()); s.setValue("username", ui_->proxy_username->text()); s.setValue("password", ui_->proxy_password->text()); + s.setValue("engine", ui_->proxy_engine->isChecked()); s.endGroup(); NetworkProxyFactory::Instance()->ReloadSettings(); diff --git a/src/settings/networkproxysettingspage.ui b/src/settings/networkproxysettingspage.ui index 3cc1bf801..4c3e6432a 100644 --- a/src/settings/networkproxysettingspage.ui +++ b/src/settings/networkproxysettingspage.ui @@ -127,6 +127,13 @@ + + + + Use proxy settings for streaming + + +