Fix multiple download protection for <a download> x-origin redirect
The bug: multiple downloads protection is bypassed when there are multiple
<a download> download attempts and they end up triggering a x-origin redirect
to another download.
The cause: Each x-origin redirect following the <a download> is being treated as
a navigation. (See DownloadManagerImpl::InterceptDownload() (NetworkService
enabled), DownloadResourceHandler::OnRequestRedirected() (NetworkService
disabled)). The navigation will hit
DownloadRequestLimiter::TabDownloadState::DidStartNavigation that resets some
state of the limiter, and future downloads won't be prevented.
The solution: plumb |from_download_cross_origin_redirect| to NavigationRequest,
and skip resetting the limiter state when the flag is true.
Bug: 959640
Change-Id: I7d8aca09670be5258e149e34e3e6f2f3107442ff
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1627209
Reviewed-by: Jochen Eisinger <[email protected]>
Reviewed-by: Min Qin <[email protected]>
Commit-Queue: Yao Xiao <[email protected]>
Cr-Commit-Position: refs/heads/master@{#665973}
diff --git a/content/browser/frame_host/navigation_controller_impl.cc b/content/browser/frame_host/navigation_controller_impl.cc
index f50c1283..031b30e 100644
--- a/content/browser/frame_host/navigation_controller_impl.cc
+++ b/content/browser/frame_host/navigation_controller_impl.cc
@@ -3141,10 +3141,14 @@
// extra_headers in params are \n separated; NavigationRequests want \r\n.
std::string extra_headers_crlf;
base::ReplaceChars(params.extra_headers, "\n", "\r\n", &extra_headers_crlf);
- return NavigationRequest::CreateBrowserInitiated(
+
+ auto navigation_request = NavigationRequest::CreateBrowserInitiated(
node, common_params, commit_params, !params.is_renderer_initiated,
extra_headers_crlf, *frame_entry, entry, request_body,
params.navigation_ui_data ? params.navigation_ui_data->Clone() : nullptr);
+ navigation_request->set_from_download_cross_origin_redirect(
+ params.from_download_cross_origin_redirect);
+ return navigation_request;
}
std::unique_ptr<NavigationRequest>