diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/api/qwebengineurlrequestjob.cpp | 1 | ||||
-rw-r--r-- | src/core/api/qwebengineurlrequestjob.h | 4 | ||||
-rw-r--r-- | src/core/core_chromium.pri | 2 | ||||
-rw-r--r-- | src/core/url_request_custom_job.cpp | 283 | ||||
-rw-r--r-- | src/core/url_request_custom_job.h | 54 | ||||
-rw-r--r-- | src/core/url_request_custom_job_delegate.cpp | 22 | ||||
-rw-r--r-- | src/core/url_request_custom_job_delegate.h | 8 | ||||
-rw-r--r-- | src/core/url_request_custom_job_proxy.cpp | 266 | ||||
-rw-r--r-- | src/core/url_request_custom_job_proxy.h | 97 |
9 files changed, 423 insertions, 314 deletions
diff --git a/src/core/api/qwebengineurlrequestjob.cpp b/src/core/api/qwebengineurlrequestjob.cpp index 1db23f6ab..742bdf527 100644 --- a/src/core/api/qwebengineurlrequestjob.cpp +++ b/src/core/api/qwebengineurlrequestjob.cpp @@ -39,6 +39,7 @@ #include "qwebengineurlrequestjob.h" +#include "url_request_custom_job_proxy.h" #include "url_request_custom_job_delegate.h" using QtWebEngineCore::URLRequestCustomJobDelegate; diff --git a/src/core/api/qwebengineurlrequestjob.h b/src/core/api/qwebengineurlrequestjob.h index afa542d7e..4f23ab401 100644 --- a/src/core/api/qwebengineurlrequestjob.h +++ b/src/core/api/qwebengineurlrequestjob.h @@ -48,7 +48,7 @@ namespace QtWebEngineCore { class URLRequestCustomJobDelegate; -class URLRequestCustomJobShared; +class URLRequestCustomJobProxy; } // namespace QT_BEGIN_NAMESPACE @@ -79,7 +79,7 @@ public: private: QWebEngineUrlRequestJob(QtWebEngineCore::URLRequestCustomJobDelegate *); - friend class QtWebEngineCore::URLRequestCustomJobShared; + friend class QtWebEngineCore::URLRequestCustomJobProxy; QtWebEngineCore::URLRequestCustomJobDelegate* d_ptr; }; diff --git a/src/core/core_chromium.pri b/src/core/core_chromium.pri index f13095bfe..b76469833 100644 --- a/src/core/core_chromium.pri +++ b/src/core/core_chromium.pri @@ -96,6 +96,7 @@ SOURCES = \ url_request_context_getter_qt.cpp \ url_request_custom_job.cpp \ url_request_custom_job_delegate.cpp \ + url_request_custom_job_proxy.cpp \ url_request_qrc_job_qt.cpp \ user_script.cpp \ visited_links_manager_qt.cpp \ @@ -171,6 +172,7 @@ HEADERS = \ url_request_context_getter_qt.h \ url_request_custom_job.h \ url_request_custom_job_delegate.h \ + url_request_custom_job_proxy.h \ url_request_qrc_job_qt.h \ user_script.h \ visited_links_manager_qt.h \ diff --git a/src/core/url_request_custom_job.cpp b/src/core/url_request_custom_job.cpp index d093efd0a..724a879e0 100644 --- a/src/core/url_request_custom_job.cpp +++ b/src/core/url_request_custom_job.cpp @@ -38,57 +38,50 @@ ****************************************************************************/ #include "url_request_custom_job.h" -#include "url_request_custom_job_delegate.h" - -#include "api/qwebengineurlrequestjob.h" -#include "api/qwebengineurlschemehandler.h" -#include "browser_context_adapter.h" -#include "type_conversion.h" - +#include "url_request_custom_job_proxy.h" #include "content/public/browser/browser_thread.h" -#include "net/base/net_errors.h" #include "net/base/io_buffer.h" -#include <QFileInfo> -#include <QMimeDatabase> -#include <QMimeType> -#include <QUrl> +#include <QIODevice> using namespace net; namespace QtWebEngineCore { -URLRequestCustomJob::URLRequestCustomJob(URLRequest *request, NetworkDelegate *networkDelegate, - const std::string &scheme, QWeakPointer<const BrowserContextAdapter> adapter) +URLRequestCustomJob::URLRequestCustomJob(URLRequest *request, + NetworkDelegate *networkDelegate, + const std::string &scheme, + QWeakPointer<const BrowserContextAdapter> adapter) : URLRequestJob(request, networkDelegate) , m_scheme(scheme) , m_adapter(adapter) - , m_shared(new URLRequestCustomJobShared(this)) + , m_proxy(new URLRequestCustomJobProxy(this)) { } URLRequestCustomJob::~URLRequestCustomJob() { - if (m_shared) - m_shared->killJob(); + if (m_proxy) + m_proxy->killJob(); } -static void startAsync(URLRequestCustomJobShared *shared) +static void startAsync(URLRequestCustomJobProxy *proxy) { - shared->startAsync(); + proxy->startAsync(); } void URLRequestCustomJob::Start() { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, base::Bind(&startAsync, m_shared)); + content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, + base::Bind(&startAsync, m_proxy)); } void URLRequestCustomJob::Kill() { - if (m_shared) - m_shared->killJob(); - m_shared = 0; + if (m_proxy) + m_proxy->killJob(); + m_proxy = 0; URLRequestJob::Kill(); } @@ -96,11 +89,11 @@ void URLRequestCustomJob::Kill() bool URLRequestCustomJob::GetMimeType(std::string *mimeType) const { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - if (!m_shared) + if (!m_proxy) return false; - QMutexLocker lock(&m_shared->m_mutex); - if (m_shared->m_mimeType.size() > 0) { - *mimeType = m_shared->m_mimeType; + QMutexLocker lock(&m_proxy->m_mutex); + if (m_proxy->m_mimeType.size() > 0) { + *mimeType = m_proxy->m_mimeType; return true; } return false; @@ -109,11 +102,11 @@ bool URLRequestCustomJob::GetMimeType(std::string *mimeType) const bool URLRequestCustomJob::GetCharset(std::string* charset) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - if (!m_shared) + if (!m_proxy) return false; - QMutexLocker lock(&m_shared->m_mutex); - if (m_shared->m_charset.size() > 0) { - *charset = m_shared->m_charset; + QMutexLocker lock(&m_proxy->m_mutex); + if (m_proxy->m_charset.size() > 0) { + *charset = m_proxy->m_charset; return true; } return false; @@ -122,11 +115,11 @@ bool URLRequestCustomJob::GetCharset(std::string* charset) bool URLRequestCustomJob::IsRedirectResponse(GURL* location, int* http_status_code) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - if (!m_shared) + if (!m_proxy) return false; - QMutexLocker lock(&m_shared->m_mutex); - if (m_shared->m_redirect.is_valid()) { - *location = m_shared->m_redirect; + QMutexLocker lock(&m_proxy->m_mutex); + if (m_proxy->m_redirect.is_valid()) { + *location = m_proxy->m_redirect; *http_status_code = 303; return true; } @@ -136,224 +129,18 @@ bool URLRequestCustomJob::IsRedirectResponse(GURL* location, int* http_status_co int URLRequestCustomJob::ReadRawData(IOBuffer *buf, int bufSize) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - Q_ASSERT(m_shared); - QMutexLocker lock(&m_shared->m_mutex); - if (m_shared->m_error) - return m_shared->m_error; - qint64 rv = m_shared->m_device ? m_shared->m_device->read(buf->data(), bufSize) : -1; + Q_ASSERT(m_proxy); + QMutexLocker lock(&m_proxy->m_mutex); + if (m_proxy->m_error) + return m_proxy->m_error; + qint64 rv = m_proxy->m_device ? m_proxy->m_device->read(buf->data(), bufSize) : -1; if (rv >= 0) return static_cast<int>(rv); else { // QIODevice::read might have called fail on us. - if (m_shared->m_error) - return m_shared->m_error; + if (m_proxy->m_error) + return m_proxy->m_error; return ERR_FAILED; } } - - -URLRequestCustomJobShared::URLRequestCustomJobShared(URLRequestCustomJob *job) - : m_mutex(QMutex::Recursive) - , m_job(job) - , m_delegate(0) - , m_error(0) - , m_started(false) - , m_asyncInitialized(false) - , m_weakFactory(this) -{ -} - -URLRequestCustomJobShared::~URLRequestCustomJobShared() -{ - Q_ASSERT(!m_job); - Q_ASSERT(!m_delegate); -} - -void URLRequestCustomJobShared::killJob() -{ - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - QMutexLocker lock(&m_mutex); - m_job = 0; - bool doDelete = false; - if (m_delegate) { - m_delegate->deleteLater(); - } else { - // Do not delete yet if startAsync has not yet run. - doDelete = m_asyncInitialized; - } - if (m_device && m_device->isOpen()) - m_device->close(); - m_device = 0; - m_weakFactory.InvalidateWeakPtrs(); - lock.unlock(); - if (doDelete) - delete this; -} - -void URLRequestCustomJobShared::unsetJobDelegate() -{ - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - QMutexLocker lock(&m_mutex); - m_delegate = 0; - bool doDelete = false; - if (m_job) - abort(); - else - doDelete = true; - lock.unlock(); - if (doDelete) - delete this; -} - -void URLRequestCustomJobShared::setReplyMimeType(const std::string &mimeType) -{ - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - QMutexLocker lock(&m_mutex); - m_mimeType = mimeType; -} - -void URLRequestCustomJobShared::setReplyCharset(const std::string &charset) -{ - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - QMutexLocker lock(&m_mutex); - m_charset = charset; -} - -void URLRequestCustomJobShared::setReplyDevice(QIODevice *device) -{ - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - QMutexLocker lock(&m_mutex); - if (!m_job) - return; - m_device = device; - if (m_device && !m_device->isReadable()) - m_device->open(QIODevice::ReadOnly); - - qint64 size = m_device ? m_device->size() : -1; - if (size > 0) - m_job->set_expected_content_size(size); - if (m_device && m_device->isReadable()) - content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJobShared::notifyStarted, m_weakFactory.GetWeakPtr())); - else - fail(ERR_INVALID_URL); -} - -void URLRequestCustomJobShared::redirect(const GURL &url) -{ - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - - QMutexLocker lock(&m_mutex); - if (m_device || m_error) - return; - if (!m_job) - return; - m_redirect = url; - content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJobShared::notifyStarted, m_weakFactory.GetWeakPtr())); -} - -void URLRequestCustomJobShared::abort() -{ - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - QMutexLocker lock(&m_mutex); - if (m_device && m_device->isOpen()) - m_device->close(); - m_device = 0; - if (!m_job) - return; - content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJobShared::notifyCanceled, m_weakFactory.GetWeakPtr())); -} - -void URLRequestCustomJobShared::notifyCanceled() -{ - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - QMutexLocker lock(&m_mutex); - if (!m_job) - return; - if (m_started) - m_job->NotifyCanceled(); - else - m_job->NotifyStartError(URLRequestStatus(URLRequestStatus::CANCELED, ERR_ABORTED)); -} - -void URLRequestCustomJobShared::notifyStarted() -{ - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - QMutexLocker lock(&m_mutex); - if (!m_job) - return; - Q_ASSERT(!m_started); - m_started = true; - m_job->NotifyHeadersComplete(); -} - -void URLRequestCustomJobShared::fail(int error) -{ - QMutexLocker lock(&m_mutex); - m_error = error; - if (content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) - return; - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - if (!m_job) - return; - content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJobShared::notifyFailure, m_weakFactory.GetWeakPtr())); -} - -void URLRequestCustomJobShared::notifyFailure() -{ - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - QMutexLocker lock(&m_mutex); - if (!m_job) - return; - if (m_device) - m_device->close(); - if (!m_started) - m_job->NotifyStartError(URLRequestStatus::FromError(m_error)); - // else we fail on the next read, or the read that might already be in progress -} - -GURL URLRequestCustomJobShared::requestUrl() -{ - QMutexLocker lock(&m_mutex); - if (!m_job) - return GURL(); - return m_job->request()->url(); -} - -std::string URLRequestCustomJobShared::requestMethod() -{ - QMutexLocker lock(&m_mutex); - if (!m_job) - return std::string(); - return m_job->request()->method(); -} - -void URLRequestCustomJobShared::startAsync() -{ - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - Q_ASSERT(!m_started); - Q_ASSERT(!m_delegate); - QMutexLocker lock(&m_mutex); - if (!m_job) { - lock.unlock(); - delete this; - return; - } - - 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 93edb0b8c..171786c7b 100644 --- a/src/core/url_request_custom_job.h +++ b/src/core/url_request_custom_job.h @@ -40,19 +40,15 @@ #ifndef URL_REQUEST_CUSTOM_JOB_H_ #define URL_REQUEST_CUSTOM_JOB_H_ -#include "net/url_request/url_request.h" #include "net/url_request/url_request_job.h" - -#include <QtCore/QMutex> -#include <QtCore/QPointer> - -QT_FORWARD_DECLARE_CLASS(QIODevice) +#include "url/gurl.h" +#include <QtCore/QWeakPointer> namespace QtWebEngineCore { class BrowserContextAdapter; class URLRequestCustomJobDelegate; -class URLRequestCustomJobShared; +class URLRequestCustomJobProxy; // A request job that handles reading custom URL schemes class URLRequestCustomJob : public net::URLRequestJob { @@ -71,52 +67,12 @@ protected: private: std::string m_scheme; QWeakPointer<const BrowserContextAdapter> m_adapter; - URLRequestCustomJobShared *m_shared; + URLRequestCustomJobProxy *m_proxy; - friend class URLRequestCustomJobShared; + friend class URLRequestCustomJobProxy; DISALLOW_COPY_AND_ASSIGN(URLRequestCustomJob); }; - -// A shared state between URLRequestCustomJob living on the IO thread -// and URLRequestCustomJobDelegate living on the UI thread. -class URLRequestCustomJobShared { -public: - URLRequestCustomJobShared(URLRequestCustomJob *job); - ~URLRequestCustomJobShared(); - - void setReplyMimeType(const std::string &); - void setReplyCharset(const std::string &); - void setReplyDevice(QIODevice *); - - void redirect(const GURL &url); - void fail(int); - void abort(); - - void killJob(); - void unsetJobDelegate(); - - void startAsync(); - void notifyStarted(); - void notifyFailure(); - void notifyCanceled(); - - GURL requestUrl(); - std::string requestMethod(); - - QMutex m_mutex; - QPointer<QIODevice> m_device; - URLRequestCustomJob *m_job; - URLRequestCustomJobDelegate *m_delegate; - std::string m_mimeType; - std::string m_charset; - int m_error; - GURL m_redirect; - bool m_started; - bool m_asyncInitialized; - base::WeakPtrFactory<URLRequestCustomJobShared> m_weakFactory; -}; - } // namespace QtWebEngineCore #endif // URL_REQUEST_CUSTOM_JOB_H_ diff --git a/src/core/url_request_custom_job_delegate.cpp b/src/core/url_request_custom_job_delegate.cpp index 7e806a4e0..83a6353dc 100644 --- a/src/core/url_request_custom_job_delegate.cpp +++ b/src/core/url_request_custom_job_delegate.cpp @@ -37,8 +37,8 @@ ** ****************************************************************************/ -#include "url_request_custom_job.h" #include "url_request_custom_job_delegate.h" +#include "url_request_custom_job_proxy.h" #include "type_conversion.h" #include "net/base/net_errors.h" @@ -47,40 +47,40 @@ namespace QtWebEngineCore { -URLRequestCustomJobDelegate::URLRequestCustomJobDelegate(URLRequestCustomJobShared *shared) - : m_shared(shared) +URLRequestCustomJobDelegate::URLRequestCustomJobDelegate(URLRequestCustomJobProxy *proxy) + : m_proxy(proxy) { } URLRequestCustomJobDelegate::~URLRequestCustomJobDelegate() { - m_shared->unsetJobDelegate(); + m_proxy->unsetJobDelegate(); } QUrl URLRequestCustomJobDelegate::url() const { - return toQt(m_shared->requestUrl()); + return toQt(m_proxy->requestUrl()); } QByteArray URLRequestCustomJobDelegate::method() const { - return QByteArray::fromStdString(m_shared->requestMethod()); + return QByteArray::fromStdString(m_proxy->requestMethod()); } void URLRequestCustomJobDelegate::setReply(const QByteArray &contentType, QIODevice *device) { - m_shared->setReplyMimeType(contentType.toStdString()); - m_shared->setReplyDevice(device); + m_proxy->setReplyMimeType(contentType.toStdString()); + m_proxy->setReplyDevice(device); } void URLRequestCustomJobDelegate::abort() { - m_shared->abort(); + m_proxy->abort(); } void URLRequestCustomJobDelegate::redirect(const QUrl &url) { - m_shared->redirect(toGurl(url)); + m_proxy->redirect(toGurl(url)); } void URLRequestCustomJobDelegate::fail(Error error) @@ -106,7 +106,7 @@ void URLRequestCustomJobDelegate::fail(Error error) break; } if (net_error) - m_shared->fail(net_error); + m_proxy->fail(net_error); } } // namespace diff --git a/src/core/url_request_custom_job_delegate.h b/src/core/url_request_custom_job_delegate.h index 7752d979e..732ff8d7a 100644 --- a/src/core/url_request_custom_job_delegate.h +++ b/src/core/url_request_custom_job_delegate.h @@ -49,7 +49,7 @@ QT_FORWARD_DECLARE_CLASS(QIODevice) namespace QtWebEngineCore { -class URLRequestCustomJobShared; +class URLRequestCustomJobProxy; class QWEBENGINE_EXPORT URLRequestCustomJobDelegate : public QObject { Q_OBJECT @@ -75,10 +75,10 @@ public: void fail(Error); private: - URLRequestCustomJobDelegate(URLRequestCustomJobShared *shared); + URLRequestCustomJobDelegate(URLRequestCustomJobProxy *proxy); - friend class URLRequestCustomJobShared; - URLRequestCustomJobShared *m_shared; + friend class URLRequestCustomJobProxy; + URLRequestCustomJobProxy *m_proxy; }; } // namespace diff --git a/src/core/url_request_custom_job_proxy.cpp b/src/core/url_request_custom_job_proxy.cpp new file mode 100644 index 000000000..c6233709e --- /dev/null +++ b/src/core/url_request_custom_job_proxy.cpp @@ -0,0 +1,266 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "url_request_custom_job_proxy.h" +#include "url_request_custom_job.h" +#include "url_request_custom_job_delegate.h" +#include "api/qwebengineurlrequestjob.h" +#include "browser_context_adapter.h" +#include "type_conversion.h" +#include "content/public/browser/browser_thread.h" + +using namespace net; + +namespace QtWebEngineCore { + +URLRequestCustomJobProxy::URLRequestCustomJobProxy(URLRequestCustomJob *job) + : m_mutex(QMutex::Recursive) + , m_job(job) + , m_delegate(0) + , m_error(0) + , m_started(false) + , m_asyncInitialized(false) + , m_weakFactory(this) +{ +} + +URLRequestCustomJobProxy::~URLRequestCustomJobProxy() +{ + Q_ASSERT(!m_job); + Q_ASSERT(!m_delegate); +} + +void URLRequestCustomJobProxy::killJob() +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + QMutexLocker lock(&m_mutex); + m_job = 0; + bool doDelete = false; + if (m_delegate) { + m_delegate->deleteLater(); + } else { + // Do not delete yet if startAsync has not yet run. + doDelete = m_asyncInitialized; + } + if (m_device && m_device->isOpen()) + m_device->close(); + m_device = 0; + m_weakFactory.InvalidateWeakPtrs(); + lock.unlock(); + if (doDelete) + delete this; +} + +void URLRequestCustomJobProxy::unsetJobDelegate() +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + QMutexLocker lock(&m_mutex); + m_delegate = 0; + bool doDelete = false; + if (m_job) + abort(); + else + doDelete = true; + lock.unlock(); + if (doDelete) + delete this; +} + +void URLRequestCustomJobProxy::setReplyMimeType(const std::string &mimeType) +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + QMutexLocker lock(&m_mutex); + m_mimeType = mimeType; +} + +void URLRequestCustomJobProxy::setReplyCharset(const std::string &charset) +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + QMutexLocker lock(&m_mutex); + m_charset = charset; +} + +void URLRequestCustomJobProxy::setReplyDevice(QIODevice *device) +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + QMutexLocker lock(&m_mutex); + if (!m_job) + return; + m_device = device; + if (m_device && !m_device->isReadable()) + m_device->open(QIODevice::ReadOnly); + + qint64 size = m_device ? m_device->size() : -1; + if (size > 0) + m_job->set_expected_content_size(size); + if (m_device && m_device->isReadable()) { + content::BrowserThread::PostTask( + content::BrowserThread::IO, FROM_HERE, + base::Bind(&URLRequestCustomJobProxy::notifyStarted, + m_weakFactory.GetWeakPtr())); + } else { + fail(ERR_INVALID_URL); + } +} + +void URLRequestCustomJobProxy::redirect(const GURL &url) +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + QMutexLocker lock(&m_mutex); + if (m_device || m_error) + return; + if (!m_job) + return; + m_redirect = url; + content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, + base::Bind(&URLRequestCustomJobProxy::notifyStarted, + m_weakFactory.GetWeakPtr())); +} + +void URLRequestCustomJobProxy::abort() +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + QMutexLocker lock(&m_mutex); + if (m_device && m_device->isOpen()) + m_device->close(); + m_device = 0; + if (!m_job) + return; + content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, + base::Bind(&URLRequestCustomJobProxy::notifyCanceled, + m_weakFactory.GetWeakPtr())); +} + +void URLRequestCustomJobProxy::notifyCanceled() +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + QMutexLocker lock(&m_mutex); + if (!m_job) + return; + if (m_started) + m_job->NotifyCanceled(); + else + m_job->NotifyStartError(URLRequestStatus(URLRequestStatus::CANCELED, ERR_ABORTED)); +} + +void URLRequestCustomJobProxy::notifyStarted() +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + QMutexLocker lock(&m_mutex); + if (!m_job) + return; + Q_ASSERT(!m_started); + m_started = true; + m_job->NotifyHeadersComplete(); +} + +void URLRequestCustomJobProxy::fail(int error) +{ + QMutexLocker lock(&m_mutex); + m_error = error; + if (content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) + return; + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + if (!m_job) + return; + content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, + base::Bind(&URLRequestCustomJobProxy::notifyFailure, + m_weakFactory.GetWeakPtr())); +} + +void URLRequestCustomJobProxy::notifyFailure() +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + QMutexLocker lock(&m_mutex); + if (!m_job) + return; + if (m_device) + m_device->close(); + if (!m_started) + m_job->NotifyStartError(URLRequestStatus::FromError(m_error)); + // else we fail on the next read, or the read that might already be in progress +} + +GURL URLRequestCustomJobProxy::requestUrl() +{ + QMutexLocker lock(&m_mutex); + if (!m_job) + return GURL(); + return m_job->request()->url(); +} + +std::string URLRequestCustomJobProxy::requestMethod() +{ + QMutexLocker lock(&m_mutex); + if (!m_job) + return std::string(); + return m_job->request()->method(); +} + +void URLRequestCustomJobProxy::startAsync() +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + Q_ASSERT(!m_started); + Q_ASSERT(!m_delegate); + QMutexLocker lock(&m_mutex); + if (!m_job) { + lock.unlock(); + delete this; + return; + } + + 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_proxy.h b/src/core/url_request_custom_job_proxy.h new file mode 100644 index 000000000..b8c7b5c67 --- /dev/null +++ b/src/core/url_request_custom_job_proxy.h @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2017 Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef URL_REQUEST_CUSTOM_JOB_PROXY_H_ +#define URL_REQUEST_CUSTOM_JOB_PROXY_H_ + +#include "url/gurl.h" +#include "base/memory/weak_ptr.h" +#include <QtCore/QMutex> +#include <QtCore/QPointer> + + +QT_FORWARD_DECLARE_CLASS(QIODevice) + +namespace QtWebEngineCore { + +class URLRequestCustomJob; +class URLRequestCustomJobDelegate; + +// Used to comunicate between URLRequestCustomJob living on the IO thread +// and URLRequestCustomJobDelegate living on the UI thread. +class URLRequestCustomJobProxy { +public: + URLRequestCustomJobProxy(URLRequestCustomJob *job); + ~URLRequestCustomJobProxy(); + + void setReplyMimeType(const std::string &); + void setReplyCharset(const std::string &); + void setReplyDevice(QIODevice *); + + void redirect(const GURL &url); + void fail(int); + void abort(); + + void killJob(); + void unsetJobDelegate(); + + void startAsync(); + void notifyStarted(); + void notifyFailure(); + void notifyCanceled(); + + GURL requestUrl(); + std::string requestMethod(); + + QMutex m_mutex; + QPointer<QIODevice> m_device; + URLRequestCustomJob *m_job; + URLRequestCustomJobDelegate *m_delegate; + std::string m_mimeType; + std::string m_charset; + int m_error; + GURL m_redirect; + bool m_started; + bool m_asyncInitialized; + base::WeakPtrFactory<URLRequestCustomJobProxy> m_weakFactory; +}; + +} // namespace QtWebEngineCore + +#endif // URL_REQUEST_CUSTOM_JOB_PROXY_H_ |