aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2018-05-23 12:28:46 +0200
committerJani Heikkinen <jani.heikkinen@qt.io>2018-05-25 06:30:41 +0000
commit8556133d620e7b64076d7b73de00451e16545c3b (patch)
tree2852c66e13dc166f21ce6a1576cdd551c8f15ae0
parent047e3f480e9ebed55b21025f19ed7ed7351df118 (diff)
On network redirects, update finalUrl, not url
We want all further imports to be relative to the redirected URL, not the base one. Note that this will incorporate any prior URL interceptions into the final URL if a redirect happens. We don't really want this to happen because the result of interception is not meant to be the base for further URL lookup. However, as interception occurs before redirection, this is unavoidable. Don't use URL interceptors on remote URLs. Task-number: QTBUG-67882 Change-Id: I6693d14c8af8212dda9954d0bd0293c3c85441ef (cherry picked from commit cda2680d801acce4e221b23e88d9b3c5504f86e8) Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
-rw-r--r--src/qml/qml/qqmltypeloader.cpp19
-rw-r--r--tests/auto/qml/qqmltypeloader/data/Base.qml3
-rw-r--r--tests/auto/qml/qqmltypeloader/data/Load.qml11
-rw-r--r--tests/auto/qml/qqmltypeloader/data/redirected/Imported.qml5
-rw-r--r--tests/auto/qml/qqmltypeloader/data/redirected/Redirected.qml5
-rw-r--r--tests/auto/qml/qqmltypeloader/data/redirected/qmldir1
-rw-r--r--tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp18
-rw-r--r--tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.pro7
8 files changed, 60 insertions, 9 deletions
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index afcb9cdbe9..339ede461a 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -357,9 +357,8 @@ qreal QQmlDataBlob::progress() const
/*!
Returns the physical url of the data. Initially this is the same as
-finalUrl(), but if a network redirect happens while fetching the data, this url
-is updated to reflect the new location. Also, if a URL interceptor is set, it
-will work on this URL and leave finalUrl() alone.
+finalUrl(), but if a URL interceptor is set, it will work on this URL
+and leave finalUrl() alone.
\sa finalUrl()
*/
@@ -380,8 +379,12 @@ QString QQmlDataBlob::urlString() const
Returns the logical URL to be used for resolving further URLs referred to in
the code.
-This is the blob url passed to the constructor. If a network redirect
-happens while fetching the data, this url remains the same.
+This is the blob url passed to the constructor. If a URL interceptor rewrites
+the URL, this one stays the same. If a network redirect happens while fetching
+the data, this url is updated to reflect the new location. Therefore, if both
+an interception and a redirection happen, the final url will indirectly
+incorporate the result of the interception, potentially breaking further
+lookups.
\sa url()
*/
@@ -1195,15 +1198,15 @@ void QQmlTypeLoader::networkReplyFinished(QNetworkReply *reply)
QVariant redirect = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
if (redirect.isValid()) {
QUrl url = reply->url().resolved(redirect.toUrl());
- blob->m_url = url;
- blob->m_urlString.clear();
+ blob->m_finalUrl = url;
+ blob->m_finalUrlString.clear();
QNetworkReply *reply = m_thread->networkAccessManager()->get(QNetworkRequest(url));
QObject *nrp = m_thread->networkReplyProxy();
QObject::connect(reply, SIGNAL(finished()), nrp, SLOT(finished()));
m_networkReplies.insert(reply, blob);
#ifdef DATABLOB_DEBUG
- qWarning("QQmlDataBlob: redirected to %s", qPrintable(blob->urlString()));
+ qWarning("QQmlDataBlob: redirected to %s", qPrintable(blob->finalUrlString()));
#endif
return;
}
diff --git a/tests/auto/qml/qqmltypeloader/data/Base.qml b/tests/auto/qml/qqmltypeloader/data/Base.qml
new file mode 100644
index 0000000000..431c659424
--- /dev/null
+++ b/tests/auto/qml/qqmltypeloader/data/Base.qml
@@ -0,0 +1,3 @@
+import QtQml 2.0
+
+QtObject {}
diff --git a/tests/auto/qml/qqmltypeloader/data/Load.qml b/tests/auto/qml/qqmltypeloader/data/Load.qml
new file mode 100644
index 0000000000..0b893bb5cd
--- /dev/null
+++ b/tests/auto/qml/qqmltypeloader/data/Load.qml
@@ -0,0 +1,11 @@
+import QtQuick 2.0
+
+Item {
+ property int xy: loader.xy
+ Loader {
+ id: loader
+ asynchronous: true
+ source: 'Base.qml'
+ property int xy: item.xy
+ }
+}
diff --git a/tests/auto/qml/qqmltypeloader/data/redirected/Imported.qml b/tests/auto/qml/qqmltypeloader/data/redirected/Imported.qml
new file mode 100644
index 0000000000..62954fe1b2
--- /dev/null
+++ b/tests/auto/qml/qqmltypeloader/data/redirected/Imported.qml
@@ -0,0 +1,5 @@
+import QtQml 2.0
+
+QtObject {
+ property int xy: 323232
+}
diff --git a/tests/auto/qml/qqmltypeloader/data/redirected/Redirected.qml b/tests/auto/qml/qqmltypeloader/data/redirected/Redirected.qml
new file mode 100644
index 0000000000..40fec5ed31
--- /dev/null
+++ b/tests/auto/qml/qqmltypeloader/data/redirected/Redirected.qml
@@ -0,0 +1,5 @@
+import QtQml 2.0
+
+Imported {
+
+}
diff --git a/tests/auto/qml/qqmltypeloader/data/redirected/qmldir b/tests/auto/qml/qqmltypeloader/data/redirected/qmldir
new file mode 100644
index 0000000000..8eb1fa5c18
--- /dev/null
+++ b/tests/auto/qml/qqmltypeloader/data/redirected/qmldir
@@ -0,0 +1 @@
+Imported 1.0 Imported.qml
diff --git a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp
index 5a3d76e903..e00d08183f 100644
--- a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp
+++ b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp
@@ -33,6 +33,7 @@
#include <QtQuick/qquickitem.h>
#include <QtQml/private/qqmlengine_p.h>
#include <QtQml/private/qqmltypeloader_p.h>
+#include "../../shared/testhttpserver.h"
#include "../../shared/util.h"
class tst_QQMLTypeLoader : public QQmlDataTest
@@ -48,6 +49,7 @@ private slots:
void keepSingleton();
void keepRegistrations();
void intercept();
+ void redirect();
};
void tst_QQMLTypeLoader::testLoadComplete()
@@ -410,6 +412,22 @@ void tst_QQMLTypeLoader::intercept()
QVERIFY(factory.loadedFiles.contains(QLatin1String(QT_TESTCASE_BUILDDIR) + "/Slow/qmldir"));
}
+void tst_QQMLTypeLoader::redirect()
+{
+ TestHTTPServer server;
+ QVERIFY2(server.listen(), qPrintable(server.errorString()));
+ QVERIFY(server.serveDirectory(dataDirectory()));
+ server.addRedirect("Base.qml", server.urlString("/redirected/Redirected.qml"));
+
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.loadUrl(server.urlString("/Load.qml"), QQmlComponent::Asynchronous);
+ QTRY_VERIFY2(component.isReady(), qPrintable(component.errorString()));
+
+ QObject *object = component.create();
+ QTRY_COMPARE(object->property("xy").toInt(), 323232);
+}
+
QTEST_MAIN(tst_QQMLTypeLoader)
#include "tst_qqmltypeloader.moc"
diff --git a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.pro b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.pro
index 3a20e94741..0352561e03 100644
--- a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.pro
+++ b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.pro
@@ -3,7 +3,12 @@ TARGET = tst_qqmltypeloader
QT += qml testlib qml-private quick
macx:CONFIG -= app_bundle
-SOURCES += tst_qqmltypeloader.cpp
+SOURCES += \
+ tst_qqmltypeloader.cpp \
+ ../../shared/testhttpserver.cpp
+
+HEADERS += \
+ ../../shared/testhttpserver.h
include (../../shared/util.pri)