diff options
author | Michael Bruning <michael.bruning@theqtcompany.com> | 2015-12-03 11:16:32 +0100 |
---|---|---|
committer | Michael BrĂ¼ning <michael.bruning@theqtcompany.com> | 2015-12-04 16:32:39 +0000 |
commit | 32f83d9c2c884dfa516095c07f8590b2c4c99321 (patch) | |
tree | 0b2e3ab36aa5364717e223e9951d19788445616d /src/core | |
parent | 1847e158e09e24af704b02c8fb30adbf04d3befa (diff) |
Reuse or clean up HttpNetworkSession when (re-) setting a cache type.
Not reusing or cleaning up the session led to race conditions which in
turn lead to crashes and asserts.
Reuse the session if parameters match, clean up and it recreate otherwise.
Task-number: QTBUG-49397
Change-Id: I4f846a448b50d80a3cf7c4f9bb833fa6d64974d7
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@theqtcompany.com>
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/url_request_context_getter_qt.cpp | 102 | ||||
-rw-r--r-- | src/core/url_request_context_getter_qt.h | 3 |
2 files changed, 81 insertions, 24 deletions
diff --git a/src/core/url_request_context_getter_qt.cpp b/src/core/url_request_context_getter_qt.cpp index 10923e4cb..c2e592bc5 100644 --- a/src/core/url_request_context_getter_qt.cpp +++ b/src/core/url_request_context_getter_qt.cpp @@ -126,22 +126,29 @@ void URLRequestContextGetterQt::updateStorageSettings() } } -void URLRequestContextGetterQt::generateStorage() +void URLRequestContextGetterQt::cancelAllUrlRequests() { Q_ASSERT(m_urlRequestContext); - if (m_storage) { - // We must stop all requests before deleting their backends. - std::set<const net::URLRequest*>* url_requests = m_urlRequestContext->url_requests(); - std::set<const net::URLRequest*>::const_iterator it = url_requests->begin(); - std::set<const net::URLRequest*>::const_iterator end = url_requests->end(); - for ( ; it != end; ++it) { - net::URLRequest* request = const_cast<net::URLRequest*>(*it); - if (request) - request->Cancel(); - } + std::set<const net::URLRequest*>* url_requests = m_urlRequestContext->url_requests(); + std::set<const net::URLRequest*>::const_iterator it = url_requests->begin(); + std::set<const net::URLRequest*>::const_iterator end = url_requests->end(); + for ( ; it != end; ++it) { + net::URLRequest* request = const_cast<net::URLRequest*>(*it); + if (request) + request->Cancel(); } +} + +void URLRequestContextGetterQt::generateStorage() +{ + Q_ASSERT(m_urlRequestContext); + + // We must stop all requests before deleting their backends. + if (m_storage) + cancelAllUrlRequests(); + m_storage.reset(new net::URLRequestContextStorage(m_urlRequestContext.get())); net::ProxyConfigService *proxyConfigService = m_proxyConfigService.fetchAndStoreAcquire(0); @@ -260,11 +267,56 @@ void URLRequestContextGetterQt::updateHttpCache() } } +static bool doNetworkSessionParamsMatch(const net::HttpNetworkSession::Params &first, const net::HttpNetworkSession::Params &second) +{ + if (first.transport_security_state != second.transport_security_state) + return false; + if (first.cert_verifier != second.cert_verifier) + return false; + if (first.channel_id_service != second.channel_id_service) + return false; + if (first.proxy_service != second.proxy_service) + return false; + if (first.ssl_config_service != second.ssl_config_service) + return false; + if (first.http_auth_handler_factory != second.http_auth_handler_factory) + return false; + if (first.network_delegate != second.network_delegate) + return false; + if (first.http_server_properties.get() != second.http_server_properties.get()) + return false; + if (first.ignore_certificate_errors != second.ignore_certificate_errors) + return false; + if (first.host_resolver != second.host_resolver) + return false; + + return true; +} + +net::HttpNetworkSession::Params URLRequestContextGetterQt::generateNetworkSessionParams() +{ + Q_ASSERT(m_urlRequestContext); + + net::HttpNetworkSession::Params network_session_params; + + network_session_params.transport_security_state = m_urlRequestContext->transport_security_state(); + network_session_params.cert_verifier = m_urlRequestContext->cert_verifier(); + network_session_params.channel_id_service = m_urlRequestContext->channel_id_service(); + network_session_params.proxy_service = m_urlRequestContext->proxy_service(); + network_session_params.ssl_config_service = m_urlRequestContext->ssl_config_service(); + network_session_params.http_auth_handler_factory = m_urlRequestContext->http_auth_handler_factory(); + network_session_params.network_delegate = m_networkDelegate.get(); + network_session_params.http_server_properties = m_urlRequestContext->http_server_properties(); + network_session_params.ignore_certificate_errors = m_ignoreCertificateErrors; + network_session_params.host_resolver = m_urlRequestContext->host_resolver(); + + return network_session_params; +} + void URLRequestContextGetterQt::generateHttpCache() { Q_ASSERT(m_urlRequestContext); Q_ASSERT(m_storage); - m_updateHttpCache = 0; net::HttpCache::DefaultBackend* main_backend = 0; switch (m_browserContext->httpCacheType()) { @@ -290,19 +342,21 @@ void URLRequestContextGetterQt::generateHttpCache() break; } - net::HttpNetworkSession::Params network_session_params; - network_session_params.transport_security_state = m_urlRequestContext->transport_security_state(); - network_session_params.cert_verifier = m_urlRequestContext->cert_verifier(); - network_session_params.channel_id_service = m_urlRequestContext->channel_id_service(); - network_session_params.proxy_service = m_urlRequestContext->proxy_service(); - network_session_params.ssl_config_service = m_urlRequestContext->ssl_config_service(); - network_session_params.http_auth_handler_factory = m_urlRequestContext->http_auth_handler_factory(); - network_session_params.network_delegate = m_networkDelegate.get(); - network_session_params.http_server_properties = m_urlRequestContext->http_server_properties(); - network_session_params.ignore_certificate_errors = m_ignoreCertificateErrors; - network_session_params.host_resolver = m_urlRequestContext->host_resolver(); + net::HttpCache *cache = 0; + net::HttpNetworkSession *network_session = 0; + net::HttpNetworkSession::Params network_session_params = generateNetworkSessionParams(); + + if (m_urlRequestContext->http_transaction_factory()) + network_session = m_urlRequestContext->http_transaction_factory()->GetSession(); - m_storage->set_http_transaction_factory(new net::HttpCache(network_session_params, main_backend)); + if (!network_session || !doNetworkSessionParamsMatch(network_session_params, network_session->params())) { + cancelAllUrlRequests(); + cache = new net::HttpCache(network_session_params, main_backend); + } else + cache = new net::HttpCache(network_session, main_backend); + + m_storage->set_http_transaction_factory(cache); + m_updateHttpCache = 0; } void URLRequestContextGetterQt::generateJobFactory() diff --git a/src/core/url_request_context_getter_qt.h b/src/core/url_request_context_getter_qt.h index 38cfd7957..dc861f8da 100644 --- a/src/core/url_request_context_getter_qt.h +++ b/src/core/url_request_context_getter_qt.h @@ -45,6 +45,7 @@ #include "base/single_thread_task_runner.h" #include "content/public/browser/content_browser_client.h" #include "content/public/common/url_constants.h" +#include "net/http/http_network_session.h" #include "net/url_request/url_request_context_storage.h" #include "net/url_request/url_request_job_factory_impl.h" #include "net/proxy/dhcp_proxy_script_fetcher_factory.h" @@ -84,6 +85,8 @@ private: void generateHttpCache(); void generateUserAgent(); void generateJobFactory(); + void cancelAllUrlRequests(); + net::HttpNetworkSession::Params generateNetworkSessionParams(); bool m_ignoreCertificateErrors; QAtomicInt m_updateCookieStore; |