summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@digia.com>2014-11-24 18:03:17 +0100
committerAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2014-12-12 12:29:12 +0100
commit6ec3268a30a63d5c15258ea6f4f792e21930b093 (patch)
treeb2a122f94eed67546a7ee1d0f118a7e72ec18c8f /src/core
parentb93a478d60e90073870aad22febd519adc4a4a3b (diff)
Introduce QWebEngineProfile API
Introduces initial widgets API for the Chromium BrowserContext. Adds API for controlling cookie jar policy, user-agent string and cache and persistent data paths. Similar QML API will follow in another patch. [ChangeLog][QtWebEngineWidgets][QWebEngineProfile] New API for profiles applying to groups of QWebEnginePages. Change-Id: I3c4ef4053fde7564af29178c91a0aca8a2b61a5f Reviewed-by: Jocelyn Turcotte <jocelyn.turcotte@digia.com>
Diffstat (limited to 'src/core')
-rw-r--r--src/core/browser_context_adapter.cpp161
-rw-r--r--src/core/browser_context_adapter.h51
-rw-r--r--src/core/browser_context_qt.cpp7
-rw-r--r--src/core/browser_context_qt.h4
-rw-r--r--src/core/url_request_context_getter_qt.cpp304
-rw-r--r--src/core/url_request_context_getter_qt.h24
-rw-r--r--src/core/web_contents_adapter.cpp7
-rw-r--r--src/core/web_contents_adapter_p.h4
-rw-r--r--src/core/web_engine_context.cpp8
-rw-r--r--src/core/web_engine_context.h6
10 files changed, 440 insertions, 136 deletions
diff --git a/src/core/browser_context_adapter.cpp b/src/core/browser_context_adapter.cpp
index ccb6a385d..133dd688a 100644
--- a/src/core/browser_context_adapter.cpp
+++ b/src/core/browser_context_adapter.cpp
@@ -37,8 +37,12 @@
#include "browser_context_adapter.h"
#include "browser_context_qt.h"
+#include "content_client_qt.h"
#include "web_engine_context.h"
#include "web_engine_visited_links_manager.h"
+#include "url_request_context_getter_qt.h"
+
+#include "net/proxy/proxy_service.h"
#include <QCoreApplication>
#include <QDir>
@@ -57,11 +61,22 @@ inline QString buildLocationFromStandardPath(const QString &standardPath, const
}
}
-BrowserContextAdapter::BrowserContextAdapter(const QString &name, bool offTheRecord)
- : m_name(name)
- , m_offTheRecord(offTheRecord)
+BrowserContextAdapter::BrowserContextAdapter(bool offTheRecord)
+ : m_offTheRecord(offTheRecord)
+ , m_browserContext(new BrowserContextQt(this))
+ , m_httpCacheType(DiskHttpCache)
+ , m_persistentCookiesPolicy(AllowPersistentCookies)
+ , m_httpCacheMaxSize(0)
+{
+}
+
+BrowserContextAdapter::BrowserContextAdapter(const QString &storageName)
+ : m_name(storageName)
+ , m_offTheRecord(false)
, m_browserContext(new BrowserContextQt(this))
- , m_visitedLinksManager(new WebEngineVisitedLinksManager(this))
+ , m_httpCacheType(DiskHttpCache)
+ , m_persistentCookiesPolicy(AllowPersistentCookies)
+ , m_httpCacheMaxSize(0)
{
}
@@ -69,6 +84,24 @@ BrowserContextAdapter::~BrowserContextAdapter()
{
}
+void BrowserContextAdapter::setStorageName(const QString &storageName)
+{
+ if (storageName == m_name)
+ return;
+ m_name = storageName;
+ if (m_browserContext->url_request_getter_)
+ m_browserContext->url_request_getter_->updateStorageSettings();
+}
+
+void BrowserContextAdapter::setOffTheRecord(bool offTheRecord)
+{
+ if (offTheRecord == m_offTheRecord)
+ return;
+ m_offTheRecord = offTheRecord;
+ if (m_browserContext->url_request_getter_)
+ m_browserContext->url_request_getter_->updateStorageSettings();
+}
+
BrowserContextQt *BrowserContextAdapter::browserContext()
{
return m_browserContext.data();
@@ -76,6 +109,8 @@ BrowserContextQt *BrowserContextAdapter::browserContext()
WebEngineVisitedLinksManager *BrowserContextAdapter::visitedLinksManager()
{
+ if (!m_visitedLinksManager)
+ m_visitedLinksManager.reset(new WebEngineVisitedLinksManager(this));
return m_visitedLinksManager.data();
}
@@ -91,10 +126,124 @@ BrowserContextAdapter* BrowserContextAdapter::offTheRecordContext()
QString BrowserContextAdapter::dataPath() const
{
- return buildLocationFromStandardPath(QStandardPaths::writableLocation(QStandardPaths::DataLocation), m_name);
+ if (m_offTheRecord)
+ return QString();
+ if (!m_dataPath.isEmpty())
+ return m_dataPath;
+ if (!m_name.isNull())
+ return buildLocationFromStandardPath(QStandardPaths::writableLocation(QStandardPaths::DataLocation), m_name);
+ return QString();
+}
+
+void BrowserContextAdapter::setDataPath(const QString &path)
+{
+ if (m_dataPath == path)
+ return;
+ m_dataPath = path;
+ if (m_browserContext->url_request_getter_)
+ m_browserContext->url_request_getter_->updateStorageSettings();
}
QString BrowserContextAdapter::cachePath() const
{
- return buildLocationFromStandardPath(QStandardPaths::writableLocation(QStandardPaths::CacheLocation), m_name);
+ if (m_offTheRecord)
+ return QString();
+ if (!m_cachePath.isEmpty())
+ return m_cachePath;
+ if (!m_name.isNull())
+ return buildLocationFromStandardPath(QStandardPaths::writableLocation(QStandardPaths::CacheLocation), m_name);
+ return QString();
+}
+
+void BrowserContextAdapter::setCachePath(const QString &path)
+{
+ if (m_cachePath == path)
+ return;
+ m_cachePath = path;
+ if (m_browserContext->url_request_getter_)
+ m_browserContext->url_request_getter_->updateHttpCache();
+}
+
+QString BrowserContextAdapter::cookiesPath() const
+{
+ if (m_offTheRecord)
+ return QString();
+ QString basePath = dataPath();
+ if (!basePath.isEmpty())
+ return basePath % QDir::separator() % QLatin1String("Coookies");
+ return QString();
+}
+
+QString BrowserContextAdapter::httpCachePath() const
+{
+ if (m_offTheRecord)
+ return QString();
+ QString basePath = cachePath();
+ if (!basePath.isEmpty())
+ return basePath % QDir::separator() % QLatin1String("Cache");
+ return QString();
+}
+
+QString BrowserContextAdapter::httpUserAgent() const
+{
+ if (m_httpUserAgent.isNull())
+ return QString::fromStdString(ContentClientQt::getUserAgent());
+ return m_httpUserAgent;
+}
+
+void BrowserContextAdapter::setHttpUserAgent(const QString &userAgent)
+{
+ if (m_httpUserAgent == userAgent)
+ return;
+ m_httpUserAgent = userAgent;
+ if (m_browserContext->url_request_getter_)
+ m_browserContext->url_request_getter_->updateUserAgent();
+}
+
+BrowserContextAdapter::HttpCacheType BrowserContextAdapter::httpCacheType() const
+{
+ if (isOffTheRecord() || httpCachePath().isEmpty())
+ return MemoryHttpCache;
+ return m_httpCacheType;
+}
+
+void BrowserContextAdapter::setHttpCacheType(BrowserContextAdapter::HttpCacheType newhttpCacheType)
+{
+ BrowserContextAdapter::HttpCacheType oldCacheType = httpCacheType();
+ m_httpCacheType = newhttpCacheType;
+ if (oldCacheType == httpCacheType())
+ return;
+ if (m_browserContext->url_request_getter_)
+ m_browserContext->url_request_getter_->updateHttpCache();
+}
+
+BrowserContextAdapter::PersistentCookiesPolicy BrowserContextAdapter::persistentCookiesPolicy() const
+{
+ if (isOffTheRecord() || cookiesPath().isEmpty())
+ return NoPersistentCookies;
+ return m_persistentCookiesPolicy;
+}
+
+void BrowserContextAdapter::setPersistentCookiesPolicy(BrowserContextAdapter::PersistentCookiesPolicy newPersistentCookiesPolicy)
+{
+ BrowserContextAdapter::PersistentCookiesPolicy oldPolicy = persistentCookiesPolicy();
+ m_persistentCookiesPolicy = newPersistentCookiesPolicy;
+ if (oldPolicy == persistentCookiesPolicy())
+ return;
+ if (m_browserContext->url_request_getter_)
+ m_browserContext->url_request_getter_->updateCookieStore();
+}
+
+int BrowserContextAdapter::httpCacheMaxSize() const
+{
+ return m_httpCacheMaxSize;
+}
+
+void BrowserContextAdapter::setHttpCacheMaxSize(int maxSize)
+{
+ if (m_httpCacheMaxSize == maxSize)
+ return;
+ m_httpCacheMaxSize = maxSize;
+ if (m_browserContext->url_request_getter_)
+ m_browserContext->url_request_getter_->updateHttpCache();
}
diff --git a/src/core/browser_context_adapter.h b/src/core/browser_context_adapter.h
index e4e046c8e..dabd8a11e 100644
--- a/src/core/browser_context_adapter.h
+++ b/src/core/browser_context_adapter.h
@@ -46,10 +46,11 @@
class BrowserContextQt;
class WebEngineVisitedLinksManager;
-// Make a QSharedData if we need to open arbitrary BrowserContextAdapter beyond the defaults.
-class QWEBENGINE_EXPORT BrowserContextAdapter // : public QSharedData
+class QWEBENGINE_EXPORT BrowserContextAdapter : public QSharedData
{
public:
+ explicit BrowserContextAdapter(bool offTheRecord = false);
+ explicit BrowserContextAdapter(const QString &storagePrefix);
virtual ~BrowserContextAdapter();
static BrowserContextAdapter* defaultContext();
@@ -58,19 +59,57 @@ public:
WebEngineVisitedLinksManager *visitedLinksManager();
BrowserContextQt *browserContext();
+
+ QString storageName() const { return m_name; }
+ void setStorageName(const QString &storageName);
+
bool isOffTheRecord() const { return m_offTheRecord; }
+ void setOffTheRecord(bool offTheRecord);
+
QString dataPath() const;
+ void setDataPath(const QString &path);
+
QString cachePath() const;
+ void setCachePath(const QString &path);
+
+ QString httpCachePath() const;
+ QString cookiesPath() const;
+
+ QString httpUserAgent() const;
+ void setHttpUserAgent(const QString &userAgent);
+
+ // KEEP IN SYNC with API or add mapping layer
+ enum HttpCacheType {
+ MemoryHttpCache = 0,
+ DiskHttpCache
+ };
+
+ enum PersistentCookiesPolicy {
+ NoPersistentCookies = 0,
+ AllowPersistentCookies,
+ ForcePersistentCookies
+ };
+
+ HttpCacheType httpCacheType() const;
+ void setHttpCacheType(BrowserContextAdapter::HttpCacheType);
+
+ PersistentCookiesPolicy persistentCookiesPolicy() const;
+ void setPersistentCookiesPolicy(BrowserContextAdapter::PersistentCookiesPolicy);
-protected:
- BrowserContextAdapter(const QString &name, bool offTheRecord = false);
+ int httpCacheMaxSize() const;
+ void setHttpCacheMaxSize(int maxSize);
private:
- const QString m_name;
+ QString m_name;
bool m_offTheRecord;
QScopedPointer<BrowserContextQt> m_browserContext;
QScopedPointer<WebEngineVisitedLinksManager> m_visitedLinksManager;
- friend class WebEngineContext;
+ QString m_dataPath;
+ QString m_cachePath;
+ QString m_httpUserAgent;
+ HttpCacheType m_httpCacheType;
+ PersistentCookiesPolicy m_persistentCookiesPolicy;
+ int m_httpCacheMaxSize;
Q_DISABLE_COPY(BrowserContextAdapter)
};
diff --git a/src/core/browser_context_qt.cpp b/src/core/browser_context_qt.cpp
index 2484ba879..e2cc8851b 100644
--- a/src/core/browser_context_qt.cpp
+++ b/src/core/browser_context_qt.cpp
@@ -51,7 +51,6 @@
BrowserContextQt::BrowserContextQt(BrowserContextAdapter *adapter)
: m_adapter(adapter)
{
- resourceContext.reset(new ResourceContextQt(this));
}
BrowserContextQt::~BrowserContextQt()
@@ -102,6 +101,8 @@ net::URLRequestContextGetter *BrowserContextQt::GetMediaRequestContextForStorage
content::ResourceContext *BrowserContextQt::GetResourceContext()
{
+ if (!resourceContext)
+ resourceContext.reset(new ResourceContextQt(this));
return resourceContext.get();
}
@@ -128,7 +129,7 @@ content::PushMessagingService *BrowserContextQt::GetPushMessagingService()
net::URLRequestContextGetter *BrowserContextQt::CreateRequestContext(content::ProtocolHandlerMap *protocol_handlers)
{
- url_request_getter_ = new URLRequestContextGetterQt(this, protocol_handlers);
- static_cast<ResourceContextQt*>(resourceContext.get())->set_url_request_context_getter(url_request_getter_.get());
+ url_request_getter_ = new URLRequestContextGetterQt(m_adapter, protocol_handlers);
+ static_cast<ResourceContextQt*>(GetResourceContext())->set_url_request_context_getter(url_request_getter_.get());
return url_request_getter_.get();
}
diff --git a/src/core/browser_context_qt.h b/src/core/browser_context_qt.h
index 634db6f3f..c11a234ab 100644
--- a/src/core/browser_context_qt.h
+++ b/src/core/browser_context_qt.h
@@ -44,6 +44,7 @@
#include "download_manager_delegate_qt.h"
class BrowserContextAdapter;
+class URLRequestContextGetterQt;
class BrowserContextQt : public content::BrowserContext
{
@@ -70,9 +71,10 @@ public:
private:
scoped_ptr<content::ResourceContext> resourceContext;
- scoped_refptr<net::URLRequestContextGetter> url_request_getter_;
+ scoped_refptr<URLRequestContextGetterQt> url_request_getter_;
scoped_ptr<DownloadManagerDelegateQt> downloadManagerDelegate;
BrowserContextAdapter *m_adapter;
+ friend class BrowserContextAdapter;
DISALLOW_COPY_AND_ASSIGN(BrowserContextQt);
};
diff --git a/src/core/url_request_context_getter_qt.cpp b/src/core/url_request_context_getter_qt.cpp
index 282e5e94f..0d72845b5 100644
--- a/src/core/url_request_context_getter_qt.cpp
+++ b/src/core/url_request_context_getter_qt.cpp
@@ -61,141 +61,229 @@
#include "net/url_request/ftp_protocol_handler.h"
#include "net/ftp/ftp_network_layer.h"
-#include "browser_context_qt.h"
+#include "browser_context_adapter.h"
#include "content_client_qt.h"
#include "network_delegate_qt.h"
#include "qrc_protocol_handler_qt.h"
+#include "type_conversion.h"
static const char kQrcSchemeQt[] = "qrc";
using content::BrowserThread;
-URLRequestContextGetterQt::URLRequestContextGetterQt(BrowserContextQt *browserContext, content::ProtocolHandlerMap *protocolHandlers)
+URLRequestContextGetterQt::URLRequestContextGetterQt(BrowserContextAdapter *browserContext, content::ProtocolHandlerMap *protocolHandlers)
: m_ignoreCertificateErrors(false)
+ , m_updateStorageSettings(false)
+ , m_updateCookieStore(false)
+ , m_updateHttpCache(false)
, m_browserContext(browserContext)
{
std::swap(m_protocolHandlers, *protocolHandlers);
- // We must create the proxy config service on the UI loop on Linux because it
- // must synchronously run on the glib message loop. This will be passed to
- // the URLRequestContextStorage on the IO thread in GetURLRequestContext().
-//#ifdef Q_OS_LINUX
- m_proxyConfigService.reset(net::ProxyService::CreateSystemProxyConfigService(BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::IO)->message_loop_proxy()
- , BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::FILE)));
-//#endif
+ updateStorageSettings();
}
net::URLRequestContext *URLRequestContextGetterQt::GetURLRequestContext()
{
if (!m_urlRequestContext) {
-
m_urlRequestContext.reset(new net::URLRequestContext());
- m_networkDelegate.reset(new NetworkDelegateQt);
+ m_networkDelegate.reset(new NetworkDelegateQt);
m_urlRequestContext->set_network_delegate(m_networkDelegate.get());
- scoped_refptr<net::CookieStore> cookieStore;
- if (m_browserContext->IsOffTheRecord()) {
- cookieStore = content::CreateCookieStore(content::CookieStoreConfig(base::FilePath(), content::CookieStoreConfig::EPHEMERAL_SESSION_COOKIES, NULL, NULL));
- } else {
- base::FilePath cookiesPath = m_browserContext->GetPath().Append(FILE_PATH_LITERAL("Cookies"));
- cookieStore = content::CreateCookieStore(content::CookieStoreConfig(cookiesPath, content::CookieStoreConfig::PERSISTANT_SESSION_COOKIES, NULL, NULL));
- }
-
- m_storage.reset(new net::URLRequestContextStorage(m_urlRequestContext.get()));
- m_storage->set_cookie_store(cookieStore.get());
- m_storage->set_server_bound_cert_service(new net::ServerBoundCertService(
- new net::DefaultServerBoundCertStore(NULL),
- base::WorkerPool::GetTaskRunner(true)));
- m_storage->set_http_user_agent_settings(
- new net::StaticHttpUserAgentSettings("en-us,en", ContentClientQt::getUserAgent()));
-
- scoped_ptr<net::HostResolver> host_resolver(
- net::HostResolver::CreateDefaultResolver(NULL));
-
- m_storage->set_cert_verifier(net::CertVerifier::CreateDefault());
-
- m_storage->set_proxy_service(net::ProxyService::CreateUsingSystemProxyResolver(m_proxyConfigService.release(), 0, NULL));
-
- m_storage->set_ssl_config_service(new net::SSLConfigServiceDefaults);
- m_storage->set_transport_security_state(new net::TransportSecurityState());
-
- m_storage->set_http_auth_handler_factory(
- net::HttpAuthHandlerFactory::CreateDefault(host_resolver.get()));
- m_storage->set_http_server_properties(scoped_ptr<net::HttpServerProperties>(new net::HttpServerPropertiesImpl));
-
- net::HttpCache::DefaultBackend* main_backend;
- if (m_browserContext->IsOffTheRecord()) {
- main_backend =
- new net::HttpCache::DefaultBackend(
- net::MEMORY_CACHE,
- net::CACHE_BACKEND_DEFAULT,
- base::FilePath(),
- 0,
- BrowserThread::GetMessageLoopProxyForThread(
- BrowserThread::CACHE));
- } else {
- base::FilePath cache_path = m_browserContext->GetCachePath().Append(FILE_PATH_LITERAL("Cache"));
- main_backend =
- new net::HttpCache::DefaultBackend(
- net::DISK_CACHE,
- net::CACHE_BACKEND_DEFAULT,
- cache_path,
- 0,
- BrowserThread::GetMessageLoopProxyForThread(
- BrowserThread::CACHE));
- }
-
- 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.server_bound_cert_service =
- m_urlRequestContext->server_bound_cert_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;
-
- // Give |m_storage| ownership at the end in case it's |mapped_host_resolver|.
- m_storage->set_host_resolver(host_resolver.Pass());
- network_session_params.host_resolver =
- m_urlRequestContext->host_resolver();
-
- net::HttpCache* main_cache = new net::HttpCache(
- network_session_params, main_backend);
- m_storage->set_http_transaction_factory(main_cache);
-
-
- m_jobFactory.reset(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());
- m_jobFactory->SetProtocolHandler(it->first, it->second.release());
- m_protocolHandlers.clear();
-
- m_jobFactory->SetProtocolHandler(url::kDataScheme, new net::DataProtocolHandler());
- m_jobFactory->SetProtocolHandler(url::kFileScheme, new net::FileProtocolHandler(
- content::BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)));
- m_jobFactory->SetProtocolHandler(kQrcSchemeQt, new QrcProtocolHandlerQt());
- m_jobFactory->SetProtocolHandler(url::kFtpScheme, new net::FtpProtocolHandler(
- new net::FtpNetworkLayer(m_urlRequestContext->host_resolver())));
- m_urlRequestContext->set_job_factory(m_jobFactory.get());
+ generateStorage();
+ generateJobFactory();
}
return m_urlRequestContext.get();
}
+void URLRequestContextGetterQt::updateStorageSettings()
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ if (!m_proxyConfigService) {
+ // We must create the proxy config service on the UI loop on Linux because it
+ // must synchronously run on the glib message loop. This will be passed to
+ // the URLRequestContextStorage on the IO thread in GetURLRequestContext().
+ m_proxyConfigService.reset(net::ProxyService::CreateSystemProxyConfigService(
+ BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::IO)->message_loop_proxy(),
+ BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::FILE))
+ );
+ }
+ if (m_storage && !m_updateStorageSettings) {
+ m_updateStorageSettings = true;
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestContextGetterQt::generateStorage, this));
+ }
+}
+
+void URLRequestContextGetterQt::generateStorage()
+{
+ Q_ASSERT(m_urlRequestContext);
+ Q_ASSERT(m_proxyConfigService);
+ m_updateStorageSettings = false;
+
+ m_storage.reset(new net::URLRequestContextStorage(m_urlRequestContext.get()));
+
+ generateCookieStore();
+ generateUserAgent();
+
+ m_storage->set_server_bound_cert_service(new net::ServerBoundCertService(
+ new net::DefaultServerBoundCertStore(NULL),
+ base::WorkerPool::GetTaskRunner(true)));
+
+ m_storage->set_cert_verifier(net::CertVerifier::CreateDefault());
+ m_storage->set_proxy_service(net::ProxyService::CreateUsingSystemProxyResolver(
+ m_proxyConfigService.release(), 0, NULL));
+ m_storage->set_ssl_config_service(new net::SSLConfigServiceDefaults);
+ m_storage->set_transport_security_state(new net::TransportSecurityState());
+
+ scoped_ptr<net::HostResolver> host_resolver(net::HostResolver::CreateDefaultResolver(NULL));
+ m_storage->set_http_auth_handler_factory(net::HttpAuthHandlerFactory::CreateDefault(host_resolver.get()));
+ m_storage->set_http_server_properties(scoped_ptr<net::HttpServerProperties>(new net::HttpServerPropertiesImpl));
+
+ // Give |m_storage| ownership at the end in case it's |mapped_host_resolver|.
+ m_storage->set_host_resolver(host_resolver.Pass());
+
+ generateHttpCache();
+}
+
+void URLRequestContextGetterQt::updateCookieStore()
+{
+ if (m_urlRequestContext && !m_updateCookieStore && !m_updateStorageSettings) {
+ m_updateCookieStore = true;
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestContextGetterQt::generateCookieStore, this));
+ }
+}
+
+void URLRequestContextGetterQt::generateCookieStore()
+{
+ Q_ASSERT(m_urlRequestContext);
+ Q_ASSERT(m_storage);
+ m_updateCookieStore = false;
+
+ // Unset it first to get a chance to destroy and flush the old cookie store before before opening a new on possibly the same file.
+ m_storage->set_cookie_store(0);
+
+ net::CookieStore* cookieStore = 0;
+ switch (m_browserContext->persistentCookiesPolicy()) {
+ case BrowserContextAdapter::NoPersistentCookies:
+ cookieStore =
+ content::CreateCookieStore(content::CookieStoreConfig(
+ base::FilePath(),
+ content::CookieStoreConfig::EPHEMERAL_SESSION_COOKIES,
+ NULL, NULL)
+ );
+ break;
+ case BrowserContextAdapter::AllowPersistentCookies:
+ cookieStore =
+ content::CreateCookieStore(content::CookieStoreConfig(
+ base::FilePath(toFilePathString(m_browserContext->cookiesPath())),
+ content::CookieStoreConfig::PERSISTANT_SESSION_COOKIES,
+ NULL, NULL)
+ );
+ break;
+ case BrowserContextAdapter::ForcePersistentCookies:
+ cookieStore =
+ content::CreateCookieStore(content::CookieStoreConfig(
+ base::FilePath(toFilePathString(m_browserContext->cookiesPath())),
+ content::CookieStoreConfig::RESTORED_SESSION_COOKIES,
+ NULL, NULL)
+ );
+ break;
+ }
+ m_storage->set_cookie_store(cookieStore);
+}
+
+void URLRequestContextGetterQt::updateUserAgent()
+{
+ if (m_urlRequestContext && !m_updateStorageSettings)
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestContextGetterQt::generateUserAgent, this));
+}
+
+void URLRequestContextGetterQt::generateUserAgent()
+{
+ Q_ASSERT(m_urlRequestContext);
+ Q_ASSERT(m_storage);
+
+ m_storage->set_http_user_agent_settings(
+ new net::StaticHttpUserAgentSettings("en-us,en", m_browserContext->httpUserAgent().toStdString()));
+}
+
+void URLRequestContextGetterQt::updateHttpCache()
+{
+ if (m_urlRequestContext && !m_updateHttpCache && !m_updateStorageSettings) {
+ m_updateHttpCache = true;
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestContextGetterQt::generateHttpCache, this));
+ }
+}
+
+void URLRequestContextGetterQt::generateHttpCache()
+{
+ Q_ASSERT(m_urlRequestContext);
+ Q_ASSERT(m_storage);
+ m_updateHttpCache = false;
+
+ net::HttpCache::DefaultBackend* main_backend = 0;
+ switch (m_browserContext->httpCacheType()) {
+ case BrowserContextAdapter::MemoryHttpCache:
+ main_backend =
+ new net::HttpCache::DefaultBackend(
+ net::MEMORY_CACHE,
+ net::CACHE_BACKEND_DEFAULT,
+ base::FilePath(),
+ m_browserContext->httpCacheMaxSize(),
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE)
+ );
+ break;
+ case BrowserContextAdapter::DiskHttpCache:
+ main_backend =
+ new net::HttpCache::DefaultBackend(
+ net::DISK_CACHE,
+ net::CACHE_BACKEND_DEFAULT,
+ base::FilePath(toFilePathString(m_browserContext->httpCachePath())),
+ m_browserContext->httpCacheMaxSize(),
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE)
+ );
+ 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.server_bound_cert_service = m_urlRequestContext->server_bound_cert_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();
+
+ m_storage->set_http_transaction_factory(new net::HttpCache(network_session_params, main_backend));
+}
+
+void URLRequestContextGetterQt::generateJobFactory()
+{
+ Q_ASSERT(m_urlRequestContext);
+ Q_ASSERT(!m_jobFactory);
+ m_jobFactory.reset(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());
+ m_jobFactory->SetProtocolHandler(it->first, it->second.release());
+ m_protocolHandlers.clear();
+
+ m_jobFactory->SetProtocolHandler(url::kDataScheme, new net::DataProtocolHandler());
+ m_jobFactory->SetProtocolHandler(url::kFileScheme, new net::FileProtocolHandler(
+ content::BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
+ base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)));
+ m_jobFactory->SetProtocolHandler(kQrcSchemeQt, new QrcProtocolHandlerQt());
+ m_jobFactory->SetProtocolHandler(url::kFtpScheme,
+ new net::FtpProtocolHandler(new net::FtpNetworkLayer(m_urlRequestContext->host_resolver())));
+
+ m_urlRequestContext->set_job_factory(m_jobFactory.get());
+}
scoped_refptr<base::SingleThreadTaskRunner> URLRequestContextGetterQt::GetNetworkTaskRunner() const
{
diff --git a/src/core/url_request_context_getter_qt.h b/src/core/url_request_context_getter_qt.h
index 2c42322bd..5f6048403 100644
--- a/src/core/url_request_context_getter_qt.h
+++ b/src/core/url_request_context_getter_qt.h
@@ -40,6 +40,7 @@
#include "net/url_request/url_request_context_getter.h"
#include "base/files/file_path.h"
+#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/single_thread_task_runner.h"
#include "content/public/browser/content_browser_client.h"
@@ -50,26 +51,41 @@
#include "qglobal.h"
namespace net {
-class HostResolver;
class MappedHostResolver;
class NetworkDelegate;
class ProxyConfigService;
}
-class BrowserContextQt;
+class BrowserContextAdapter;
class URLRequestContextGetterQt : public net::URLRequestContextGetter {
public:
- explicit URLRequestContextGetterQt(BrowserContextQt *browserContext, content::ProtocolHandlerMap *protocolHandlers);
+ explicit URLRequestContextGetterQt(BrowserContextAdapter *browserContext, content::ProtocolHandlerMap *protocolHandlers);
virtual net::URLRequestContext *GetURLRequestContext() Q_DECL_OVERRIDE;
virtual scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner() const Q_DECL_OVERRIDE;
+ // Called on the UI thread:
+ void updateStorageSettings();
+ void updateUserAgent();
+ void updateCookieStore();
+ void updateHttpCache();
+
private:
virtual ~URLRequestContextGetterQt() {}
+ // Called on the IO thread:
+ void generateStorage();
+ void generateCookieStore();
+ void generateHttpCache();
+ void generateUserAgent();
+ void generateJobFactory();
+
bool m_ignoreCertificateErrors;
- BrowserContextQt *m_browserContext;
+ volatile bool m_updateStorageSettings;
+ volatile bool m_updateCookieStore;
+ volatile bool m_updateHttpCache;
+ BrowserContextAdapter *m_browserContext;
content::ProtocolHandlerMap m_protocolHandlers;
scoped_ptr<net::ProxyConfigService> m_proxyConfigService;
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index 678b558c1..0b1aba1cf 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -347,10 +347,13 @@ void WebContentsAdapter::initialize(WebContentsAdapterClient *adapterClient)
{
Q_D(WebContentsAdapter);
d->adapterClient = adapterClient;
+ // We keep a reference to browserContextAdapter to keep it alive as long as we use it.
+ // This is needed in case the QML WebEngineProfile is garbage collected before the WebEnginePage.
+ d->browserContextAdapter = adapterClient->browserContextAdapter();
// Create our own if a WebContents wasn't provided at construction.
if (!d->webContents)
- d->webContents.reset(createBlankWebContents(adapterClient, adapterClient->browserContextAdapter()->browserContext()));
+ d->webContents.reset(createBlankWebContents(adapterClient, d->browserContextAdapter->browserContext()));
// This might replace any adapter that has been initialized with this WebEngineSettings.
adapterClient->webEngineSettings()->setWebContentsAdapter(this);
@@ -631,7 +634,7 @@ void WebContentsAdapter::enableInspector(bool enable)
BrowserContextQt* WebContentsAdapter::browserContext()
{
Q_D(WebContentsAdapter);
- return static_cast<BrowserContextQt*>(d->webContents->GetBrowserContext());
+ return d->browserContextAdapter->browserContext();
}
QAccessibleInterface *WebContentsAdapter::browserAccessible()
diff --git a/src/core/web_contents_adapter_p.h b/src/core/web_contents_adapter_p.h
index 28df0113a..f47c05de0 100644
--- a/src/core/web_contents_adapter_p.h
+++ b/src/core/web_contents_adapter_p.h
@@ -42,6 +42,9 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
+#include <QExplicitlySharedDataPointer>
+
+class BrowserContextAdapter;
class QtRenderViewObserverHost;
class WebContentsAdapterClient;
class WebContentsDelegateQt;
@@ -52,6 +55,7 @@ public:
WebContentsAdapterPrivate();
~WebContentsAdapterPrivate();
scoped_refptr<WebEngineContext> engineContext;
+ QExplicitlySharedDataPointer<BrowserContextAdapter> browserContextAdapter;
scoped_ptr<content::WebContents> webContents;
scoped_ptr<WebContentsDelegateQt> webContentsDelegate;
scoped_ptr<QtRenderViewObserverHost> renderViewObserverHost;
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index b17ee124c..6f335d2fc 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -142,15 +142,15 @@ scoped_refptr<WebEngineContext> WebEngineContext::current()
BrowserContextAdapter* WebEngineContext::defaultBrowserContext()
{
if (!m_defaultBrowserContext)
- m_defaultBrowserContext.reset(new BrowserContextAdapter(QStringLiteral("Default"), false));
- return m_defaultBrowserContext.get();
+ m_defaultBrowserContext = new BrowserContextAdapter(QStringLiteral("Default"));
+ return m_defaultBrowserContext.data();
}
BrowserContextAdapter* WebEngineContext::offTheRecordBrowserContext()
{
if (!m_offTheRecordBrowserContext)
- m_offTheRecordBrowserContext.reset(new BrowserContextAdapter(QStringLiteral("OTR"), true));
- return m_offTheRecordBrowserContext.get();
+ m_offTheRecordBrowserContext = new BrowserContextAdapter(true);
+ return m_offTheRecordBrowserContext.data();
}
#ifndef CHROMIUM_VERSION
diff --git a/src/core/web_engine_context.h b/src/core/web_engine_context.h
index 0b3ad8678..a44a48d3a 100644
--- a/src/core/web_engine_context.h
+++ b/src/core/web_engine_context.h
@@ -40,6 +40,8 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
+#include <QExplicitlySharedDataPointer>
+
namespace base {
class RunLoop;
}
@@ -72,8 +74,8 @@ private:
#if defined(OS_ANDROID)
scoped_ptr<SurfaceFactoryQt> m_surfaceFactory;
#endif
- scoped_ptr<BrowserContextAdapter> m_defaultBrowserContext;
- scoped_ptr<BrowserContextAdapter> m_offTheRecordBrowserContext;
+ QExplicitlySharedDataPointer<BrowserContextAdapter> m_defaultBrowserContext;
+ QExplicitlySharedDataPointer<BrowserContextAdapter> m_offTheRecordBrowserContext;
};
#endif // WEB_ENGINE_CONTEXT_H