summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Bruning <michael.bruning@theqtcompany.com>2015-12-03 11:16:32 +0100
committerMichael BrĂ¼ning <michael.bruning@theqtcompany.com>2015-12-04 16:32:39 +0000
commit32f83d9c2c884dfa516095c07f8590b2c4c99321 (patch)
tree0b2e3ab36aa5364717e223e9951d19788445616d
parent1847e158e09e24af704b02c8fb30adbf04d3befa (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>
-rw-r--r--src/core/url_request_context_getter_qt.cpp102
-rw-r--r--src/core/url_request_context_getter_qt.h3
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;