From 303008d070132c0981ca04cbe1aeb6250907935a Mon Sep 17 00:00:00 2001 From: "zeno.albisser@nokia.com" Date: Tue, 24 Jan 2012 10:03:54 +0000 Subject: [PATCH] [Qt][WK2] Application URL schemes cause asserts when using debug. https://bugs.webkit.org/show_bug.cgi?id=76700 Instances of QtNetworkRequestData / QtNetworkReplyData are meant to be used for transfering data over IPC. To allow transferring instances of these classes over IPC they need to be copyable, and it must be possible to create such instances on the stack. Because classes that inherit from RefCounted always need to be used in connection with RefPtr, QtNetworkRequestData and QtNetworkReplyData cannot inherit directly from RefCounted. Deleting an object that inherits from RefCounted, without the proper sequence of ref()/deref() being called by it's RefPtr, causes asserts when running a debug version. Reviewed by Simon Hausmann. * Shared/qt/QtNetworkReplyData.h: (WebKit::QtRefCountedNetworkReplyData::data): * Shared/qt/QtNetworkRequestData.cpp: (WebKit::QtRefCountedNetworkRequestData::QtRefCountedNetworkRequestData): * Shared/qt/QtNetworkRequestData.h: (WebKit::QtRefCountedNetworkRequestData::data): * Target.pri: * UIProcess/API/qt/qquicknetworkreply.cpp: (QQuickNetworkReply::QQuickNetworkReply): (QQuickNetworkReply::contentType): (QQuickNetworkReply::setContentType): (QQuickNetworkReply::operation): (QQuickNetworkReply::setOperation): (QQuickNetworkReply::contentDisposition): (QQuickNetworkReply::setContentDisposition): (QQuickNetworkReply::location): (QQuickNetworkReply::setLocation): (QQuickNetworkReply::lastModified): (QQuickNetworkReply::setLastModified): (QQuickNetworkReply::cookie): (QQuickNetworkReply::setCookie): (QQuickNetworkReply::userAgent): (QQuickNetworkReply::setUserAgent): (QQuickNetworkReply::server): (QQuickNetworkReply::setServer): (QQuickNetworkReply::data): (QQuickNetworkReply::setData): (QQuickNetworkReply::send): (QQuickNetworkReply::networkRequestData): (QQuickNetworkReply::setNetworkRequestData): (QQuickNetworkReply::networkReplyData): * UIProcess/API/qt/qquicknetworkreply_p.h: * UIProcess/API/qt/qquicknetworkrequest.cpp: (QQuickNetworkRequest::QQuickNetworkRequest): (QQuickNetworkRequest::setNetworkRequestData): (QQuickNetworkRequest::url): * UIProcess/API/qt/qquicknetworkrequest_p.h: * UIProcess/API/qt/qquickwebview.cpp: (QQuickWebViewExperimental::invokeApplicationSchemeHandler): * UIProcess/API/qt/qquickwebview_p.h: * UIProcess/WebPageProxy.h: * UIProcess/qt/QtPageClient.cpp: (QtPageClient::handleApplicationSchemeRequest): * UIProcess/qt/QtPageClient.h: * UIProcess/qt/WebPageProxyQt.cpp: (WebKit::WebPageProxy::resolveApplicationSchemeRequest): (WebKit::WebPageProxy::sendApplicationSchemeReply): * WebProcess/qt/QtNetworkReply.cpp: (WebKit::QtNetworkReply::setData): (WebKit::QtNetworkReply::readData): git-svn-id: http://svn.webkit.org/repository/webkit/trunk@105711 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- Source/WebKit2/ChangeLog | 70 ++++++++++++++++++ Source/WebKit2/Shared/qt/QtNetworkReplyData.h | 11 ++- Source/WebKit2/Shared/qt/QtNetworkRequestData.cpp | 12 +-- Source/WebKit2/Shared/qt/QtNetworkRequestData.h | 11 ++- Source/WebKit2/Target.pri | 1 + .../UIProcess/API/qt/qquicknetworkreply.cpp | 85 +++++++++++----------- .../UIProcess/API/qt/qquicknetworkreply_p.h | 13 ++-- .../UIProcess/API/qt/qquicknetworkrequest.cpp | 48 ++++++++++++ .../UIProcess/API/qt/qquicknetworkrequest_p.h | 17 ++--- Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp | 9 ++- Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h | 4 +- Source/WebKit2/UIProcess/WebPageProxy.h | 2 +- Source/WebKit2/UIProcess/qt/QtPageClient.cpp | 4 +- Source/WebKit2/UIProcess/qt/QtPageClient.h | 2 +- Source/WebKit2/UIProcess/qt/WebPageProxyQt.cpp | 8 +- Source/WebKit2/WebProcess/qt/QtNetworkReply.cpp | 5 ++ 16 files changed, 220 insertions(+), 82 deletions(-) create mode 100644 Source/WebKit2/UIProcess/API/qt/qquicknetworkrequest.cpp diff --git a/Source/WebKit2/ChangeLog b/Source/WebKit2/ChangeLog index 7b9b3cd..1faaae1 100644 --- a/Source/WebKit2/ChangeLog +++ b/Source/WebKit2/ChangeLog @@ -1,3 +1,73 @@ +2012-01-24 Zeno Albisser + + [Qt][WK2] Application URL schemes cause asserts when using debug. + https://bugs.webkit.org/show_bug.cgi?id=76700 + + Instances of QtNetworkRequestData / QtNetworkReplyData are meant + to be used for transfering data over IPC. To allow transferring + instances of these classes over IPC they need to be copyable, + and it must be possible to create such instances on the stack. + Because classes that inherit from RefCounted always need to be + used in connection with RefPtr, QtNetworkRequestData and + QtNetworkReplyData cannot inherit directly from RefCounted. + + Deleting an object that inherits from RefCounted, without + the proper sequence of ref()/deref() being called by it's + RefPtr, causes asserts when running a debug version. + + Reviewed by Simon Hausmann. + + * Shared/qt/QtNetworkReplyData.h: + (WebKit::QtRefCountedNetworkReplyData::data): + * Shared/qt/QtNetworkRequestData.cpp: + (WebKit::QtRefCountedNetworkRequestData::QtRefCountedNetworkRequestData): + * Shared/qt/QtNetworkRequestData.h: + (WebKit::QtRefCountedNetworkRequestData::data): + * Target.pri: + * UIProcess/API/qt/qquicknetworkreply.cpp: + (QQuickNetworkReply::QQuickNetworkReply): + (QQuickNetworkReply::contentType): + (QQuickNetworkReply::setContentType): + (QQuickNetworkReply::operation): + (QQuickNetworkReply::setOperation): + (QQuickNetworkReply::contentDisposition): + (QQuickNetworkReply::setContentDisposition): + (QQuickNetworkReply::location): + (QQuickNetworkReply::setLocation): + (QQuickNetworkReply::lastModified): + (QQuickNetworkReply::setLastModified): + (QQuickNetworkReply::cookie): + (QQuickNetworkReply::setCookie): + (QQuickNetworkReply::userAgent): + (QQuickNetworkReply::setUserAgent): + (QQuickNetworkReply::server): + (QQuickNetworkReply::setServer): + (QQuickNetworkReply::data): + (QQuickNetworkReply::setData): + (QQuickNetworkReply::send): + (QQuickNetworkReply::networkRequestData): + (QQuickNetworkReply::setNetworkRequestData): + (QQuickNetworkReply::networkReplyData): + * UIProcess/API/qt/qquicknetworkreply_p.h: + * UIProcess/API/qt/qquicknetworkrequest.cpp: + (QQuickNetworkRequest::QQuickNetworkRequest): + (QQuickNetworkRequest::setNetworkRequestData): + (QQuickNetworkRequest::url): + * UIProcess/API/qt/qquicknetworkrequest_p.h: + * UIProcess/API/qt/qquickwebview.cpp: + (QQuickWebViewExperimental::invokeApplicationSchemeHandler): + * UIProcess/API/qt/qquickwebview_p.h: + * UIProcess/WebPageProxy.h: + * UIProcess/qt/QtPageClient.cpp: + (QtPageClient::handleApplicationSchemeRequest): + * UIProcess/qt/QtPageClient.h: + * UIProcess/qt/WebPageProxyQt.cpp: + (WebKit::WebPageProxy::resolveApplicationSchemeRequest): + (WebKit::WebPageProxy::sendApplicationSchemeReply): + * WebProcess/qt/QtNetworkReply.cpp: + (WebKit::QtNetworkReply::setData): + (WebKit::QtNetworkReply::readData): + 2012-01-24 Carlos Garcia Campos [GTK] Implement DownloadClient in WebKit2 GTK+ API diff --git a/Source/WebKit2/Shared/qt/QtNetworkReplyData.h b/Source/WebKit2/Shared/qt/QtNetworkReplyData.h index d74b422..c39a48f 100644 --- a/Source/WebKit2/Shared/qt/QtNetworkReplyData.h +++ b/Source/WebKit2/Shared/qt/QtNetworkReplyData.h @@ -39,9 +39,7 @@ class ArgumentDecoder; namespace WebKit { -struct QtNetworkReplyData : public WTF::RefCounted { - WTF_MAKE_NONCOPYABLE(QtNetworkReplyData); -public: +struct QtNetworkReplyData { QtNetworkReplyData(); void encode(CoreIPC::ArgumentEncoder*) const; @@ -63,6 +61,13 @@ public: SharedMemory::Handle m_dataHandle; }; +struct QtRefCountedNetworkReplyData : public WTF::RefCounted { + QtNetworkReplyData& data() { return m_data; } +private: + QtNetworkReplyData m_data; +}; + + } // namespace WebKit #endif // QtNetworkReplyData_h diff --git a/Source/WebKit2/Shared/qt/QtNetworkRequestData.cpp b/Source/WebKit2/Shared/qt/QtNetworkRequestData.cpp index c6ea6e3..f210660 100644 --- a/Source/WebKit2/Shared/qt/QtNetworkRequestData.cpp +++ b/Source/WebKit2/Shared/qt/QtNetworkRequestData.cpp @@ -36,6 +36,10 @@ namespace WebKit { +QtRefCountedNetworkRequestData::QtRefCountedNetworkRequestData(const QtNetworkRequestData& data) + : m_data(data) +{ } + QtNetworkRequestData::QtNetworkRequestData() { } @@ -46,14 +50,6 @@ QtNetworkRequestData::QtNetworkRequestData(const QNetworkRequest& request, QNetw m_replyUuid = QUuid::createUuid().toString(); } -QtNetworkRequestData::QtNetworkRequestData(const QtNetworkRequestData& origin) - : RefCounted(), - m_scheme(origin.m_scheme), - m_urlString(origin.m_urlString), - m_replyUuid(origin.m_replyUuid) -{ -} - void QtNetworkRequestData::encode(CoreIPC::ArgumentEncoder* encoder) const { encoder->encode(m_scheme); diff --git a/Source/WebKit2/Shared/qt/QtNetworkRequestData.h b/Source/WebKit2/Shared/qt/QtNetworkRequestData.h index 1567964..082d499 100644 --- a/Source/WebKit2/Shared/qt/QtNetworkRequestData.h +++ b/Source/WebKit2/Shared/qt/QtNetworkRequestData.h @@ -39,11 +39,9 @@ class QNetworkReply; namespace WebKit { -struct QtNetworkRequestData : public WTF::RefCounted { +struct QtNetworkRequestData { QtNetworkRequestData(); QtNetworkRequestData(const QNetworkRequest&, QNetworkReply*); - QtNetworkRequestData(const QtNetworkRequestData&); - void encode(CoreIPC::ArgumentEncoder*) const; static bool decode(CoreIPC::ArgumentDecoder*, QtNetworkRequestData&); @@ -52,6 +50,13 @@ struct QtNetworkRequestData : public WTF::RefCounted { String m_replyUuid; }; +struct QtRefCountedNetworkRequestData : public WTF::RefCounted { + QtRefCountedNetworkRequestData(const QtNetworkRequestData&); + QtNetworkRequestData& data() { return m_data; } +private: + QtNetworkRequestData m_data; +}; + } // namespace WebKit #endif // QtNetworkRequestData_h diff --git a/Source/WebKit2/Target.pri b/Source/WebKit2/Target.pri index 5ee2797..6704cac 100644 --- a/Source/WebKit2/Target.pri +++ b/Source/WebKit2/Target.pri @@ -507,6 +507,7 @@ SOURCES += \ UIProcess/API/qt/qquickwebview.cpp \ UIProcess/API/qt/qwebiconimageprovider.cpp \ UIProcess/API/qt/qquicknetworkreply.cpp \ + UIProcess/API/qt/qquicknetworkrequest.cpp \ UIProcess/API/qt/qquickurlschemedelegate.cpp \ UIProcess/API/qt/qwebpreferences.cpp \ UIProcess/API/qt/qwebviewportinfo.cpp \ diff --git a/Source/WebKit2/UIProcess/API/qt/qquicknetworkreply.cpp b/Source/WebKit2/UIProcess/API/qt/qquicknetworkreply.cpp index 4e88103..c69486c 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquicknetworkreply.cpp +++ b/Source/WebKit2/UIProcess/API/qt/qquicknetworkreply.cpp @@ -30,128 +30,127 @@ using namespace WebKit; QQuickNetworkReply::QQuickNetworkReply(QObject* parent) : QObject(parent) - , m_networkReplyData(adoptRef(new WebKit::QtNetworkReplyData)) + , m_networkReplyData(adoptRef(new WebKit::QtRefCountedNetworkReplyData)) + , m_dataLength(0) { Q_ASSERT(parent); } QString QQuickNetworkReply::contentType() const { - return m_networkReplyData->m_contentType; + return m_networkReplyData->data().m_contentType; } void QQuickNetworkReply::setContentType(const QString& contentType) { - m_networkReplyData->m_contentType = contentType; + m_networkReplyData->data().m_contentType = contentType; } QNetworkAccessManager::Operation QQuickNetworkReply::operation() const { - return m_networkReplyData->m_operation; + return m_networkReplyData->data().m_operation; } void QQuickNetworkReply::setOperation(QNetworkAccessManager::Operation operation) { - m_networkReplyData->m_operation = operation; + m_networkReplyData->data().m_operation = operation; } QString QQuickNetworkReply::contentDisposition() const { - return m_networkReplyData->m_contentDisposition; + return m_networkReplyData->data().m_contentDisposition; } void QQuickNetworkReply::setContentDisposition(const QString& disposition) { - m_networkReplyData->m_contentDisposition = disposition; + m_networkReplyData->data().m_contentDisposition = disposition; } QString QQuickNetworkReply::location() const { - return m_networkReplyData->m_location; + return m_networkReplyData->data().m_location; } void QQuickNetworkReply::setLocation(const QString& location) { - m_networkReplyData->m_location = location; + m_networkReplyData->data().m_location = location; } QString QQuickNetworkReply::lastModified() const { - return QDateTime::fromMSecsSinceEpoch(m_networkReplyData->m_lastModified).toString(Qt::ISODate); + return QDateTime::fromMSecsSinceEpoch(m_networkReplyData->data().m_lastModified).toString(Qt::ISODate); } void QQuickNetworkReply::setLastModified(const QString& lastModified) { - m_networkReplyData->m_lastModified = QDateTime::fromString(lastModified, Qt::ISODate).toMSecsSinceEpoch(); + m_networkReplyData->data().m_lastModified = QDateTime::fromString(lastModified, Qt::ISODate).toMSecsSinceEpoch(); } QString QQuickNetworkReply::cookie() const { - return m_networkReplyData->m_cookie; + return m_networkReplyData->data().m_cookie; } void QQuickNetworkReply::setCookie(const QString& cookie) { - m_networkReplyData->m_cookie = cookie; + m_networkReplyData->data().m_cookie = cookie; } QString QQuickNetworkReply::userAgent() const { - return m_networkReplyData->m_userAgent; + return m_networkReplyData->data().m_userAgent; } void QQuickNetworkReply::setUserAgent(const QString& userAgent) { - m_networkReplyData->m_userAgent = userAgent; + m_networkReplyData->data().m_userAgent = userAgent; } QString QQuickNetworkReply::server() const { - return m_networkReplyData->m_server; + return m_networkReplyData->data().m_server; } void QQuickNetworkReply::setServer(const QString& server) { - m_networkReplyData->m_server = server; + m_networkReplyData->data().m_server = server; } QString QQuickNetworkReply::data() const { - if (m_networkReplyData->m_dataHandle.isNull()) - return QString(); - RefPtr sm = SharedMemory::create(m_networkReplyData->m_dataHandle, SharedMemory::ReadOnly); - if (!sm) + if (!m_sharedMemory) return QString(); - uint64_t stringLength = m_networkReplyData->m_contentLength / sizeof(UChar); - return QString(reinterpret_cast(sm->data()), stringLength); + uint64_t stringLength = m_dataLength / sizeof(QChar); + return QString(reinterpret_cast(m_sharedMemory->data()), stringLength); } void QQuickNetworkReply::setData(const QString& data) { - // This function can be called several times. In this case the previous SharedMemory handles - // will be overwritten and the previously allocated SharedMemory will die with the last handle. - m_networkReplyData->m_contentLength = 0; + // This function can be called several times. In this case the previously allocated SharedMemory + // will be released automatically and new memory will be allocated. + m_dataLength = 0; if (data.isNull()) return; - const UChar* ucharData = reinterpret_cast(data.constData()); - uint64_t smLength = sizeof(UChar) * data.length(); - RefPtr sm = SharedMemory::create(smLength); - if (!sm) + uint64_t smLength = sizeof(QChar) * data.length(); + m_sharedMemory = SharedMemory::create(smLength); + if (!m_sharedMemory) return; + // The size of the allocated shared memory can be bigger than requested. // Usually the size will be rounded up to the next multiple of a page size. - memcpy(sm->data(), ucharData, smLength); - - if (!sm->createHandle(m_networkReplyData->m_dataHandle, SharedMemory::ReadOnly)) - return; - m_networkReplyData->m_contentLength = smLength; + memcpy(m_sharedMemory->data(), data.constData(), smLength); + m_dataLength = smLength; } void QQuickNetworkReply::send() { + if (!m_sharedMemory || !m_sharedMemory->createHandle(m_networkReplyData->data().m_dataHandle, SharedMemory::ReadOnly)) + return; + m_networkReplyData->data().m_contentLength = m_dataLength; + QObject* schemeParent = parent()->parent(); if (!schemeParent) return; @@ -159,22 +158,26 @@ void QQuickNetworkReply::send() if (!webViewExperimental) return; webViewExperimental->sendApplicationSchemeReply(this); + + // After sending the reply data, we have to reinitialize the m_networkReplyData, + // to make sure we have a fresh SharesMemory::Handle. + m_networkReplyData = adoptRef(new WebKit::QtRefCountedNetworkReplyData); } -WTF::RefPtr QQuickNetworkReply::networkRequestData() const +WebKit::QtRefCountedNetworkRequestData* QQuickNetworkReply::networkRequestData() const { - return m_networkRequestData; + return m_networkRequestData.get(); } -void QQuickNetworkReply::setNetworkRequestData(WTF::RefPtr data) +void QQuickNetworkReply::setNetworkRequestData(WTF::PassRefPtr data) { m_networkRequestData = data; - m_networkReplyData->m_replyUuid = data->m_replyUuid; + m_networkReplyData->data().m_replyUuid = m_networkRequestData->data().m_replyUuid; } -WTF::RefPtr QQuickNetworkReply::networkReplyData() const +WebKit::QtRefCountedNetworkReplyData* QQuickNetworkReply::networkReplyData() const { - return m_networkReplyData; + return m_networkReplyData.get(); } #include "moc_qquicknetworkreply_p.cpp" diff --git a/Source/WebKit2/UIProcess/API/qt/qquicknetworkreply_p.h b/Source/WebKit2/UIProcess/API/qt/qquicknetworkreply_p.h index ffe45f3..59eb7f2 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquicknetworkreply_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qquicknetworkreply_p.h @@ -23,6 +23,7 @@ #include "QtNetworkReplyData.h" #include "QtNetworkRequestData.h" +#include "SharedMemory.h" #include "qwebkitglobal.h" #include #include @@ -57,16 +58,18 @@ public: QString data() const; void setData(const QString& data); - WTF::RefPtr networkRequestData() const; - void setNetworkRequestData(WTF::RefPtr data); - WTF::RefPtr networkReplyData() const; + WebKit::QtRefCountedNetworkRequestData* networkRequestData() const; + void setNetworkRequestData(WTF::PassRefPtr data); + WebKit::QtRefCountedNetworkReplyData* networkReplyData() const; public Q_SLOTS: void send(); private: - WTF::RefPtr m_networkRequestData; - WTF::RefPtr m_networkReplyData; + WTF::RefPtr m_networkRequestData; + WTF::RefPtr m_networkReplyData; + WTF::RefPtr m_sharedMemory; + uint64_t m_dataLength; }; QML_DECLARE_TYPE(QQuickNetworkReply) diff --git a/Source/WebKit2/UIProcess/API/qt/qquicknetworkrequest.cpp b/Source/WebKit2/UIProcess/API/qt/qquicknetworkrequest.cpp new file mode 100644 index 0000000..152ef4e --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/qquicknetworkrequest.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2011 Zeno Albisser + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#include "config.h" +#include "qquicknetworkrequest_p.h" + +#include "QtNetworkRequestData.h" +#include "qquickwebview_p.h" + +using namespace WebKit; + +QQuickNetworkRequest::QQuickNetworkRequest(QObject* parent) + : QObject(parent) +{ + Q_ASSERT(parent); +} + +void QQuickNetworkRequest::setNetworkRequestData(WTF::PassRefPtr data) +{ + m_networkRequestData = data; +} + +QUrl QQuickNetworkRequest::url() const +{ + if (m_networkRequestData) + return QUrl(m_networkRequestData->data().m_urlString); + return QUrl(); +} + +#include "moc_qquicknetworkrequest_p.cpp" + diff --git a/Source/WebKit2/UIProcess/API/qt/qquicknetworkrequest_p.h b/Source/WebKit2/UIProcess/API/qt/qquicknetworkrequest_p.h index 113114c..7df66f5 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquicknetworkrequest_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qquicknetworkrequest_p.h @@ -21,6 +21,8 @@ #ifndef qquicknetworkrequest_p_h #define qquicknetworkrequest_p_h +#include "QtNetworkRequestData.h" +#include "RefPtr.h" #include "qwebkitglobal.h" #include #include @@ -28,20 +30,17 @@ class QWEBKIT_EXPORT QQuickNetworkRequest : public QObject { Q_OBJECT - Q_PROPERTY(QString url READ url) + Q_PROPERTY(QUrl url READ url) public: - QQuickNetworkRequest(QObject* parent) - : QObject(parent) - { - Q_ASSERT(parent); - } + QQuickNetworkRequest(QObject* parent); - QString url() const { return m_url; } - void setUrl(const QString& url) { m_url = url; } + void setNetworkRequestData(WTF::PassRefPtr data); + + QUrl url() const; private: - QString m_url; + WTF::RefPtr m_networkRequestData; }; QML_DECLARE_TYPE(QQuickNetworkRequest) diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp b/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp index e7162b7..ea85442 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp @@ -34,6 +34,7 @@ #include "WebPreferences.h" #include "qquicknetworkreply_p.h" +#include "qquicknetworkrequest_p.h" #include "qquickwebpage_p_p.h" #include "qquickwebview_p_p.h" #include "qwebdownloaditem_p_p.h" @@ -824,15 +825,17 @@ QDeclarativeListProperty QQuickWebViewExperimental::sch QQuickWebViewExperimental::schemeDelegates_Clear); } -void QQuickWebViewExperimental::invokeApplicationSchemeHandler(PassRefPtr request) +void QQuickWebViewExperimental::invokeApplicationSchemeHandler(PassRefPtr request) { + RefPtr req = request; const QObjectList children = schemeParent->children(); for (int index = 0; index < children.count(); index++) { QQuickUrlSchemeDelegate* delegate = qobject_cast(children.at(index)); if (!delegate) continue; - if (!delegate->scheme().compare(QString(request->m_scheme), Qt::CaseInsensitive)) { - delegate->reply()->setNetworkRequestData(request); + if (!delegate->scheme().compare(QString(req->data().m_scheme), Qt::CaseInsensitive)) { + delegate->request()->setNetworkRequestData(req); + delegate->reply()->setNetworkRequestData(req); emit delegate->receivedRequest(); return; } diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h index 8e88c60..45a8df2 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h @@ -44,7 +44,7 @@ class PlatformWebView; } namespace WebKit { -class QtNetworkRequestData; +class QtRefCountedNetworkRequestData; } namespace WTF { @@ -250,7 +250,7 @@ public: static int schemeDelegates_Count(QDeclarativeListProperty*); static void schemeDelegates_Clear(QDeclarativeListProperty*); QDeclarativeListProperty schemeDelegates(); - void invokeApplicationSchemeHandler(WTF::PassRefPtr); + void invokeApplicationSchemeHandler(WTF::PassRefPtr); void sendApplicationSchemeReply(QQuickNetworkReply*); public Q_SLOTS: diff --git a/Source/WebKit2/UIProcess/WebPageProxy.h b/Source/WebKit2/UIProcess/WebPageProxy.h index 21c7a92..241d70f 100644 --- a/Source/WebKit2/UIProcess/WebPageProxy.h +++ b/Source/WebKit2/UIProcess/WebPageProxy.h @@ -1018,7 +1018,7 @@ private: float m_mediaVolume; #if PLATFORM(QT) - WTF::HashSet > m_applicationSchemeRequests; + WTF::HashSet > m_applicationSchemeRequests; #endif }; diff --git a/Source/WebKit2/UIProcess/qt/QtPageClient.cpp b/Source/WebKit2/UIProcess/qt/QtPageClient.cpp index 9fda135..3824e5d 100644 --- a/Source/WebKit2/UIProcess/qt/QtPageClient.cpp +++ b/Source/WebKit2/UIProcess/qt/QtPageClient.cpp @@ -100,11 +100,11 @@ void QtPageClient::handleDownloadRequest(DownloadProxy* download) QQuickWebViewPrivate::get(m_webView)->handleDownloadRequest(download); } -void QtPageClient::handleApplicationSchemeRequest(PassRefPtr requestData) +void QtPageClient::handleApplicationSchemeRequest(PassRefPtr requestData) { if (!m_webView || !m_webView->experimental()) return; - m_webView->experimental()->invokeApplicationSchemeHandler(requestData.get()); + m_webView->experimental()->invokeApplicationSchemeHandler(requestData); } void QtPageClient::handleAuthenticationRequiredRequest(const String& hostname, const String& realm, const String& prefilledUsername, String& username, String& password) diff --git a/Source/WebKit2/UIProcess/qt/QtPageClient.h b/Source/WebKit2/UIProcess/qt/QtPageClient.h index 3a85859..43050f5 100644 --- a/Source/WebKit2/UIProcess/qt/QtPageClient.h +++ b/Source/WebKit2/UIProcess/qt/QtPageClient.h @@ -53,7 +53,7 @@ public: virtual void didRelaunchProcess(); virtual PassOwnPtr createDrawingAreaProxy(); virtual void handleDownloadRequest(DownloadProxy*); - virtual void handleApplicationSchemeRequest(PassRefPtr); + virtual void handleApplicationSchemeRequest(PassRefPtr); virtual void handleAuthenticationRequiredRequest(const String& hostname, const String& realm, const String& prefilledUsername, String& username, String& password); virtual void handleCertificateVerificationRequest(const String& hostname, bool& ignoreErrors); diff --git a/Source/WebKit2/UIProcess/qt/WebPageProxyQt.cpp b/Source/WebKit2/UIProcess/qt/WebPageProxyQt.cpp index ac9fde4..bf86edc 100644 --- a/Source/WebKit2/UIProcess/qt/WebPageProxyQt.cpp +++ b/Source/WebKit2/UIProcess/qt/WebPageProxyQt.cpp @@ -87,17 +87,17 @@ void WebPageProxy::registerApplicationScheme(const String& scheme) void WebPageProxy::resolveApplicationSchemeRequest(QtNetworkRequestData request) { - RefPtr requestData = adoptRef(new QtNetworkRequestData(request)); + RefPtr requestData = adoptRef(new QtRefCountedNetworkRequestData(request)); m_applicationSchemeRequests.add(requestData); static_cast(m_pageClient)->handleApplicationSchemeRequest(requestData); } void WebPageProxy::sendApplicationSchemeReply(const QQuickNetworkReply* reply) { - RefPtr requestData = reply->networkRequestData(); + RefPtr requestData = reply->networkRequestData(); if (m_applicationSchemeRequests.contains(requestData)) { - RefPtr replyData = reply->networkReplyData(); - process()->send(Messages::WebPage::ApplicationSchemeReply(*replyData), pageID()); + RefPtr replyData = reply->networkReplyData(); + process()->send(Messages::WebPage::ApplicationSchemeReply(replyData->data()), pageID()); m_applicationSchemeRequests.remove(requestData); } } diff --git a/Source/WebKit2/WebProcess/qt/QtNetworkReply.cpp b/Source/WebKit2/WebProcess/qt/QtNetworkReply.cpp index fd0f5cb..9904110 100644 --- a/Source/WebKit2/WebProcess/qt/QtNetworkReply.cpp +++ b/Source/WebKit2/WebProcess/qt/QtNetworkReply.cpp @@ -50,6 +50,8 @@ QtNetworkReply::QtNetworkReply(const QNetworkRequest& req, QtNetworkAccessManage void QtNetworkReply::setData(const SharedMemory::Handle& handle, qint64 dataSize) { + if (handle.isNull()) + return; m_sharedMemory = SharedMemory::create(handle, SharedMemory::ReadOnly); if (!m_sharedMemory) return; @@ -82,6 +84,9 @@ void QtNetworkReply::setReplyData(const QtNetworkReplyData& replyData) qint64 QtNetworkReply::readData(char* data, qint64 maxlen) { + if (!m_sharedMemory) + return 0; + qint64 bytesRead = maxlen < m_bytesAvailable ? maxlen : m_bytesAvailable; if (qMemCopy(data, static_cast(m_sharedMemory->data()) + m_sharedMemorySize - m_bytesAvailable, bytesRead)) { m_bytesAvailable -= bytesRead; -- 2.7.4