https://bugs.webkit.org/show_bug.cgi?id=77007
Make application schemes use QVariant for payload data.
This allows passing QByteArrays as well as simple String data.
Remove unneeded http header parts that were exposed in
QQuickNetworkReply.
Add ByteArrayTestData class to allow injecting QByteArray
data into an application scheme handler for testing.
Reviewed by Simon Hausmann.
* Shared/qt/QtNetworkReplyData.cpp:
(WebKit::QtNetworkReplyData::QtNetworkReplyData):
(WebKit::QtNetworkReplyData::encode):
(WebKit::QtNetworkReplyData::decode):
* Shared/qt/QtNetworkReplyData.h:
* UIProcess/API/qt/qquicknetworkreply.cpp:
(QQuickNetworkReply::QQuickNetworkReply):
(QQuickNetworkReply::data):
(QQuickNetworkReply::setData):
(QQuickNetworkReply::send):
* UIProcess/API/qt/qquicknetworkreply_p.h:
* UIProcess/API/qt/tests/bytearraytestdata.cpp: Added.
(ByteArrayTestData::ByteArrayTestData):
(ByteArrayTestData::latin1Data):
(ByteArrayTestData::utf8Data):
* UIProcess/API/qt/tests/bytearraytestdata.h: Added.
* UIProcess/API/qt/tests/qmltests/WebView/tst_applicationScheme.qml:
* UIProcess/API/qt/tests/qmltests/tst_qmltests.cpp:
(main):
* UIProcess/API/qt/tests/tests.pri:
* WebProcess/qt/QtNetworkReply.cpp:
(WebKit::QtNetworkReply::setReplyData):
* WebProcess/qt/QtNetworkReply.h:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@105991
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2012-01-26 Zeno Albisser <zeno@webkit.org>
+
+ [Qt][WK2] Use QVariant for payload data in application URL schemes.
+ https://bugs.webkit.org/show_bug.cgi?id=77007
+
+ Make application schemes use QVariant for payload data.
+ This allows passing QByteArrays as well as simple String data.
+
+ Remove unneeded http header parts that were exposed in
+ QQuickNetworkReply.
+
+ Add ByteArrayTestData class to allow injecting QByteArray
+ data into an application scheme handler for testing.
+
+ Reviewed by Simon Hausmann.
+
+ * Shared/qt/QtNetworkReplyData.cpp:
+ (WebKit::QtNetworkReplyData::QtNetworkReplyData):
+ (WebKit::QtNetworkReplyData::encode):
+ (WebKit::QtNetworkReplyData::decode):
+ * Shared/qt/QtNetworkReplyData.h:
+ * UIProcess/API/qt/qquicknetworkreply.cpp:
+ (QQuickNetworkReply::QQuickNetworkReply):
+ (QQuickNetworkReply::data):
+ (QQuickNetworkReply::setData):
+ (QQuickNetworkReply::send):
+ * UIProcess/API/qt/qquicknetworkreply_p.h:
+ * UIProcess/API/qt/tests/bytearraytestdata.cpp: Added.
+ (ByteArrayTestData::ByteArrayTestData):
+ (ByteArrayTestData::latin1Data):
+ (ByteArrayTestData::utf8Data):
+ * UIProcess/API/qt/tests/bytearraytestdata.h: Added.
+ * UIProcess/API/qt/tests/qmltests/WebView/tst_applicationScheme.qml:
+ * UIProcess/API/qt/tests/qmltests/tst_qmltests.cpp:
+ (main):
+ * UIProcess/API/qt/tests/tests.pri:
+ * WebProcess/qt/QtNetworkReply.cpp:
+ (WebKit::QtNetworkReply::setReplyData):
+ * WebProcess/qt/QtNetworkReply.h:
+
2012-01-26 Thiago Marcos P. Santos <tmpsantos@gmail.com>
[Qt] Fixed build when using force_static_libs_as_shared
QtNetworkReplyData::QtNetworkReplyData()
: m_contentLength(0)
- , m_lastModified(0)
{ }
void QtNetworkReplyData::encode(CoreIPC::ArgumentEncoder* encoder) const
{
encoder->encode(m_urlString);
- encoder->encodeEnum(m_operation);
- encoder->encode(m_contentDisposition);
encoder->encode(m_contentType);
encoder->encodeUInt64(m_contentLength);
- encoder->encode(m_location);
- encoder->encodeUInt64(m_lastModified);
- encoder->encode(m_cookie);
- encoder->encode(m_userAgent);
- encoder->encode(m_server);
encoder->encode(m_replyUuid);
encoder->encode(m_dataHandle);
}
{
if (!decoder->decode(destination.m_urlString))
return false;
- if (!decoder->decodeEnum(destination.m_operation))
- return false;
- if (!decoder->decode(destination.m_contentDisposition))
- return false;
if (!decoder->decode(destination.m_contentType))
return false;
if (!decoder->decodeUInt64(destination.m_contentLength))
return false;
- if (!decoder->decode(destination.m_location))
- return false;
- if (!decoder->decodeUInt64(destination.m_lastModified))
- return false;
- if (!decoder->decode(destination.m_cookie))
- return false;
- if (!decoder->decode(destination.m_userAgent))
- return false;
- if (!decoder->decode(destination.m_server))
- return false;
if (!decoder->decode(destination.m_replyUuid))
return false;
if (!decoder->decode(destination.m_dataHandle))
WTF::String m_urlString;
- QNetworkAccessManager::Operation m_operation;
- WTF::String m_contentDisposition;
WTF::String m_contentType;
uint64_t m_contentLength;
- WTF::String m_location;
- uint64_t m_lastModified;
- WTF::String m_cookie;
- WTF::String m_userAgent;
- WTF::String m_server;
String m_replyUuid;
SharedMemory::Handle m_dataHandle;
QQuickNetworkReply::QQuickNetworkReply(QObject* parent)
: QObject(parent)
, m_networkReplyData(adoptRef(new WebKit::QtRefCountedNetworkReplyData))
- , m_dataLength(0)
{
Q_ASSERT(parent);
}
m_networkReplyData->data().m_contentType = contentType;
}
-QNetworkAccessManager::Operation QQuickNetworkReply::operation() const
+QVariant QQuickNetworkReply::data() const
{
- return m_networkReplyData->data().m_operation;
+ return m_data;
}
-void QQuickNetworkReply::setOperation(QNetworkAccessManager::Operation operation)
+void QQuickNetworkReply::setData(const QVariant& data)
{
- m_networkReplyData->data().m_operation = operation;
+ m_data = data;
}
-QString QQuickNetworkReply::contentDisposition() const
-{
- return m_networkReplyData->data().m_contentDisposition;
-}
-
-void QQuickNetworkReply::setContentDisposition(const QString& disposition)
-{
- m_networkReplyData->data().m_contentDisposition = disposition;
-}
-
-QString QQuickNetworkReply::location() const
-{
- return m_networkReplyData->data().m_location;
-}
-
-void QQuickNetworkReply::setLocation(const QString& location)
-{
- m_networkReplyData->data().m_location = location;
-}
-
-QString QQuickNetworkReply::lastModified() const
-{
- return QDateTime::fromMSecsSinceEpoch(m_networkReplyData->data().m_lastModified).toString(Qt::ISODate);
-}
-
-void QQuickNetworkReply::setLastModified(const QString& lastModified)
-{
- m_networkReplyData->data().m_lastModified = QDateTime::fromString(lastModified, Qt::ISODate).toMSecsSinceEpoch();
-}
-
-QString QQuickNetworkReply::cookie() const
-{
- return m_networkReplyData->data().m_cookie;
-}
-
-void QQuickNetworkReply::setCookie(const QString& cookie)
-{
- m_networkReplyData->data().m_cookie = cookie;
-}
-
-QString QQuickNetworkReply::userAgent() const
-{
- return m_networkReplyData->data().m_userAgent;
-}
-
-void QQuickNetworkReply::setUserAgent(const QString& userAgent)
-{
- m_networkReplyData->data().m_userAgent = userAgent;
-}
-
-QString QQuickNetworkReply::server() const
-{
- return m_networkReplyData->data().m_server;
-}
-
-void QQuickNetworkReply::setServer(const QString& server)
-{
- m_networkReplyData->data().m_server = server;
-}
-
-QString QQuickNetworkReply::data() const
-{
- if (!m_sharedMemory)
- return QString();
-
- uint64_t stringLength = m_dataLength / sizeof(QChar);
- return QString(reinterpret_cast<const QChar*>(m_sharedMemory->data()), stringLength);
-}
-
-void QQuickNetworkReply::setData(const QString& data)
+void QQuickNetworkReply::send()
{
- // 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())
+ if (m_data.isNull())
return;
- uint64_t smLength = sizeof(QChar) * data.length();
- m_sharedMemory = SharedMemory::create(smLength);
- if (!m_sharedMemory)
+ uint64_t smLength = 0;
+ const void* ptrData = 0;
+ QString stringData;
+ QByteArray byteArrayData;
+ if (m_data.type() == QVariant::String) {
+ stringData = m_data.toString();
+ ptrData = reinterpret_cast<const void*>(stringData.constData());
+ smLength = sizeof(QChar) * stringData.length();
+ } else {
+ if (!m_data.canConvert<QByteArray>())
+ return;
+ byteArrayData = m_data.toByteArray();
+ ptrData = byteArrayData.data();
+ smLength = byteArrayData.size();
+ }
+
+ WTF::RefPtr<WebKit::SharedMemory> sharedMemory = SharedMemory::create(smLength);
+ if (!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(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;
- QQuickWebViewExperimental* webViewExperimental = qobject_cast<QQuickWebViewExperimental*>(schemeParent->parent());
- if (!webViewExperimental)
- return;
- webViewExperimental->sendApplicationSchemeReply(this);
+ memcpy(sharedMemory->data(), ptrData, smLength);
+
+ if (sharedMemory->createHandle(m_networkReplyData->data().m_dataHandle, SharedMemory::ReadOnly)) {
+ m_networkReplyData->data().m_contentLength = smLength;
+
+ QObject* schemeParent = parent()->parent();
+ if (schemeParent) {
+ QQuickWebViewExperimental* webViewExperimental = qobject_cast<QQuickWebViewExperimental*>(schemeParent->parent());
+ if (webViewExperimental)
+ webViewExperimental->sendApplicationSchemeReply(this);
+ }
+ }
// After sending the reply data, we have to reinitialize the m_networkReplyData,
// to make sure we have a fresh SharesMemory::Handle.
class QWEBKIT_EXPORT QQuickNetworkReply : public QObject {
Q_OBJECT
Q_PROPERTY(QString contentType READ contentType WRITE setContentType)
- Q_PROPERTY(QString data READ data WRITE setData)
+ Q_PROPERTY(QVariant data READ data WRITE setData)
Q_ENUMS(QNetworkAccessManager::Operation)
public:
QQuickNetworkReply(QObject* parent);
QString contentType() const;
void setContentType(const QString&);
- QNetworkAccessManager::Operation operation() const;
- void setOperation(QNetworkAccessManager::Operation);
- QString contentDisposition() const;
- void setContentDisposition(const QString&);
- QString location() const;
- void setLocation(const QString&);
- QString lastModified() const;
- void setLastModified(const QString&);
- QString cookie() const;
- void setCookie(const QString&);
- QString userAgent() const;
- void setUserAgent(const QString&);
- QString server() const;
- void setServer(const QString&);
- QString data() const;
- void setData(const QString& data);
+ QVariant data() const;
+ void setData(const QVariant& data);
WebKit::QtRefCountedNetworkRequestData* networkRequestData() const;
void setNetworkRequestData(WTF::PassRefPtr<WebKit::QtRefCountedNetworkRequestData> data);
private:
WTF::RefPtr<WebKit::QtRefCountedNetworkRequestData> m_networkRequestData;
WTF::RefPtr<WebKit::QtRefCountedNetworkReplyData> m_networkReplyData;
- WTF::RefPtr<WebKit::SharedMemory> m_sharedMemory;
- uint64_t m_dataLength;
+ QVariant m_data;
};
QML_DECLARE_TYPE(QQuickNetworkReply)
--- /dev/null
+/*
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * 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 "bytearraytestdata.h"
+
+ByteArrayTestData::ByteArrayTestData(QObject* parent)
+ : QObject(parent)
+{
+ QString text = QStringLiteral("<html><head><title>title with copyright %1</title></head><body>content</body></html>");
+ text = text.arg(QChar::fromLatin1(169));
+
+ m_latin1Data = text.toLatin1();
+ m_utf8Data = text.toUtf8();
+
+ Q_ASSERT(m_latin1Data != m_utf8Data);
+}
+
+QVariant ByteArrayTestData::latin1Data() const
+{
+ return QVariant(m_latin1Data);
+}
+
+QVariant ByteArrayTestData::utf8Data() const
+{
+ return QVariant(m_utf8Data);
+}
+
+#include "moc_bytearraytestdata.cpp"
--- /dev/null
+/*
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * 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.
+ *
+ */
+
+#ifndef bytearraytestdata_h
+#define bytearraytestdata_h
+
+#include "qwebkitglobal.h"
+#include <QByteArray>
+#include <QObject>
+#include <QtQuick/qquickitem.h>
+
+class QWEBKIT_EXPORT ByteArrayTestData : public QObject {
+ Q_OBJECT
+ Q_PROPERTY(QVariant latin1Data READ latin1Data)
+ Q_PROPERTY(QVariant utf8Data READ utf8Data)
+
+public:
+ ByteArrayTestData(QObject* parent = 0);
+ QVariant latin1Data() const;
+ QVariant utf8Data() const;
+
+private:
+ QByteArray m_latin1Data;
+ QByteArray m_utf8Data;
+};
+
+QML_DECLARE_TYPE(ByteArrayTestData)
+
+#endif // bytearraytestdata_h
import QtTest 1.0
import QtWebKit 3.0
import QtWebKit.experimental 3.0
+import Test 1.0
WebView {
id: webView
reply.data = "<html><head><title>Should not happen</title></head><body>A test page.</body></html>"
reply.send()
}
+ },
+ UrlSchemeDelegate {
+ scheme: "schemeCharset"
+ onReceivedRequest: {
+ if (request.url == "schemecharset://latin1") {
+ reply.data = byteArrayHelper.latin1Data
+ reply.contentType = "text/html; charset=iso-8859-1"
+ } else if (request.url == "schemecharset://utf-8") {
+ reply.data = byteArrayHelper.utf8Data
+ reply.contentType = "text/html; charset=utf-8"
+ }
+ reply.send()
+ }
}
+
]
}
signalName: "titleChanged"
}
+ ByteArrayTestData {
+ id: byteArrayHelper
+ }
+
TestCase {
name: "WebViewApplicationSchemes"
compare(spyTitle.count, 2)
}
+
+ function test_charsets() {
+ spyTitle.clear()
+ compare(spyTitle.count, 0)
+ var testUrl = "schemeCharset://latin1"
+ webView.load(testUrl)
+ spyTitle.wait()
+ compare(webView.title, "title with copyright ©")
+
+ testUrl = "schemeCharset://utf-8"
+ webView.load(testUrl)
+ spyTitle.wait()
+ compare(webView.title, "title with copyright ©")
+ }
}
}
Boston, MA 02110-1301, USA.
*/
+#include "../bytearraytestdata.h"
#include "../util.h"
#include <QVarLengthArray>
// Instantiate QApplication to prevent quick_test_main to instantiate a QGuiApplication.
// This can be removed as soon as we do not use QtWidgets any more.
QApplication app(argc, argv);
+ qmlRegisterType<ByteArrayTestData>("Test", 1, 0, "ByteArrayTestData");
return quick_test_main(argc, argv, "qmltests", 0, QUICK_TEST_SOURCE_DIR);
}
VPATH += $$_PRO_FILE_PWD_
TARGET = tst_$$TARGET
+HEADERS += ../bytearraytestdata.h
+
SOURCES += $${TARGET}.cpp \
- ../util.cpp
+ ../util.cpp \
+ ../bytearraytestdata.cpp
INCLUDEPATH += $$PWD
QT += testlib declarative widgets quick
void QtNetworkReply::setReplyData(const QtNetworkReplyData& replyData)
{
- if (replyData.m_operation)
- setOperation(replyData.m_operation);
- if (!replyData.m_contentDisposition.isNull())
- setHeader(QNetworkRequest::ContentDispositionHeader, QString(replyData.m_contentDisposition));
if (!replyData.m_contentType.isNull())
setHeader(QNetworkRequest::ContentTypeHeader, QString(replyData.m_contentType));
- if (!replyData.m_location.isNull())
- setHeader(QNetworkRequest::LocationHeader, QString(replyData.m_location));
- if (replyData.m_lastModified)
- setHeader(QNetworkRequest::LastModifiedHeader, QDateTime::fromMSecsSinceEpoch(replyData.m_lastModified));
- if (!replyData.m_cookie.isNull())
- setHeader(QNetworkRequest::SetCookieHeader, QVariant::fromValue(QNetworkCookie::parseCookies(QString(replyData.m_cookie).toAscii())));
- if (!replyData.m_userAgent.isNull())
- setHeader(QNetworkRequest::UserAgentHeader, QString(replyData.m_userAgent));
- if (!replyData.m_server.isNull())
- setHeader(QNetworkRequest::ServerHeader, QString(replyData.m_server));
setHeader(QNetworkRequest::ContentLengthHeader, QVariant::fromValue(replyData.m_contentLength));
setData(replyData.m_dataHandle, replyData.m_contentLength);
}
return m_bytesAvailable + QNetworkReply::bytesAvailable();
}
-void QtNetworkReply::setHeader(QNetworkRequest::KnownHeaders header, const QVariant &value)
-{
- QNetworkReply::setHeader(header, value);
-}
-
void QtNetworkReply::abort() { }
void QtNetworkReply::close() { }
void QtNetworkReply::setReadBufferSize(qint64 size) { }
virtual qint64 readData(char *data, qint64 maxlen);
virtual qint64 bytesAvailable() const;
- void setHeader(QNetworkRequest::KnownHeaders, const QVariant &value);
- void setData(const SharedMemory::Handle&, qint64 dataSize);
void setReplyData(const QtNetworkReplyData&);
void finalize();
protected:
+ void setData(const SharedMemory::Handle&, qint64 dataSize);
+
virtual void abort();
virtual void close();
virtual void setReadBufferSize(qint64);
private:
qint64 m_bytesAvailable;
- QByteArray m_buffer;
RefPtr<SharedMemory> m_sharedMemory;
qint64 m_sharedMemorySize;
};