-
-
Notifications
You must be signed in to change notification settings - Fork 414
Description
Describe the bug
I have opened the bug downstream. maplibre/maplibre-native-qt#221
And with a bit of help I found some workarounds. It is obviously that the true solution must be found here (or even more upstream in Qt6).
To Reproduce
Steps to reproduce the behavior:
- Run the widget test with bit longer timeout
- Scroll into map
- Notice that no new tiles are requested
- See error in the console
Expected behavior
It is obvious that the user wants an interface that works.
Screenshots
./test_mln_widgets
********* Start testing of TestWidgets *********
Config: Using QtTest library 6.9.1, Qt 6.9.1 (x86_64-little_endian-lp64 shared (dynamic) release build; by GCC 10.3.1 20210422 (Red Hat 10.3.1-1)), arch unknown
PASS : TestWidgets::initTestCase()
QWARN : TestWidgets::testGLWidgetStyle() [ INFO ] "{unknown}[General]: GPU Identifier: llvmpipe (LLVM 20.1.8, 256 bits)"
QCRITICAL: TestWidgets::testGLWidgetStyle() qt.network.http2.connection: [0x7798ac05f8d0] Connection error: HEADERS on invalid stream (1)
QCRITICAL: TestWidgets::testGLWidgetStyle() qt.network.http2.connection: [0x7798ac0786c0] Connection error: HEADERS on invalid stream (1)
QCRITICAL: TestWidgets::testGLWidgetStyle() qt.network.http2.connection: [0x7798ac0736d0] Connection error: DATA on invalid stream (11)
QWARN : TestWidgets::testGLWidgetStyle() qt.network.http2: stream 13 error: "DATA on invalid stream"
QWARN : TestWidgets::testGLWidgetStyle() qt.network.http2: stream 13 finished with error: "Server dislikes our behavior, excessive load detected."
QWARN : TestWidgets::testGLWidgetStyle() qt.network.http2: stream 15 error: "DATA on invalid stream"
QWARN : TestWidgets::testGLWidgetStyle() qt.network.http2: stream 15 finished with error: "Server dislikes our behavior, excessive load detected."
QWARN : TestWidgets::testGLWidgetStyle() [ ERROR ] "{unknown}[Style]: Failed to load tile 2/2/1=>2 for source openmaptiles: HTTP status code 0"
QWARN : TestWidgets::testGLWidgetStyle() [ ERROR ] "{unknown}[Style]: Failed to load tile 2/1/1=>2 for source openmaptiles: HTTP status code 0"
** Workarounds **
- Disable HTTP/2, with HTTP/1 there are no errors.
diff --git a/platform/qt/src/mbgl/http_file_source.cpp b/platform/qt/src/mbgl/http_file_source.cpp
index 2cdb50f734b..fdada5298fe 100644
--- a/platform/qt/src/mbgl/http_file_source.cpp
+++ b/platform/qt/src/mbgl/http_file_source.cpp
@@ -37,7 +37,7 @@ void HTTPFileSource::Impl::request(HTTPRequest* req) {
networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
#endif
#endif
-
+ networkRequest.setAttribute(QNetworkRequest::Http2AllowedAttribute, false);
data.first = m_manager->get(networkRequest);
connect(data.first, &QNetworkReply::finished, this, &HTTPFileSource::Impl::onReplyFinished);
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
- Explicitly handle the errors and clear the connection Cache. The latter is the most important part.
@@ -74,6 +74,7 @@ void HTTPFileSource::Impl::cancel(HTTPRequest* req) {
void HTTPFileSource::Impl::onReplyFinished() {
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
+ if (!reply) return;
#if defined(Q_OS_WASM)
const QUrl& url = reply->url();
@@ -91,14 +92,27 @@ void HTTPFileSource::Impl::onReplyFinished() {
return;
}
- QByteArray data = reply->readAll();
- QVector<HTTPRequest*>& requestsVector = it.value().second;
+ // Error handling
+ if (reply->error() != QNetworkReply::NoError) {
+ qWarning() << "Network error for URL" << url << ":" << reply->errorString();
+
+ QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
+ if (!statusCode.isValid()) {
+ qWarning() << "No HTTP status code received; possible connection/protocol failure.";
+ }
- // Cannot use the iterator to walk the requestsVector
- // because calling handleNetworkReply() might get
- // requests added to the requestsVector.
- while (!requestsVector.isEmpty()) {
- requestsVector.takeFirst()->handleNetworkReply(reply, data);
+ m_manager->clearConnectionCache();
+ } else
+ {
+ QByteArray data = reply->readAll();
+ QVector<HTTPRequest*>& requestsVector = it.value().second;
+
+ // Cannot use the iterator to walk the requestsVector
+ // because calling handleNetworkReply() might get
+ // requests added to the requestsVector.
+ while (!requestsVector.isEmpty()) {
+ requestsVector.takeFirst()->handleNetworkReply(reply, data);
+ }
}
m_pending.erase(it);
Platform information (please complete the following information):
- Operating System: Linux
- Platform (e.g. Node.js, Qt): Qt6
- Version: 6.9.1