summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKirill Burtsev <kirill.burtsev@qt.io>2022-03-24 09:10:15 +0100
committerKirill Burtsev <kirill.burtsev@qt.io>2022-04-08 17:14:22 +0200
commit6ce62c241fbe108cd477905c16064c178215a227 (patch)
tree702e9d151160d9207fd2c23a692caa06ac5c0398
parentb3f7e2ae95ec839058a2a8f82b9b568a2e875a5e (diff)
Resolve status code for http response with failure
All non-default https status codes are hidden under net::ERR_HTTP_RESPONSE_CODE_FAILURE error of network stack. Handle successful load case and set the real http status code for error. Also set localized load error description only for http codes. Fixes: QTBUG-46860 Fixes: QTBUG-61100 Task-number: QTBUG-94963 Change-Id: I81e083441d1814fb530f39ea3da1c4ef52b7da59 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io> (cherry picked from commit a4e32eac5cb858ffa5668b01cef10cc42854713b)
-rw-r--r--src/core/web_contents_delegate_qt.cpp20
-rw-r--r--src/core/web_engine_error.cpp19
-rw-r--r--src/core/web_engine_error.h2
-rw-r--r--tests/auto/widgets/loadsignals/tst_loadsignals.cpp74
4 files changed, 89 insertions, 26 deletions
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index 885f58149..f939cba28 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -63,8 +63,6 @@
#include "web_engine_settings.h"
#include "certificate_error_controller.h"
#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
-#include "components/error_page/common/error.h"
-#include "components/error_page/common/localized_error.h"
#include "components/web_cache/browser/web_cache_manager.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
@@ -430,9 +428,11 @@ void WebContentsDelegateQt::DidFinishNavigation(content::NavigationHandle *navig
return;
// WebContentsObserver::DidFailLoad is not called any longer so we have to report the failure here.
- const net::Error error_code = navigation_handle->GetNetErrorCode();
- const std::string error_description = net::ErrorToString(error_code);
- didFailLoad(toQt(navigation_handle->GetURL()), error_code, toQt(error_description));
+ int error_code = navigation_handle->GetNetErrorCode();
+ if (error_code == net::ERR_HTTP_RESPONSE_CODE_FAILURE)
+ if (auto entry = web_contents()->GetController().GetActiveEntry())
+ error_code = entry->GetHttpStatusCode();
+ didFailLoad(toQt(navigation_handle->GetURL()), error_code, WebEngineError::toQtErrorDescription(error_code));
// The load will succede as an error-page load later, and we reported the original error above
if (navigation_handle->IsErrorPage()) {
@@ -516,12 +516,7 @@ void WebContentsDelegateQt::DidFailLoad(content::RenderFrameHost* render_frame_h
emitLoadFinished(/* isErrorPage = */true);
return;
}
- // Qt6: Consider getting rid of the error_description (Chromium already has)
- std::u16string error_description;
- error_description = error_page::LocalizedError::GetErrorDetails(
- error_code <= 0 ? error_page::Error::kNetErrorDomain : error_page::Error::kHttpErrorDomain,
- error_code, false, false);
- didFailLoad(toQt(validated_url), error_code, toQt(error_description));
+ didFailLoad(toQt(validated_url), error_code, WebEngineError::toQtErrorDescription(error_code));
}
void WebContentsDelegateQt::DidFinishLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url)
@@ -550,6 +545,7 @@ void WebContentsDelegateQt::DidFinishLoad(content::RenderFrameHost* render_frame
m_loadingInfo.success = http_statuscode < 400;
m_loadingInfo.url = toQt(validated_url);
m_loadingInfo.errorCode = http_statuscode;
+ m_loadingInfo.errorDescription = WebEngineError::toQtErrorDescription(http_statuscode);
m_loadingInfo.triggersErrorPage = triggersErrorPage;
}
@@ -753,7 +749,7 @@ void WebContentsDelegateQt::launchExternalURL(const QUrl &url, ui::PageTransitio
if (!navigationAllowedByPolicy)
errorDescription = QStringLiteral("Launching external protocol forbidden by WebEngineSettings::UnknownUrlSchemePolicy");
else
- errorDescription = QStringLiteral("Launching external protocol suppressed by WebContentsAdapterClient::navigationRequested");
+ errorDescription = QStringLiteral("Launching external protocol suppressed by 'navigationRequested' API");
didFailLoad(url, net::Error::ERR_ABORTED, errorDescription);
}
}
diff --git a/src/core/web_engine_error.cpp b/src/core/web_engine_error.cpp
index 52a84494c..a6580d76b 100644
--- a/src/core/web_engine_error.cpp
+++ b/src/core/web_engine_error.cpp
@@ -38,8 +38,17 @@
****************************************************************************/
#include "web_engine_error.h"
+
+#include "components/error_page/common/error.h"
+#include "components/error_page/common/localized_error.h"
#include "net/base/net_errors.h"
+#include "type_conversion.h"
+
+#include <QString>
+
+using namespace QtWebEngineCore;
+
const int WebEngineError::UserAbortedError = net::ERR_ABORTED;
namespace {
@@ -84,3 +93,13 @@ WebEngineError::ErrorDomain WebEngineError::toQtErrorDomain(int error_code)
else
return WebEngineError::InternalErrorDomain;
}
+
+QString WebEngineError::toQtErrorDescription(int errorCode)
+{
+ if (errorCode < 0)
+ return toQt(net::ErrorToString(errorCode));
+ else if (errorCode > 0)
+ return toQt(error_page::LocalizedError::GetErrorDetails(
+ error_page::Error::kHttpErrorDomain, errorCode, false, false));
+ return QString();
+}
diff --git a/src/core/web_engine_error.h b/src/core/web_engine_error.h
index 7277ffa9d..0ef0950ae 100644
--- a/src/core/web_engine_error.h
+++ b/src/core/web_engine_error.h
@@ -70,7 +70,7 @@ public:
static const int UserAbortedError;
static ErrorDomain toQtErrorDomain(int error_code);
-
+ static QString toQtErrorDescription(int errorCode);
};
#endif // WEB_ENGINE_ERROR_H
diff --git a/tests/auto/widgets/loadsignals/tst_loadsignals.cpp b/tests/auto/widgets/loadsignals/tst_loadsignals.cpp
index 0daf0ce05..42e23e83b 100644
--- a/tests/auto/widgets/loadsignals/tst_loadsignals.cpp
+++ b/tests/auto/widgets/loadsignals/tst_loadsignals.cpp
@@ -233,26 +233,28 @@ void tst_LoadSignals::rejectNavigationRequest_data()
QTest::addColumn<QUrl>("rejectedUrl");
QTest::addColumn<int>("expectedNavigations");
QTest::addColumn<QList<int>>("expectedSignals");
+ QTest::addColumn<int>("errorCode");
+ QTest::addColumn<QWebEngineLoadingInfo::ErrorDomain>("errorDomain");
QTest::newRow("Simple")
<< QUrl("qrc:///resources/page1.html")
<< QUrl("qrc:///resources/page1.html")
- << 1 << SignalsOrderOnceFailure;
+ << 1 << SignalsOrderOnceFailure << -3 << QWebEngineLoadingInfo::InternalErrorDomain;
QTest::newRow("SamePageImmediate")
<< QUrl("qrc:///resources/page5.html")
<< QUrl("qrc:///resources/page5.html#anchor")
- << 1 << SignalsOrderOnce;
+ << 1 << SignalsOrderOnce << 200 << QWebEngineLoadingInfo::InternalErrorDomain; // FIXME wrong error domain
QTest::newRow("SamePageDeferred")
<< QUrl("qrc:///resources/page3.html")
<< QUrl("qrc:///resources/page3.html#anchor")
- << 1 << SignalsOrderOnce;
+ << 1 << SignalsOrderOnce << 200 << QWebEngineLoadingInfo::InternalErrorDomain; // FIXME wrong error domain
QTest::newRow("OtherPageImmediate")
<< QUrl("qrc:///resources/page6.html")
<< QUrl("qrc:///resources/page2.html#anchor")
- << 2 << SignalsOrderOnceFailure;
+ << 2 << SignalsOrderOnceFailure << -3 << QWebEngineLoadingInfo::InternalErrorDomain;
QTest::newRow("OtherPageDeferred")
<< QUrl("qrc:///resources/page7.html")
<< QUrl("qrc:///resources/page2.html#anchor")
- << 2 << SignalsOrderTwiceWithFailure;
+ << 2 << SignalsOrderTwiceWithFailure << -3 << QWebEngineLoadingInfo::InternalErrorDomain;
}
/**
@@ -267,6 +269,8 @@ void tst_LoadSignals::rejectNavigationRequest()
QFETCH(QUrl, rejectedUrl);
QFETCH(int, expectedNavigations);
QFETCH(QList<int>, expectedSignals);
+ QFETCH(int, errorCode);
+ QFETCH(QWebEngineLoadingInfo::ErrorDomain, errorDomain);
page.blacklist.insert(rejectedUrl);
page.load(initialUrl);
@@ -281,6 +285,8 @@ void tst_LoadSignals::rejectNavigationRequest()
// No further loadStarted should have occurred within this time
QCOMPARE(loadStartedSpy.size(), expectedLoadCount);
QCOMPARE(loadFinishedSpy.size(), expectedLoadCount);
+ QCOMPARE(page.loadingInfos.last().errorCode(), errorCode);
+ QCOMPARE(page.loadingInfos.last().errorDomain(), errorDomain);
}
/**
@@ -368,6 +374,8 @@ void tst_LoadSignals::fileDownload()
QTRY_LOOP_IMPL(loadStartedSpy.size() != 2 || loadFinishedSpy.size() != 2, 1000, 100);
QCOMPARE(page.signalsOrder, SignalsOrderTwiceWithFailure);
+ QCOMPARE(page.loadingInfos[3].errorCode(), -3);
+ QCOMPARE(page.loadingInfos[3].errorDomain(), QWebEngineLoadingInfo::InternalErrorDomain);
}
void tst_LoadSignals::numberOfStartedAndFinishedSignalsIsSame_data()
@@ -406,21 +414,27 @@ void tst_LoadSignals::numberOfStartedAndFinishedSignalsIsSame()
resetSpies();
QTRY_LOOP_IMPL(loadStartedSpy.size() || loadFinishedSpy.size(), 1000, 100);
QCOMPARE(page.signalsOrder, SignalsOrderOnce);
+ QCOMPARE(page.loadingInfos[1].errorCode(), 200);
+ QCOMPARE(page.loadingInfos[1].errorDomain(), QWebEngineLoadingInfo::InternalErrorDomain); // FIXME should be no error or separate domain?
}
void tst_LoadSignals::loadFinishedAfterNotFoundError_data()
{
QTest::addColumn<bool>("rfcInvalid");
QTest::addColumn<bool>("withServer");
- QTest::addRow("rfc_invalid") << true << false;
- QTest::addRow("non_existent") << false << false;
- QTest::addRow("server_404") << false << true;
+ QTest::addColumn<int>("errorCode");
+ QTest::addColumn<int>("errorDomain");
+ QTest::addRow("rfc_invalid") << true << false << -105 << int(QWebEngineLoadingInfo::ConnectionErrorDomain);
+ QTest::addRow("non_existent") << false << false << -105 << int(QWebEngineLoadingInfo::ConnectionErrorDomain);
+ QTest::addRow("server_404") << false << true << 404 << int(QWebEngineLoadingInfo::InternalErrorDomain); // FIXME should be no error or separate domain?
}
void tst_LoadSignals::loadFinishedAfterNotFoundError()
{
- QFETCH(bool, withServer);
QFETCH(bool, rfcInvalid);
+ QFETCH(bool, withServer);
+ QFETCH(int, errorCode);
+ QFETCH(int, errorDomain);
QScopedPointer<HttpServer> server;
if (withServer) {
@@ -440,6 +454,19 @@ void tst_LoadSignals::loadFinishedAfterNotFoundError()
QVERIFY(std::is_sorted(page.loadProgress.begin(), page.loadProgress.end()));
page.loadProgress.clear();
+ { auto &&loadStart = page.loadingInfos[0], &&loadFinish = page.loadingInfos[1];
+ QCOMPARE(loadStart.status(), QWebEngineLoadingInfo::LoadStartedStatus);
+ QCOMPARE(loadStart.isErrorPage(), false);
+ QCOMPARE(loadStart.errorCode(), 0);
+ QCOMPARE(loadStart.errorDomain(), QWebEngineLoadingInfo::NoErrorDomain);
+ QCOMPARE(loadStart.errorString(), QString());
+ QCOMPARE(loadFinish.status(), QWebEngineLoadingInfo::LoadFailedStatus);
+ QCOMPARE(loadFinish.isErrorPage(), false);
+ QCOMPARE(loadFinish.errorCode(), errorCode);
+ QCOMPARE(loadFinish.errorDomain(), errorDomain);
+ QVERIFY(!loadFinish.errorString().isEmpty());
+ }
+
view.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, true);
url = server
? server->url("/another-missing-one.html")
@@ -453,6 +480,19 @@ void tst_LoadSignals::loadFinishedAfterNotFoundError()
QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 3, 1000);
QCOMPARE(loadStartedSpy.count(), 2);
QVERIFY(std::is_sorted(page.loadProgress.begin(), page.loadProgress.end()));
+
+ { auto &&loadStart = page.loadingInfos[2], &&loadFinish = page.loadingInfos[3];
+ QCOMPARE(loadStart.status(), QWebEngineLoadingInfo::LoadStartedStatus);
+ QCOMPARE(loadStart.isErrorPage(), false);
+ QCOMPARE(loadStart.errorCode(), 0);
+ QCOMPARE(loadStart.errorDomain(), QWebEngineLoadingInfo::NoErrorDomain);
+ QCOMPARE(loadStart.errorString(), QString());
+ QCOMPARE(loadFinish.status(), QWebEngineLoadingInfo::LoadFailedStatus);
+ QCOMPARE(loadFinish.isErrorPage(), true);
+ QCOMPARE(loadFinish.errorCode(), errorCode);
+ QCOMPARE(loadFinish.errorDomain(), errorDomain);
+ QVERIFY(!loadFinish.errorString().isEmpty());
+ }
}
void tst_LoadSignals::errorPageTriggered_data()
@@ -460,10 +500,12 @@ void tst_LoadSignals::errorPageTriggered_data()
QTest::addColumn<QString>("urlPath");
QTest::addColumn<bool>("loadSucceed");
QTest::addColumn<bool>("triggersErrorPage");
- QTest::newRow("/content/200") << QStringLiteral("/content/200") << true << false;
- QTest::newRow("/empty/200") << QStringLiteral("/content/200") << true << false;
- QTest::newRow("/content/404") << QStringLiteral("/content/404") << false << false;
- QTest::newRow("/empty/404") << QStringLiteral("/empty/404") << false << true;
+ QTest::addColumn<int>("errorCode");
+ QTest::addColumn<QWebEngineLoadingInfo::ErrorDomain>("errorDomain");
+ QTest::newRow("/content/200") << QStringLiteral("/content/200") << true << false << 200 << QWebEngineLoadingInfo::InternalErrorDomain; // FIXME ?
+ QTest::newRow("/empty/200") << QStringLiteral("/content/200") << true << false << 200 << QWebEngineLoadingInfo::InternalErrorDomain; // no error
+ QTest::newRow("/content/404") << QStringLiteral("/content/404") << false << false << 404 << QWebEngineLoadingInfo::InternalErrorDomain; // or
+ QTest::newRow("/empty/404") << QStringLiteral("/empty/404") << false << true << 404 << QWebEngineLoadingInfo::InternalErrorDomain; // separate domain?
}
void tst_LoadSignals::errorPageTriggered()
@@ -490,6 +532,8 @@ void tst_LoadSignals::errorPageTriggered()
QFETCH(QString, urlPath);
QFETCH(bool, loadSucceed);
QFETCH(bool, triggersErrorPage);
+ QFETCH(int, errorCode);
+ QFETCH(QWebEngineLoadingInfo::ErrorDomain, errorDomain);
view.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, true);
view.load(server.url(urlPath));
@@ -499,6 +543,8 @@ void tst_LoadSignals::errorPageTriggered()
QVERIFY(toPlainTextSync(view.page()).contains("HTTP ERROR 404"));
else
QVERIFY(toPlainTextSync(view.page()).isEmpty());
+ QCOMPARE(page.loadingInfos[1].errorCode(), errorCode);
+ QCOMPARE(page.loadingInfos[1].errorDomain(), errorDomain);
loadFinishedSpy.clear();
view.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
@@ -506,6 +552,8 @@ void tst_LoadSignals::errorPageTriggered()
QTRY_COMPARE(loadFinishedSpy.size(), 1);
QCOMPARE(loadFinishedSpy[0][0].toBool(), loadSucceed);
QVERIFY(toPlainTextSync(view.page()).isEmpty());
+ QCOMPARE(page.loadingInfos[3].errorCode(), errorCode);
+ QCOMPARE(page.loadingInfos[3].errorDomain(), errorDomain);
loadFinishedSpy.clear();
}