diff options
author | Kirill Burtsev <kirill.burtsev@qt.io> | 2022-03-24 09:10:15 +0100 |
---|---|---|
committer | Kirill Burtsev <kirill.burtsev@qt.io> | 2022-04-08 17:14:22 +0200 |
commit | 6ce62c241fbe108cd477905c16064c178215a227 (patch) | |
tree | 702e9d151160d9207fd2c23a692caa06ac5c0398 | |
parent | b3f7e2ae95ec839058a2a8f82b9b568a2e875a5e (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.cpp | 20 | ||||
-rw-r--r-- | src/core/web_engine_error.cpp | 19 | ||||
-rw-r--r-- | src/core/web_engine_error.h | 2 | ||||
-rw-r--r-- | tests/auto/widgets/loadsignals/tst_loadsignals.cpp | 74 |
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(); } |