diff options
author | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2016-04-15 12:45:59 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2016-04-20 14:32:58 +0000 |
commit | d56128c315ad89dddf507b10dc4332d05cc42f91 (patch) | |
tree | 65a2b340c82350d95cb29a1576e1053d6ba84a0c | |
parent | 5b8aad9fa24caeb50ff3640d01590a15ee4e23d8 (diff) |
Improve thread-safety of custom scheme handlers
Avoids accessing the QWebEngineUrlSchemeHandler from any other thread
than the UI thread, since it may be deleted at any time on the UI
thread.
Change-Id: Icb4331b3c36f6f619a9fd975d155a9fd608dc5e9
Reviewed-by: Kai Koehne <kai.koehne@qt.io>
-rw-r--r-- | src/core/browser_context_adapter.cpp | 10 | ||||
-rw-r--r-- | src/core/browser_context_adapter.h | 2 | ||||
-rw-r--r-- | src/core/custom_protocol_handler.cpp | 6 | ||||
-rw-r--r-- | src/core/custom_protocol_handler.h | 7 | ||||
-rw-r--r-- | src/core/type_conversion.h | 5 | ||||
-rw-r--r-- | src/core/url_request_context_getter_qt.cpp | 8 | ||||
-rw-r--r-- | src/core/url_request_custom_job.cpp | 28 | ||||
-rw-r--r-- | src/core/url_request_custom_job.h | 7 |
8 files changed, 51 insertions, 22 deletions
diff --git a/src/core/browser_context_adapter.cpp b/src/core/browser_context_adapter.cpp index cde279eac..6002b17b7 100644 --- a/src/core/browser_context_adapter.cpp +++ b/src/core/browser_context_adapter.cpp @@ -356,6 +356,16 @@ QHash<QByteArray, QWebEngineUrlSchemeHandler *> &BrowserContextAdapter::customUr return m_customUrlSchemeHandlers; } +const QHash<QByteArray, QWebEngineUrlSchemeHandler *> &BrowserContextAdapter::customUrlSchemeHandlers() const +{ + return m_customUrlSchemeHandlers; +} + +const QList<QByteArray> BrowserContextAdapter::customUrlSchemes() const +{ + return m_customUrlSchemeHandlers.keys(); +} + void BrowserContextAdapter::updateCustomUrlSchemeHandlers() { if (m_browserContext->url_request_getter_.get()) diff --git a/src/core/browser_context_adapter.h b/src/core/browser_context_adapter.h index 7ec83983f..a3367ddba 100644 --- a/src/core/browser_context_adapter.h +++ b/src/core/browser_context_adapter.h @@ -147,6 +147,8 @@ public: bool persistVisitedLinks() const; QHash<QByteArray, QWebEngineUrlSchemeHandler *> &customUrlSchemeHandlers(); + const QHash<QByteArray, QWebEngineUrlSchemeHandler *> &customUrlSchemeHandlers() const; + const QList<QByteArray> customUrlSchemes() const; void updateCustomUrlSchemeHandlers(); void addCustomUrlSchemeHandler(const QByteArray &, QWebEngineUrlSchemeHandler *); bool removeCustomUrlSchemeHandler(QWebEngineUrlSchemeHandler *); diff --git a/src/core/custom_protocol_handler.cpp b/src/core/custom_protocol_handler.cpp index fd1a4de41..5b58694a1 100644 --- a/src/core/custom_protocol_handler.cpp +++ b/src/core/custom_protocol_handler.cpp @@ -43,8 +43,8 @@ namespace QtWebEngineCore { -CustomProtocolHandler::CustomProtocolHandler(QWebEngineUrlSchemeHandler *schemeHandler) - : m_schemeHandler(schemeHandler) +CustomProtocolHandler::CustomProtocolHandler(QWeakPointer<const BrowserContextAdapter> adapter) + : m_adapter(adapter) { } @@ -53,7 +53,7 @@ net::URLRequestJob *CustomProtocolHandler::MaybeCreateJob(net::URLRequest *reque if (!networkDelegate) return new net::URLRequestErrorJob(request, Q_NULLPTR, net::ERR_ACCESS_DENIED); - return new URLRequestCustomJob(request, networkDelegate, m_schemeHandler); + return new URLRequestCustomJob(request, networkDelegate, request->url().scheme(), m_adapter); } } // namespace diff --git a/src/core/custom_protocol_handler.h b/src/core/custom_protocol_handler.h index 94da28673..8b6756715 100644 --- a/src/core/custom_protocol_handler.h +++ b/src/core/custom_protocol_handler.h @@ -42,10 +42,9 @@ #include <QtCore/QByteArray> #include <QtCore/QObject> -#include <QtCore/qcompilerdetection.h> // Needed for Q_DECL_OVERRIDE +#include <QtCore/QWeakPointer> QT_FORWARD_DECLARE_CLASS(QIODevice) -QT_FORWARD_DECLARE_CLASS(QWebEngineUrlSchemeHandler) namespace net { class NetworkDelegate; @@ -61,13 +60,13 @@ class BrowserContextAdapter; class QWEBENGINE_EXPORT CustomProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler { public: - CustomProtocolHandler(QWebEngineUrlSchemeHandler *); + CustomProtocolHandler(QWeakPointer<const BrowserContextAdapter> adapter); virtual net::URLRequestJob *MaybeCreateJob(net::URLRequest *request, net::NetworkDelegate *networkDelegate) const Q_DECL_OVERRIDE; private: DISALLOW_COPY_AND_ASSIGN(CustomProtocolHandler); - QWebEngineUrlSchemeHandler *m_schemeHandler; + QWeakPointer<const BrowserContextAdapter> m_adapter; }; } // namespace diff --git a/src/core/type_conversion.h b/src/core/type_conversion.h index eb874a26d..e97ebed6f 100644 --- a/src/core/type_conversion.h +++ b/src/core/type_conversion.h @@ -73,6 +73,11 @@ inline QString toQt(const std::string &string) return QString::fromStdString(string); } +inline QByteArray toQByteArray(const std::string &string) +{ + return QByteArray::fromStdString(string); +} + inline base::string16 toString16(const QString &qString) { #if defined(OS_WIN) diff --git a/src/core/url_request_context_getter_qt.cpp b/src/core/url_request_context_getter_qt.cpp index daa07b54b..dfc647731 100644 --- a/src/core/url_request_context_getter_qt.cpp +++ b/src/core/url_request_context_getter_qt.cpp @@ -308,7 +308,6 @@ void URLRequestContextGetterQt::updateHttpCache() void URLRequestContextGetterQt::updateJobFactory() { Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); - Q_ASSERT(m_jobFactory); content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestContextGetterQt::generateJobFactory, this)); } @@ -429,10 +428,9 @@ void URLRequestContextGetterQt::generateJobFactory() jobFactory->SetProtocolHandler(url::kFtpScheme, new net::FtpProtocolHandler(new net::FtpNetworkLayer(m_urlRequestContext->host_resolver()))); - QHash<QByteArray, QWebEngineUrlSchemeHandler*>::const_iterator it = m_browserContext->customUrlSchemeHandlers().constBegin(); - const QHash<QByteArray, QWebEngineUrlSchemeHandler*>::const_iterator end = m_browserContext->customUrlSchemeHandlers().constEnd(); - for (; it != end; ++it) - jobFactory->SetProtocolHandler(it.key().toStdString(), new CustomProtocolHandler(it.value())); + Q_FOREACH (const QByteArray &scheme, m_browserContext->customUrlSchemes()) { + jobFactory->SetProtocolHandler(scheme.toStdString(), new CustomProtocolHandler(m_browserContext)); + } // Set up interceptors in the reverse order. scoped_ptr<net::URLRequestJobFactory> topJobFactory = jobFactory.Pass(); diff --git a/src/core/url_request_custom_job.cpp b/src/core/url_request_custom_job.cpp index 07087c247..493bdb703 100644 --- a/src/core/url_request_custom_job.cpp +++ b/src/core/url_request_custom_job.cpp @@ -39,6 +39,7 @@ #include "api/qwebengineurlrequestjob.h" #include "api/qwebengineurlschemehandler.h" +#include "browser_context_adapter.h" #include "type_conversion.h" #include "content/public/browser/browser_thread.h" @@ -54,9 +55,11 @@ using namespace net; namespace QtWebEngineCore { -URLRequestCustomJob::URLRequestCustomJob(URLRequest *request, NetworkDelegate *networkDelegate, QWebEngineUrlSchemeHandler *schemeHandler) +URLRequestCustomJob::URLRequestCustomJob(URLRequest *request, NetworkDelegate *networkDelegate, + const std::string &scheme, QWeakPointer<const BrowserContextAdapter> adapter) : URLRequestJob(request, networkDelegate) - , m_schemeHandler(schemeHandler) + , m_scheme(scheme) + , m_adapter(adapter) , m_shared(new URLRequestCustomJobShared(this)) { } @@ -328,11 +331,22 @@ void URLRequestCustomJobShared::startAsync() delete this; return; } - m_delegate = new URLRequestCustomJobDelegate(this); - m_asyncInitialized = true; - QWebEngineUrlRequestJob *requestJob = new QWebEngineUrlRequestJob(m_delegate); - if (m_job) - m_job->m_schemeHandler->requestStarted(requestJob); + + QWebEngineUrlSchemeHandler *schemeHandler = 0; + QSharedPointer<const BrowserContextAdapter> browserContext = m_job->m_adapter.toStrongRef(); + if (browserContext) + schemeHandler = browserContext->customUrlSchemeHandlers()[toQByteArray(m_job->m_scheme)]; + if (schemeHandler) { + m_delegate = new URLRequestCustomJobDelegate(this); + m_asyncInitialized = true; + QWebEngineUrlRequestJob *requestJob = new QWebEngineUrlRequestJob(m_delegate); + schemeHandler->requestStarted(requestJob); + } else { + lock.unlock(); + abort(); + delete this; + return; + } } } // namespace diff --git a/src/core/url_request_custom_job.h b/src/core/url_request_custom_job.h index eedb41814..be1598ccc 100644 --- a/src/core/url_request_custom_job.h +++ b/src/core/url_request_custom_job.h @@ -45,17 +45,17 @@ #include <QtCore/QPointer> QT_FORWARD_DECLARE_CLASS(QIODevice) -QT_FORWARD_DECLARE_CLASS(QWebEngineUrlSchemeHandler) namespace QtWebEngineCore { +class BrowserContextAdapter; class URLRequestCustomJobDelegate; class URLRequestCustomJobShared; // A request job that handles reading custom URL schemes class URLRequestCustomJob : public net::URLRequestJob { public: - URLRequestCustomJob(net::URLRequest *request, net::NetworkDelegate *networkDelegate, QWebEngineUrlSchemeHandler *schemeHandler); + URLRequestCustomJob(net::URLRequest *request, net::NetworkDelegate *networkDelegate, const std::string &scheme, QWeakPointer<const BrowserContextAdapter> adapter); virtual void Start() Q_DECL_OVERRIDE; virtual void Kill() Q_DECL_OVERRIDE; virtual bool ReadRawData(net::IOBuffer *buf, int bufSize, int *bytesRead) Q_DECL_OVERRIDE; @@ -67,7 +67,8 @@ protected: virtual ~URLRequestCustomJob(); private: - QWebEngineUrlSchemeHandler *m_schemeHandler; + std::string m_scheme; + QWeakPointer<const BrowserContextAdapter> m_adapter; URLRequestCustomJobShared *m_shared; friend class URLRequestCustomJobShared; |