From 73ae71cbd1937ef1e2a1ba888a4802792fe6d738 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCri=20Valdmann?= Date: Tue, 20 Jun 2017 10:19:56 +0200 Subject: Set referrer on download requests Note that the Referer header still won't be sent if the download is triggered via an anchor element with the 'download' attribute: crbug.com/455987 . Task-number: QTBUG-61354 Change-Id: I5af971af916b2190756e3e58f19736072a213922 Reviewed-by: Michal Klocek --- src/core/web_contents_adapter.cpp | 25 +++++++++++++++-- src/core/web_contents_adapter.h | 4 ++- src/core/web_contents_adapter_client.h | 42 +++++++++++++++++++++++++++++ src/core/web_contents_view_qt.cpp | 3 +++ src/webengine/api/qquickwebengineview.cpp | 6 +++-- src/webenginewidgets/api/qwebenginepage.cpp | 7 +++-- 6 files changed, 80 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp index 9c78d67a0..6c1e6c721 100644 --- a/src/core/web_contents_adapter.cpp +++ b/src/core/web_contents_adapter.cpp @@ -928,7 +928,9 @@ void WebContentsAdapter::updateWebPreferences(const content::WebPreferences & we d->webContents->GetRenderViewHost()->UpdateWebkitPreferences(webPreferences); } -void WebContentsAdapter::download(const QUrl &url, const QString &suggestedFileName) +void WebContentsAdapter::download(const QUrl &url, const QString &suggestedFileName, + const QUrl &referrerUrl, + ReferrerPolicy referrerPolicy) { Q_D(WebContentsAdapter); content::BrowserContext *bctx = webContents()->GetBrowserContext(); @@ -941,9 +943,19 @@ void WebContentsAdapter::download(const QUrl &url, const QString &suggestedFileN dlmd->setDownloadType(BrowserContextAdapterClient::UserRequested); dlm->SetDelegate(dlmd); + GURL gurl = toGurl(url); std::unique_ptr params( - content::DownloadUrlParameters::CreateForWebContentsMainFrame(webContents(), toGurl(url))); + content::DownloadUrlParameters::CreateForWebContentsMainFrame(webContents(), gurl)); + params->set_suggested_name(toString16(suggestedFileName)); + + // referrer logic based on chrome/browser/renderer_context_menu/render_view_context_menu.cc: + params->set_referrer( + content::Referrer::SanitizeForRequest( + gurl, + content::Referrer(toGurl(referrerUrl).GetAsReferrer(), + static_cast(referrerPolicy)))); + dlm->DownloadUrl(std::move(params)); } @@ -1476,4 +1488,13 @@ ASSERT_ENUMS_MATCH(WebContentsAdapterClient::SaveToDiskDisposition, WindowOpenDi ASSERT_ENUMS_MATCH(WebContentsAdapterClient::OffTheRecordDisposition, WindowOpenDisposition::OFF_THE_RECORD) ASSERT_ENUMS_MATCH(WebContentsAdapterClient::IgnoreActionDisposition, WindowOpenDisposition::IGNORE_ACTION) +ASSERT_ENUMS_MATCH(ReferrerPolicy::Always, blink::WebReferrerPolicyAlways) +ASSERT_ENUMS_MATCH(ReferrerPolicy::Default, blink::WebReferrerPolicyDefault) +ASSERT_ENUMS_MATCH(ReferrerPolicy::NoReferrerWhenDowngrade, blink::WebReferrerPolicyNoReferrerWhenDowngrade) +ASSERT_ENUMS_MATCH(ReferrerPolicy::Never, blink::WebReferrerPolicyNever) +ASSERT_ENUMS_MATCH(ReferrerPolicy::Origin, blink::WebReferrerPolicyOrigin) +ASSERT_ENUMS_MATCH(ReferrerPolicy::OriginWhenCrossOrigin, blink::WebReferrerPolicyOriginWhenCrossOrigin) +ASSERT_ENUMS_MATCH(ReferrerPolicy::NoReferrerWhenDowngradeOriginWhenCrossOrigin, blink::WebReferrerPolicyNoReferrerWhenDowngradeOriginWhenCrossOrigin) +ASSERT_ENUMS_MATCH(ReferrerPolicy::Last, blink::WebReferrerPolicyLast) + } // namespace QtWebEngineCore diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h index 46c8d2604..67fcbe7af 100644 --- a/src/core/web_contents_adapter.h +++ b/src/core/web_contents_adapter.h @@ -124,7 +124,9 @@ public: quint64 findText(const QString &subString, bool caseSensitively, bool findBackward); void stopFinding(); void updateWebPreferences(const content::WebPreferences &webPreferences); - void download(const QUrl &url, const QString &suggestedFileName); + void download(const QUrl &url, const QString &suggestedFileName, + const QUrl &referrerUrl = QUrl(), + ReferrerPolicy referrerPolicy = ReferrerPolicy::Default); bool isAudioMuted() const; void setAudioMuted(bool mute); bool recentlyAudible(); diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h index e1fb3dc4c..3cc5350df 100644 --- a/src/core/web_contents_adapter_client.h +++ b/src/core/web_contents_adapter_client.h @@ -71,6 +71,17 @@ class WebContentsAdapter; class WebContentsDelegateQt; class WebEngineSettings; +// Must match blink::WebReferrerPolicy +enum class ReferrerPolicy { + Always, + Default, + NoReferrerWhenDowngrade, + Never, + Origin, + OriginWhenCrossOrigin, + NoReferrerWhenDowngradeOriginWhenCrossOrigin, + Last = NoReferrerWhenDowngradeOriginWhenCrossOrigin, +}; class WebEngineContextMenuSharedData : public QSharedData { @@ -96,6 +107,9 @@ public: QString suggestedFileName; QString misspelledWord; QStringList spellCheckerSuggestions; + QUrl pageUrl; + QUrl frameUrl; + ReferrerPolicy referrerPolicy = ReferrerPolicy::Default; // Some likely candidates for future additions as we add support for the related actions: // bool isImageBlocked; // mediaType; @@ -244,6 +258,34 @@ public: return d->spellCheckerSuggestions; } + void setFrameUrl(const QUrl &url) { + d->frameUrl = url; + } + + QUrl frameUrl() const { + return d->frameUrl; + } + + void setPageUrl(const QUrl &url) { + d->pageUrl = url; + } + + QUrl pageUrl() const { + return d->pageUrl; + } + + QUrl referrerUrl() const { + return !d->frameUrl.isEmpty() ? d->frameUrl : d->pageUrl; + } + + void setReferrerPolicy(ReferrerPolicy referrerPolicy) { + d->referrerPolicy = referrerPolicy; + } + + ReferrerPolicy referrerPolicy() const { + return d->referrerPolicy; + } + private: QSharedDataPointer d; }; diff --git a/src/core/web_contents_view_qt.cpp b/src/core/web_contents_view_qt.cpp index 844544887..86e839a7f 100644 --- a/src/core/web_contents_view_qt.cpp +++ b/src/core/web_contents_view_qt.cpp @@ -175,6 +175,9 @@ static inline WebEngineContextMenuData fromParams(const content::ContextMenuPara ret.setMisspelledWord(toQt(params.misspelled_word)); ret.setSpellCheckerSuggestions(fromVector(params.dictionary_suggestions)); #endif + ret.setFrameUrl(toQt(params.frame_url)); + ret.setPageUrl(toQt(params.page_url)); + ret.setReferrerPolicy((ReferrerPolicy)params.referrer_policy); return ret; } diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp index ae75b7f34..53f4f5855 100644 --- a/src/webengine/api/qquickwebengineview.cpp +++ b/src/webengine/api/qquickwebengineview.cpp @@ -1619,7 +1619,8 @@ void QQuickWebEngineView::triggerWebAction(WebAction action) break; case DownloadLinkToDisk: if (d->m_contextMenuData.linkUrl().isValid()) - d->adapter->download(d->m_contextMenuData.linkUrl(), d->m_contextMenuData.suggestedFileName()); + d->adapter->download(d->m_contextMenuData.linkUrl(), d->m_contextMenuData.suggestedFileName(), + d->m_contextMenuData.referrerUrl(), d->m_contextMenuData.referrerPolicy()); break; case CopyImageToClipboard: if (d->m_contextMenuData.hasImageContent() && @@ -1646,7 +1647,8 @@ void QQuickWebEngineView::triggerWebAction(WebAction action) case DownloadImageToDisk: case DownloadMediaToDisk: if (d->m_contextMenuData.mediaUrl().isValid()) - d->adapter->download(d->m_contextMenuData.mediaUrl(), d->m_contextMenuData.suggestedFileName()); + d->adapter->download(d->m_contextMenuData.mediaUrl(), d->m_contextMenuData.suggestedFileName(), + d->m_contextMenuData.referrerUrl(), d->m_contextMenuData.referrerPolicy()); break; case CopyMediaUrlToClipboard: if (d->m_contextMenuData.mediaUrl().isValid() && diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp index 70f5984c7..c583c7f51 100644 --- a/src/webenginewidgets/api/qwebenginepage.cpp +++ b/src/webenginewidgets/api/qwebenginepage.cpp @@ -1242,7 +1242,9 @@ void QWebEnginePage::triggerAction(WebAction action, bool) break; case DownloadLinkToDisk: if (menuData.linkUrl().isValid()) - d->adapter->download(menuData.linkUrl(), menuData.suggestedFileName()); + d->adapter->download(menuData.linkUrl(), menuData.suggestedFileName(), + menuData.referrerUrl(), menuData.referrerPolicy()); + break; case CopyImageToClipboard: if (menuData.hasImageContent() && @@ -1269,7 +1271,8 @@ void QWebEnginePage::triggerAction(WebAction action, bool) case DownloadImageToDisk: case DownloadMediaToDisk: if (menuData.mediaUrl().isValid()) - d->adapter->download(menuData.mediaUrl(), menuData.suggestedFileName()); + d->adapter->download(menuData.mediaUrl(), menuData.suggestedFileName(), + menuData.referrerUrl(), menuData.referrerPolicy()); break; case CopyMediaUrlToClipboard: if (menuData.mediaUrl().isValid() && -- cgit v1.2.3