diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-12 14:27:29 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-13 09:35:20 +0000 |
commit | c30a6232df03e1efbd9f3b226777b07e087a1122 (patch) | |
tree | e992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/content/browser/download/save_package.cc | |
parent | 7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff) | |
download | qtwebengine-chromium-85-based.tar.gz |
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/content/browser/download/save_package.cc')
-rw-r--r-- | chromium/content/browser/download/save_package.cc | 163 |
1 files changed, 99 insertions, 64 deletions
diff --git a/chromium/content/browser/download/save_package.cc b/chromium/content/browser/download/save_package.cc index 278d062ad56..03244edd05f 100644 --- a/chromium/content/browser/download/save_package.cc +++ b/chromium/content/browser/download/save_package.cc @@ -8,6 +8,7 @@ #include <utility> #include "base/bind.h" +#include "base/containers/flat_map.h" #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/i18n/file_util_icu.h" @@ -23,6 +24,7 @@ #include "base/task_runner_util.h" #include "base/threading/thread.h" #include "base/threading/thread_restrictions.h" +#include "base/unguessable_token.h" #include "build/build_config.h" #include "components/download/public/common/download_item_impl.h" #include "components/download/public/common/download_stats.h" @@ -36,6 +38,7 @@ #include "content/browser/download/save_file.h" #include "content/browser/download/save_file_manager.h" #include "content/browser/download/save_item.h" +#include "content/browser/download/save_package_serialization_handler.h" #include "content/browser/frame_host/frame_tree.h" #include "content/browser/frame_host/frame_tree_node.h" #include "content/browser/frame_host/render_frame_host_impl.h" @@ -56,6 +59,9 @@ #include "content/public/browser/resource_context.h" #include "content/public/browser/web_contents.h" #include "content/public/common/mhtml_generation_params.h" +#include "content/public/common/referrer_type_converters.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/self_owned_receiver.h" #include "net/base/filename_util.h" #include "net/base/io_buffer.h" #include "net/base/mime_util.h" @@ -914,22 +920,6 @@ void SavePackage::DoSavingProcess() { } } -bool SavePackage::OnMessageReceived(const IPC::Message& message, - RenderFrameHost* render_frame_host) { - bool handled = true; - auto* rfhi = static_cast<RenderFrameHostImpl*>(render_frame_host); - IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(SavePackage, message, rfhi) - IPC_MESSAGE_HANDLER(FrameHostMsg_SavableResourceLinksResponse, - OnSavableResourceLinksResponse) - IPC_MESSAGE_HANDLER(FrameHostMsg_SavableResourceLinksError, - OnSavableResourceLinksError) - IPC_MESSAGE_HANDLER(FrameHostMsg_SerializedHtmlWithLocalLinksResponse, - OnSerializedHtmlWithLocalLinksResponse) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled; -} - // After finishing all SaveItems which need to get data from net. // We collect all URLs which have local storage and send the // map:(originalURL:currentLocalPath) to render process (backend). @@ -956,7 +946,7 @@ void SavePackage::GetSerializedHtmlWithLocalLinks() { DCHECK_EQ(0, number_of_frames_pending_response_); FrameTree* frame_tree = static_cast<RenderFrameHostImpl*>(web_contents()->GetMainFrame()) - ->frame_tree_node()->frame_tree(); + ->frame_tree(); for (const auto& item : frame_tree_node_id_to_save_item_) { int frame_tree_node_id = item.first; const SaveItem* save_item = item.second; @@ -993,8 +983,10 @@ void SavePackage::GetSerializedHtmlWithLocalLinksForFrame( // SECURITY NOTE: We don't send *all* urls / local paths, but only // those that the given frame had access to already (because it contained // the savable resources / subframes associated with save items). - std::map<GURL, base::FilePath> url_to_local_path; - std::map<int, base::FilePath> routing_id_to_local_path; + base::flat_map<GURL, base::FilePath> url_to_local_path; + base::flat_map<base::UnguessableToken, base::FilePath> + frame_token_to_local_path; + auto it = frame_tree_node_id_to_contained_save_items_.find( target_frame_tree_node_id); if (it != frame_tree_node_id_to_contained_save_items_.end()) { @@ -1013,7 +1005,8 @@ void SavePackage::GetSerializedHtmlWithLocalLinksForFrame( } local_path = local_path.Append(save_item->full_path().BaseName()); - // Insert the link into |url_to_local_path| or |routing_id_to_local_path|. + // Insert the link into |url_to_local_path| or + // |frame_token_to_local_path|. if (save_item->save_source() != SaveFileCreateInfo::SAVE_FILE_FROM_DOM) { DCHECK_EQ(FrameTreeNode::kFrameTreeNodeInvalidId, save_item->frame_tree_node_id()); @@ -1027,43 +1020,52 @@ void SavePackage::GetSerializedHtmlWithLocalLinksForFrame( continue; } - int routing_id = + base::Optional<base::UnguessableToken> frame_token = save_item_frame_tree_node->render_manager() - ->GetRoutingIdForSiteInstance(target->GetSiteInstance()); - DCHECK_NE(MSG_ROUTING_NONE, routing_id); + ->GetFrameTokenForSiteInstance(target->GetSiteInstance()); - routing_id_to_local_path[routing_id] = local_path; + DCHECK(frame_token.has_value()); + + frame_token_to_local_path[frame_token.value()] = local_path; } } } + // Create a SavePackageSerializationHandler for the target RenderFrameHost + // plus the required callbacks to report progress, and make it owned by a mojo + // receiver that will be alive for the time that the serialization process is + // in progress. It's expected that the Done() callback will be called right + // after the last time the DidReceiveData() callback gets invoked, at which + // point the remote end of the pipe will be closed, disposing the receiver. + mojo::PendingRemote<mojom::FrameHTMLSerializerHandler> serializer_handler; + mojo::MakeSelfOwnedReceiver( + std::make_unique<SavePackageSerializationHandler>( + base::BindRepeating(&SavePackage::OnDidReceiveSerializedHtmlData, + AsWeakPtr(), target->GetWeakPtr()), + base::BindOnce(&SavePackage::OnDidFinishedSerializingHtmlData, + AsWeakPtr(), target->GetWeakPtr())), + serializer_handler.InitWithNewPipeAndPassReceiver()); + // Ask target frame to serialize itself. - target->Send(new FrameMsg_GetSerializedHtmlWithLocalLinks( - target->GetRoutingID(), url_to_local_path, routing_id_to_local_path, - web_contents()->GetBrowserContext()->IsOffTheRecord())); + target->GetSerializedHtmlWithLocalLinks( + url_to_local_path, frame_token_to_local_path, + web_contents()->GetBrowserContext()->IsOffTheRecord(), + std::move(serializer_handler)); } -// Process the serialized HTML content data of a specified frame -// retrieved from the renderer process. -void SavePackage::OnSerializedHtmlWithLocalLinksResponse( - RenderFrameHostImpl* sender, - const std::string& data, - bool end_of_data) { +void SavePackage::OnDidReceiveSerializedHtmlData( + base::WeakPtr<RenderFrameHostImpl> sender, + const std::string& data) { DCHECK_CURRENTLY_ON(BrowserThread::UI); // Check current state. - if (wait_state_ != HTML_DATA) + if (!sender || wait_state_ != HTML_DATA) return; - int frame_tree_node_id = sender->frame_tree_node()->frame_tree_node_id(); - auto it = frame_tree_node_id_to_save_item_.find(frame_tree_node_id); - if (it == frame_tree_node_id_to_save_item_.end()) { - // This is parimarily sanitization of IPC (renderer shouldn't send - // OnSerializedHtmlFragment IPC without being asked to), but it might also - // occur in the wild (if old renderer response reaches a new SavePackage). - return; - } - const SaveItem* save_item = it->second; - DCHECK_EQ(SaveFileCreateInfo::SAVE_FILE_FROM_DOM, save_item->save_source()); + // This method can only get called as a response to the serialization request + // previously sent from the browser to the renderer for a given FrameTreeNode. + const SaveItem* save_item = LookupSaveItemForSender(sender); + DCHECK(save_item); + if (save_item->state() != SaveItem::IN_PROGRESS) { for (const auto& saved_it : saved_success_items_) { if (saved_it.second->url() == save_item->url()) { @@ -1084,17 +1086,44 @@ void SavePackage::OnSerializedHtmlWithLocalLinksResponse( FROM_HERE, base::BindOnce(&SaveFileManager::UpdateSaveProgress, file_manager_, save_item->id(), data)); } +} + +void SavePackage::OnDidFinishedSerializingHtmlData( + base::WeakPtr<RenderFrameHostImpl> sender) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + // Check current state. + if (!sender || wait_state_ != HTML_DATA) + return; + + // This method can only get called as a response to the serialization request + // previously sent from the browser to the renderer for a given FrameTreeNode. + const SaveItem* save_item = LookupSaveItemForSender(sender); + DCHECK(save_item); // Current frame is completed saving, call finish in download sequence. - if (end_of_data) { - DVLOG(20) << __func__ << "() save_item_id = " << save_item->id() - << " url = \"" << save_item->url().spec() << "\""; - download::GetDownloadTaskRunner()->PostTask( - FROM_HERE, base::BindOnce(&SaveFileManager::SaveFinished, file_manager_, - save_item->id(), id(), true)); - number_of_frames_pending_response_--; - DCHECK_LE(0, number_of_frames_pending_response_); - } + DVLOG(20) << __func__ << "() save_item_id = " << save_item->id() + << " url = \"" << save_item->url().spec() << "\""; + download::GetDownloadTaskRunner()->PostTask( + FROM_HERE, base::BindOnce(&SaveFileManager::SaveFinished, file_manager_, + save_item->id(), id(), true)); + number_of_frames_pending_response_--; + DCHECK_LE(0, number_of_frames_pending_response_); +} + +const SaveItem* SavePackage::LookupSaveItemForSender( + base::WeakPtr<RenderFrameHostImpl> sender) { + if (!sender) + return nullptr; + + int frame_tree_node_id = sender->frame_tree_node()->frame_tree_node_id(); + auto it = frame_tree_node_id_to_save_item_.find(frame_tree_node_id); + if (it == frame_tree_node_id_to_save_item_.end()) + return nullptr; + + const SaveItem* save_item = it->second; + DCHECK_EQ(SaveFileCreateInfo::SAVE_FILE_FROM_DOM, save_item->save_source()); + + return save_item; } // Ask for all savable resource links from backend, include main frame and @@ -1107,12 +1136,17 @@ void SavePackage::GetSavableResourceLinks() { wait_state_ = RESOURCES_LIST; DCHECK_EQ(0, number_of_frames_pending_response_); - number_of_frames_pending_response_ = web_contents()->SendToAllFrames( - new FrameMsg_GetSavableResourceLinks(MSG_ROUTING_NONE)); + for (RenderFrameHost* rfh : web_contents()->GetAllFrames()) { + if (!rfh->IsRenderFrameLive()) + continue; + ++number_of_frames_pending_response_; + static_cast<RenderFrameHostImpl*>(rfh) + ->GetSavableResourceLinksFromRenderer(); + } DCHECK_LT(0, number_of_frames_pending_response_); // Enqueue the main frame separately (because this frame won't show up in any - // of OnSavableResourceLinksResponse callbacks). + // of GetsSavableResourceLinks callbacks). FrameTreeNode* main_frame_tree_node = static_cast<RenderFrameHostImpl*>(web_contents()->GetMainFrame()) ->frame_tree_node(); @@ -1122,11 +1156,11 @@ void SavePackage::GetSavableResourceLinks() { all_save_items_count_ = 1; } -void SavePackage::OnSavableResourceLinksResponse( +void SavePackage::SavableResourceLinksResponse( RenderFrameHostImpl* sender, const std::vector<GURL>& resources_list, - const Referrer& referrer, - const std::vector<SavableSubframe>& subframes) { + blink::mojom::ReferrerPtr referrer, + const std::vector<blink::mojom::SavableSubframePtr>& subframes) { DCHECK_CURRENTLY_ON(BrowserThread::UI); if (wait_state_ != RESOURCES_LIST) return; @@ -1135,11 +1169,12 @@ void SavePackage::OnSavableResourceLinksResponse( int container_frame_tree_node_id = sender->frame_tree_node()->frame_tree_node_id(); for (const GURL& u : resources_list) { - EnqueueSavableResource(container_frame_tree_node_id, u, referrer); + EnqueueSavableResource(container_frame_tree_node_id, u, + referrer.To<content::Referrer>()); } - for (const SavableSubframe& subframe : subframes) { + for (auto& subframe : subframes) { RenderFrameHostImpl* rfh_subframe = sender->FindAndVerifyChild( - subframe.routing_id, + subframe->subframe_token, bad_message::DWNLD_INVALID_SAVABLE_RESOURCE_LINKS_RESPONSE); if (!rfh_subframe) { @@ -1149,7 +1184,7 @@ void SavePackage::OnSavableResourceLinksResponse( EnqueueFrame(container_frame_tree_node_id, rfh_subframe->frame_tree_node()->frame_tree_node_id(), - subframe.original_url); + subframe->original_url); } CompleteSavableResourceLinksResponse(); @@ -1219,7 +1254,7 @@ void SavePackage::EnqueueFrame(int container_frame_tree_node_id, frame_tree_node_id_to_save_item_[frame_tree_node_id] = save_item; } -void SavePackage::OnSavableResourceLinksError(RenderFrameHostImpl* sender) { +void SavePackage::SavableResourceLinksError(RenderFrameHostImpl* sender) { DCHECK_CURRENTLY_ON(BrowserThread::UI); CompleteSavableResourceLinksResponse(); } |