From a3318c84b022282a5a4a2babc51d1e3ca634e25b Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Thu, 21 Apr 2016 16:06:45 +0200 Subject: Fix regenerating job-factory Only update installed custom url scheme handlers, and leave the rest of the job factory untouched, so we don't delete the protocol handlers and request interceptors Chromium passed us, and that are now owned by the job-factory. Change-Id: I640527487dda053463f8fa9986ceb47941593f2b Task-number: QTBUG-52790 Reviewed-by: Michal Klocek --- src/core/url_request_context_getter_qt.cpp | 37 +++++++++++++++++++++++++----- src/core/url_request_context_getter_qt.h | 3 +++ 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/core/url_request_context_getter_qt.cpp b/src/core/url_request_context_getter_qt.cpp index d266b279a..aa35485ae 100644 --- a/src/core/url_request_context_getter_qt.cpp +++ b/src/core/url_request_context_getter_qt.cpp @@ -88,6 +88,7 @@ using content::BrowserThread; URLRequestContextGetterQt::URLRequestContextGetterQt(QSharedPointer browserContext, content::ProtocolHandlerMap *protocolHandlers, content::URLRequestInterceptorScopedVector request_interceptors) : m_ignoreCertificateErrors(false) , m_browserContext(browserContext) + , m_baseJobFactory(0) , m_cookieDelegate(new CookieMonsterDelegateQt()) , m_requestInterceptors(request_interceptors.Pass()) { @@ -293,7 +294,9 @@ void URLRequestContextGetterQt::updateJobFactory() Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); if (m_urlRequestContext && !m_updateJobFactory.fetchAndStoreRelaxed(1)) - content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestContextGetterQt::generateJobFactory, this)); + content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, + base::Bind(&URLRequestContextGetterQt::regenerateJobFactory, + this, m_browserContext->customUrlSchemes())); } static bool doNetworkSessionParamsMatch(const net::HttpNetworkSession::Params &first, const net::HttpNetworkSession::Params &second) @@ -393,16 +396,16 @@ void URLRequestContextGetterQt::generateJobFactory() { Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); Q_ASSERT(m_urlRequestContext); + Q_ASSERT(!m_jobFactory); - m_jobFactory.reset(); scoped_ptr jobFactory(new net::URLRequestJobFactoryImpl()); { // Chromium has a few protocol handlers ready for us, only pick blob: and throw away the rest. content::ProtocolHandlerMap::iterator it = m_protocolHandlers.find(url::kBlobScheme); Q_ASSERT(it != m_protocolHandlers.end()); - // FIXME: release() passes owner-ship to the job-factory, prevent regenerating the job-factory jobFactory->SetProtocolHandler(it->first, it->second.release()); + m_protocolHandlers.clear(); } jobFactory->SetProtocolHandler(url::kDataScheme, new net::DataProtocolHandler()); @@ -413,23 +416,45 @@ void URLRequestContextGetterQt::generateJobFactory() jobFactory->SetProtocolHandler(url::kFtpScheme, new net::FtpProtocolHandler(new net::FtpNetworkLayer(m_urlRequestContext->host_resolver()))); - Q_FOREACH (const QByteArray &scheme, m_browserContext->customUrlSchemes()) { + m_installedCustomSchemes = m_browserContext->customUrlSchemes(); + Q_FOREACH (const QByteArray &scheme, m_installedCustomSchemes) { jobFactory->SetProtocolHandler(scheme.toStdString(), new CustomProtocolHandler(m_browserContext)); } + m_baseJobFactory = jobFactory.get(); + // Set up interceptors in the reverse order. scoped_ptr topJobFactory = jobFactory.Pass(); for (content::URLRequestInterceptorScopedVector::reverse_iterator i = m_requestInterceptors.rbegin(); i != m_requestInterceptors.rend(); ++i) topJobFactory.reset(new net::URLRequestInterceptingJobFactory(topJobFactory.Pass(), make_scoped_ptr(*i))); - m_requestInterceptors.weak_clear(); // FIXME: Prevents regenerating job-factory. + m_requestInterceptors.weak_clear(); m_jobFactory = topJobFactory.Pass(); m_urlRequestContext->set_job_factory(m_jobFactory.get()); +} + +void URLRequestContextGetterQt::regenerateJobFactory(const QList customSchemes) +{ + Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); + Q_ASSERT(m_urlRequestContext); + Q_ASSERT(m_jobFactory); + Q_ASSERT(m_baseJobFactory); + + m_updateJobFactory.storeRelease(0); + if (customSchemes == m_installedCustomSchemes) + return; - m_updateJobFactory = 0; + Q_FOREACH (const QByteArray &scheme, m_installedCustomSchemes) { + m_baseJobFactory->SetProtocolHandler(scheme.toStdString(), nullptr); + } + + m_installedCustomSchemes = customSchemes; + Q_FOREACH (const QByteArray &scheme, m_installedCustomSchemes) { + m_baseJobFactory->SetProtocolHandler(scheme.toStdString(), new CustomProtocolHandler(m_browserContext)); + } } scoped_refptr URLRequestContextGetterQt::GetNetworkTaskRunner() const diff --git a/src/core/url_request_context_getter_qt.h b/src/core/url_request_context_getter_qt.h index 760a71c92..b925232a6 100644 --- a/src/core/url_request_context_getter_qt.h +++ b/src/core/url_request_context_getter_qt.h @@ -89,6 +89,7 @@ private: void generateHttpCache(); void generateUserAgent(); void generateJobFactory(); + void regenerateJobFactory(const QList customSchemes); void cancelAllUrlRequests(); net::HttpNetworkSession::Params generateNetworkSessionParams(); @@ -104,9 +105,11 @@ private: scoped_ptr m_networkDelegate; scoped_ptr m_storage; scoped_ptr m_jobFactory; + net::URLRequestJobFactoryImpl *m_baseJobFactory; scoped_ptr m_dhcpProxyScriptFetcherFactory; scoped_refptr m_cookieDelegate; content::URLRequestInterceptorScopedVector m_requestInterceptors; + QList m_installedCustomSchemes; friend class NetworkDelegateQt; }; -- cgit v1.2.3