Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(104)

Side by Side Diff: content/browser/download/save_package.cc

Issue 2075273002: Resource requests from Save-Page-As should go through CanRequestURL checks. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/download/save_package.h" 5 #include "content/browser/download/save_package.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/files/file_path.h" 11 #include "base/files/file_path.h"
12 #include "base/files/file_util.h" 12 #include "base/files/file_util.h"
13 #include "base/guid.h"
13 #include "base/i18n/file_util_icu.h" 14 #include "base/i18n/file_util_icu.h"
14 #include "base/logging.h" 15 #include "base/logging.h"
15 #include "base/macros.h" 16 #include "base/macros.h"
16 #include "base/message_loop/message_loop.h" 17 #include "base/message_loop/message_loop.h"
17 #include "base/stl_util.h" 18 #include "base/stl_util.h"
18 #include "base/strings/string_piece.h" 19 #include "base/strings/string_piece.h"
19 #include "base/strings/string_split.h" 20 #include "base/strings/string_split.h"
20 #include "base/strings/sys_string_conversions.h" 21 #include "base/strings/sys_string_conversions.h"
21 #include "base/strings/utf_string_conversions.h" 22 #include "base/strings/utf_string_conversions.h"
22 #include "base/threading/thread.h" 23 #include "base/threading/thread.h"
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 DCHECK(!saved_main_directory_path_.empty()); 343 DCHECK(!saved_main_directory_path_.empty());
343 GetSavableResourceLinks(); 344 GetSavableResourceLinks();
344 } else if (save_type_ == SAVE_PAGE_TYPE_AS_MHTML) { 345 } else if (save_type_ == SAVE_PAGE_TYPE_AS_MHTML) {
345 MHTMLGenerationParams mhtml_generation_params(saved_main_file_path_); 346 MHTMLGenerationParams mhtml_generation_params(saved_main_file_path_);
346 web_contents()->GenerateMHTML( 347 web_contents()->GenerateMHTML(
347 mhtml_generation_params, 348 mhtml_generation_params,
348 base::Bind(&SavePackage::OnMHTMLGenerated, this)); 349 base::Bind(&SavePackage::OnMHTMLGenerated, this));
349 } else { 350 } else {
350 DCHECK_EQ(SAVE_PAGE_TYPE_AS_ONLY_HTML, save_type_); 351 DCHECK_EQ(SAVE_PAGE_TYPE_AS_ONLY_HTML, save_type_);
351 wait_state_ = NET_FILES; 352 wait_state_ = NET_FILES;
352 SaveFileCreateInfo::SaveFileSource save_source = page_url_.SchemeIsFile() ?
353 SaveFileCreateInfo::SAVE_FILE_FROM_FILE :
354 SaveFileCreateInfo::SAVE_FILE_FROM_NET;
355 // Add this item to waiting list. 353 // Add this item to waiting list.
356 waiting_item_queue_.push_back( 354 waiting_item_queue_.push_back(new SaveItem(
357 new SaveItem(page_url_, Referrer(), this, save_source, 355 page_url_, Referrer(), this, SaveFileCreateInfo::SAVE_FILE_FROM_NET,
358 FrameTreeNode::kFrameTreeNodeInvalidId)); 356 FrameTreeNode::kFrameTreeNodeInvalidId));
359 all_save_items_count_ = 1; 357 all_save_items_count_ = 1;
360 download_->SetTotalBytes(1); 358 download_->SetTotalBytes(1);
361 359
362 DoSavingProcess(); 360 DoSavingProcess();
363 } 361 }
364 } 362 }
365 363
366 void SavePackage::OnMHTMLGenerated(int64_t size) { 364 void SavePackage::OnMHTMLGenerated(int64_t size) {
367 DCHECK_CURRENTLY_ON(BrowserThread::UI); 365 DCHECK_CURRENTLY_ON(BrowserThread::UI);
368 if (size <= 0) { 366 if (size <= 0) {
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
583 // Now we get final name retrieved from GenerateFileName, we will use it 581 // Now we get final name retrieved from GenerateFileName, we will use it
584 // rename the SaveItem. 582 // rename the SaveItem.
585 base::FilePath final_name = 583 base::FilePath final_name =
586 saved_main_directory_path_.Append(generated_name); 584 saved_main_directory_path_.Append(generated_name);
587 save_item->SetTargetPath(final_name); 585 save_item->SetTargetPath(final_name);
588 } else { 586 } else {
589 // It is the main HTML file, use the name chosen by the user. 587 // It is the main HTML file, use the name chosen by the user.
590 save_item->SetTargetPath(saved_main_file_path_); 588 save_item->SetTargetPath(saved_main_file_path_);
591 } 589 }
592 590
593 // If the save source is from file system, inform SaveFileManager to copy
594 // corresponding file to the file path which this SaveItem specifies.
595 if (info->save_source == SaveFileCreateInfo::SAVE_FILE_FROM_FILE) {
596 BrowserThread::PostTask(
597 BrowserThread::FILE, FROM_HERE,
598 base::Bind(&SaveFileManager::SaveLocalFile, file_manager_,
599 save_item->url(), save_item->id(), id()));
600 return;
601 }
602
603 // Check whether we begin to require serialized HTML data. 591 // Check whether we begin to require serialized HTML data.
604 if (save_type_ == SAVE_PAGE_TYPE_AS_COMPLETE_HTML && 592 if (save_type_ == SAVE_PAGE_TYPE_AS_COMPLETE_HTML &&
605 wait_state_ == HTML_DATA) { 593 wait_state_ == HTML_DATA) {
606 // Inform backend to serialize the all frames' DOM and send serialized 594 // Inform backend to serialize the all frames' DOM and send serialized
607 // HTML data back. 595 // HTML data back.
608 GetSerializedHtmlWithLocalLinks(); 596 GetSerializedHtmlWithLocalLinks();
609 } 597 }
610 } 598 }
611 599
612 SaveItem* SavePackage::LookupInProgressSaveItem(SaveItemId save_item_id) { 600 SaveItem* SavePackage::LookupInProgressSaveItem(SaveItemId save_item_id) {
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
835 823
836 do { 824 do {
837 // Pop SaveItem from waiting list. 825 // Pop SaveItem from waiting list.
838 SaveItem* save_item = waiting_item_queue_.front(); 826 SaveItem* save_item = waiting_item_queue_.front();
839 waiting_item_queue_.pop_front(); 827 waiting_item_queue_.pop_front();
840 828
841 // Add the item to |in_progress_items_|. 829 // Add the item to |in_progress_items_|.
842 DCHECK(!ContainsKey(in_progress_items_, save_item->id())); 830 DCHECK(!ContainsKey(in_progress_items_, save_item->id()));
843 in_progress_items_[save_item->id()] = save_item; 831 in_progress_items_[save_item->id()] = save_item;
844 save_item->Start(); 832 save_item->Start();
833
834 // TODO(lukasza): https://crbug.com/616429: Pass the correct child process
835 // id instead of always passing main frame's process id. Correctness of
836 // security checks in ResourceDispatcherHostImpl::BeginSave depends on it
837 // (OTOH, this only matters if OOPIFs are present).
Łukasz Anforowicz 2016/06/18 00:37:20 I need to double-check how process_id/child_id and
asanka 2016/06/20 20:24:18 Thanks for calling this out. In addition to the tw
Łukasz Anforowicz 2016/06/21 16:39:34 Ack.
845 file_manager_->SaveURL( 838 file_manager_->SaveURL(
846 save_item->id(), save_item->url(), save_item->referrer(), 839 save_item->id(), save_item->url(), save_item->referrer(),
847 web_contents()->GetRenderProcessHost()->GetID(), routing_id(), 840 web_contents()->GetRenderProcessHost()->GetID(), routing_id(),
848 web_contents()->GetMainFrame()->GetRoutingID(), 841 web_contents()->GetMainFrame()->GetRoutingID(),
849 save_item->save_source(), save_item->full_path(), 842 save_item->save_source(), save_item->full_path(),
850 web_contents()->GetBrowserContext()->GetResourceContext(), this); 843 web_contents()->GetBrowserContext()->GetResourceContext(), this);
851 } while (process_all_remaining_items && !waiting_item_queue_.empty()); 844 } while (process_all_remaining_items && !waiting_item_queue_.empty());
852 } 845 }
853 846
854 int SavePackage::PercentComplete() { 847 int SavePackage::PercentComplete() {
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
986 // Collect all saved success items. 979 // Collect all saved success items.
987 // SECURITY NOTE: We don't send *all* urls / local paths, but only 980 // SECURITY NOTE: We don't send *all* urls / local paths, but only
988 // those that the given frame had access to already (because it contained 981 // those that the given frame had access to already (because it contained
989 // the savable resources / subframes associated with save items). 982 // the savable resources / subframes associated with save items).
990 std::map<GURL, base::FilePath> url_to_local_path; 983 std::map<GURL, base::FilePath> url_to_local_path;
991 std::map<int, base::FilePath> routing_id_to_local_path; 984 std::map<int, base::FilePath> routing_id_to_local_path;
992 auto it = frame_tree_node_id_to_contained_save_items_.find( 985 auto it = frame_tree_node_id_to_contained_save_items_.find(
993 target_frame_tree_node_id); 986 target_frame_tree_node_id);
994 if (it != frame_tree_node_id_to_contained_save_items_.end()) { 987 if (it != frame_tree_node_id_to_contained_save_items_.end()) {
995 for (const SaveItem* save_item : it->second) { 988 for (const SaveItem* save_item : it->second) {
996 // Skip items that failed to save.
997 if (!save_item->has_final_name()) {
998 DCHECK_EQ(SaveItem::SaveState::COMPLETE, save_item->state());
999 DCHECK(!save_item->success());
1000 continue;
1001 }
Łukasz Anforowicz 2016/06/18 00:37:20 I've added these checks in https://codereview.chro
asanka 2016/06/20 20:24:18 Acknowledged.
1002
1003 // Calculate the relative path for referring to the |save_item|. 989 // Calculate the relative path for referring to the |save_item|.
1004 base::FilePath local_path(base::FilePath::kCurrentDirectory); 990 base::FilePath local_path(base::FilePath::kCurrentDirectory);
1005 if (target_tree_node->IsMainFrame()) { 991 if (target_tree_node->IsMainFrame()) {
1006 local_path = local_path.Append(saved_main_directory_path_.BaseName()); 992 local_path = local_path.Append(saved_main_directory_path_.BaseName());
1007 } 993 }
1008 local_path = local_path.Append(save_item->full_path().BaseName()); 994 if (save_item->has_final_name()) {
995 local_path = local_path.Append(save_item->full_path().BaseName());
996 } else {
997 // Skip items that failed to save.
998 DCHECK_EQ(SaveItem::SaveState::COMPLETE, save_item->state());
999 DCHECK(!save_item->success());
1000 local_path = local_path.Append(base::FilePath::FromUTF8Unsafe(
1001 "resource-failed-to-save-" + base::GenerateGUID() + ".txt"));
Łukasz Anforowicz 2016/06/18 00:37:20 This is tricky. We could analyze this with an exa
asanka 2016/06/20 20:24:18 As long as we are talking about subresources, I'm
Łukasz Anforowicz 2016/06/21 16:39:34 Yes - propagating origin-specific restrictions int
1002 }
1009 1003
1010 // Insert the link into |url_to_local_path| or |routing_id_to_local_path|. 1004 // Insert the link into |url_to_local_path| or |routing_id_to_local_path|.
1011 if (save_item->save_source() != SaveFileCreateInfo::SAVE_FILE_FROM_DOM) { 1005 if (save_item->save_source() != SaveFileCreateInfo::SAVE_FILE_FROM_DOM) {
1012 DCHECK_EQ(FrameTreeNode::kFrameTreeNodeInvalidId, 1006 DCHECK_EQ(FrameTreeNode::kFrameTreeNodeInvalidId,
1013 save_item->frame_tree_node_id()); 1007 save_item->frame_tree_node_id());
1014 url_to_local_path[save_item->url()] = local_path; 1008 url_to_local_path[save_item->url()] = local_path;
1015 } else { 1009 } else {
1016 FrameTreeNode* save_item_frame_tree_node = 1010 FrameTreeNode* save_item_frame_tree_node =
1017 target_tree_node->frame_tree()->FindByID( 1011 target_tree_node->frame_tree()->FindByID(
1018 save_item->frame_tree_node_id()); 1012 save_item->frame_tree_node_id());
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
1207 return save_item; 1201 return save_item;
1208 } 1202 }
1209 1203
1210 void SavePackage::EnqueueSavableResource(int container_frame_tree_node_id, 1204 void SavePackage::EnqueueSavableResource(int container_frame_tree_node_id,
1211 const GURL& url, 1205 const GURL& url,
1212 const Referrer& referrer) { 1206 const Referrer& referrer) {
1213 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1207 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1214 if (!url.is_valid()) 1208 if (!url.is_valid())
1215 return; 1209 return;
1216 1210
1217 SaveFileCreateInfo::SaveFileSource save_source =
1218 url.SchemeIsFile() ? SaveFileCreateInfo::SAVE_FILE_FROM_FILE
1219 : SaveFileCreateInfo::SAVE_FILE_FROM_NET;
1220 CreatePendingSaveItemDeduplicatingByUrl( 1211 CreatePendingSaveItemDeduplicatingByUrl(
1221 container_frame_tree_node_id, FrameTreeNode::kFrameTreeNodeInvalidId, url, 1212 container_frame_tree_node_id, FrameTreeNode::kFrameTreeNodeInvalidId, url,
1222 referrer, save_source); 1213 referrer, SaveFileCreateInfo::SAVE_FILE_FROM_NET);
1223 } 1214 }
1224 1215
1225 void SavePackage::EnqueueFrame(int container_frame_tree_node_id, 1216 void SavePackage::EnqueueFrame(int container_frame_tree_node_id,
1226 int frame_tree_node_id, 1217 int frame_tree_node_id,
1227 const GURL& frame_original_url) { 1218 const GURL& frame_original_url) {
1228 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1219 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1229 SaveItem* save_item = CreatePendingSaveItem( 1220 SaveItem* save_item = CreatePendingSaveItem(
1230 container_frame_tree_node_id, frame_tree_node_id, frame_original_url, 1221 container_frame_tree_node_id, frame_tree_node_id, frame_original_url,
1231 Referrer(), SaveFileCreateInfo::SAVE_FILE_FROM_DOM); 1222 Referrer(), SaveFileCreateInfo::SAVE_FILE_FROM_DOM);
1232 DCHECK(save_item); 1223 DCHECK(save_item);
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
1508 } 1499 }
1509 1500
1510 void SavePackage::FinalizeDownloadEntry() { 1501 void SavePackage::FinalizeDownloadEntry() {
1511 DCHECK(download_); 1502 DCHECK(download_);
1512 1503
1513 download_manager_->OnSavePackageSuccessfullyFinished(download_); 1504 download_manager_->OnSavePackageSuccessfullyFinished(download_);
1514 RemoveObservers(); 1505 RemoveObservers();
1515 } 1506 }
1516 1507
1517 } // namespace content 1508 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698