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

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

Issue 10069014: Save Page As MHTML (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: whitespace Created 8 years, 8 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 | Annotate | Revision Log
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 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/file_path.h" 10 #include "base/file_path.h"
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 user_canceled_(false), 134 user_canceled_(false),
135 disk_error_occurred_(false), 135 disk_error_occurred_(false),
136 save_type_(save_type), 136 save_type_(save_type),
137 all_save_items_count_(0), 137 all_save_items_count_(0),
138 wait_state_(INITIALIZE), 138 wait_state_(INITIALIZE),
139 tab_id_(web_contents->GetRenderProcessHost()->GetID()), 139 tab_id_(web_contents->GetRenderProcessHost()->GetID()),
140 unique_id_(g_save_package_id++), 140 unique_id_(g_save_package_id++),
141 wrote_to_completed_file_(false), 141 wrote_to_completed_file_(false),
142 wrote_to_failed_file_(false) { 142 wrote_to_failed_file_(false) {
143 DCHECK(page_url_.is_valid()); 143 DCHECK(page_url_.is_valid());
144 DCHECK(save_type_ == content::SAVE_PAGE_TYPE_AS_ONLY_HTML || 144 DCHECK((save_type_ == content::SAVE_PAGE_TYPE_AS_ONLY_HTML) ||
145 save_type_ == content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML); 145 (save_type_ == content::SAVE_PAGE_TYPE_AS_MHTML) ||
146 (save_type_ == content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML));
146 DCHECK(!saved_main_file_path_.empty() && 147 DCHECK(!saved_main_file_path_.empty() &&
147 saved_main_file_path_.value().length() <= kMaxFilePathLength); 148 saved_main_file_path_.value().length() <= kMaxFilePathLength);
148 DCHECK(!saved_main_directory_path_.empty() && 149 DCHECK(!saved_main_directory_path_.empty() &&
149 saved_main_directory_path_.value().length() < kMaxFilePathLength); 150 saved_main_directory_path_.value().length() < kMaxFilePathLength);
150 InternalInit(); 151 InternalInit();
151 } 152 }
152 153
153 SavePackage::SavePackage(WebContents* web_contents) 154 SavePackage::SavePackage(WebContents* web_contents)
154 : content::WebContentsObserver(web_contents), 155 : content::WebContentsObserver(web_contents),
155 file_manager_(NULL), 156 file_manager_(NULL),
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 wait_state_ = START_PROCESS; 275 wait_state_ = START_PROCESS;
275 276
276 // Initialize the request context and resource dispatcher. 277 // Initialize the request context and resource dispatcher.
277 content::BrowserContext* browser_context = 278 content::BrowserContext* browser_context =
278 web_contents()->GetBrowserContext(); 279 web_contents()->GetBrowserContext();
279 if (!browser_context) { 280 if (!browser_context) {
280 NOTREACHED(); 281 NOTREACHED();
281 return false; 282 return false;
282 } 283 }
283 284
285 if (save_type_ == content::SAVE_PAGE_TYPE_AS_MHTML) {
286 // Force the extension to be mht. If the extension is left as html, then
287 // chrome will render it as html when opened instead of mhtml.
288 // Force the extension before creating the DownloadItem.
289 // TODO(benjhayden): Figure out how to move this back into the file picker.
290 // If the .html file already exists, then the user will be prompted to
291 // replace it, even thought it won't be replaced. If the .mht already
292 // exists, then the user will not be prompted to replace it, even though it
293 // will be replaced. The user will only be prompted to replace the .mht if
294 // they type out the filename including .mht.
295 saved_main_file_path_ = saved_main_file_path_.ReplaceExtension(
296 FILE_PATH_LITERAL("mht"));
297 }
298
284 // The download manager keeps ownership but adds us as an observer. 299 // The download manager keeps ownership but adds us as an observer.
285 download_ = download_manager_->CreateSavePackageDownloadItem( 300 download_ = download_manager_->CreateSavePackageDownloadItem(
286 saved_main_file_path_, page_url_, 301 saved_main_file_path_, page_url_,
287 browser_context->IsOffTheRecord(), this); 302 browser_context->IsOffTheRecord(), this);
288 303
289 // Check save type and process the save page job. 304 // Check save type and process the save page job.
290 if (save_type_ == content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML) { 305 if (save_type_ == content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML) {
291 // Get directory 306 // Get directory
292 DCHECK(!saved_main_directory_path_.empty()); 307 DCHECK(!saved_main_directory_path_.empty());
293 GetAllSavableResourceLinksForCurrentPage(); 308 GetAllSavableResourceLinksForCurrentPage();
309 } else if (save_type_ == content::SAVE_PAGE_TYPE_AS_MHTML) {
310 web_contents()->GenerateMHTML(saved_main_file_path_, base::Bind(
311 &SavePackage::MHTMLGenerated, this));
294 } else { 312 } else {
295 wait_state_ = NET_FILES; 313 wait_state_ = NET_FILES;
296 SaveFileCreateInfo::SaveFileSource save_source = page_url_.SchemeIsFile() ? 314 SaveFileCreateInfo::SaveFileSource save_source = page_url_.SchemeIsFile() ?
297 SaveFileCreateInfo::SAVE_FILE_FROM_FILE : 315 SaveFileCreateInfo::SAVE_FILE_FROM_FILE :
298 SaveFileCreateInfo::SAVE_FILE_FROM_NET; 316 SaveFileCreateInfo::SAVE_FILE_FROM_NET;
299 SaveItem* save_item = new SaveItem(page_url_, 317 SaveItem* save_item = new SaveItem(page_url_,
300 GURL(), 318 GURL(),
301 this, 319 this,
302 save_source); 320 save_source);
303 // Add this item to waiting list. 321 // Add this item to waiting list.
304 waiting_item_queue_.push(save_item); 322 waiting_item_queue_.push(save_item);
305 all_save_items_count_ = 1; 323 all_save_items_count_ = 1;
306 download_->SetTotalBytes(1); 324 download_->SetTotalBytes(1);
307 325
308 DoSavingProcess(); 326 DoSavingProcess();
309 } 327 }
310 328
311 return true; 329 return true;
312 } 330 }
313 331
332 void SavePackage::MHTMLGenerated(const FilePath& path, int64 size) {
333 if (size <= 0) {
334 Cancel(false);
335 } else {
336 download_->SetTotalBytes(size);
337 download_->OnAllDataSaved(size, DownloadItem::kEmptyFileHash);
338 download_->UpdateProgress(size, 0, "");
339 wrote_to_completed_file_ = true;
340 Finish();
341 }
342 }
343
314 // On POSIX, the length of |pure_file_name| + |file_name_ext| is further 344 // On POSIX, the length of |pure_file_name| + |file_name_ext| is further
315 // restricted by NAME_MAX. The maximum allowed path looks like: 345 // restricted by NAME_MAX. The maximum allowed path looks like:
316 // '/path/to/save_dir' + '/' + NAME_MAX. 346 // '/path/to/save_dir' + '/' + NAME_MAX.
317 uint32 SavePackage::GetMaxPathLengthForDirectory(const FilePath& base_dir) { 347 uint32 SavePackage::GetMaxPathLengthForDirectory(const FilePath& base_dir) {
318 #if defined(OS_POSIX) 348 #if defined(OS_POSIX)
319 return std::min(kMaxFilePathLength, 349 return std::min(kMaxFilePathLength,
320 static_cast<uint32>(base_dir.value().length()) + 350 static_cast<uint32>(base_dir.value().length()) +
321 NAME_MAX + 1); 351 NAME_MAX + 1);
322 #else 352 #else
323 return kMaxFilePathLength; 353 return kMaxFilePathLength;
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 it != saved_failed_items_.end(); ++it) 729 it != saved_failed_items_.end(); ++it)
700 save_ids.push_back(it->second->save_id()); 730 save_ids.push_back(it->second->save_id());
701 731
702 BrowserThread::PostTask( 732 BrowserThread::PostTask(
703 BrowserThread::FILE, FROM_HERE, 733 BrowserThread::FILE, FROM_HERE,
704 base::Bind(&SaveFileManager::RemoveSavedFileFromFileMap, 734 base::Bind(&SaveFileManager::RemoveSavedFileFromFileMap,
705 file_manager_, 735 file_manager_,
706 save_ids)); 736 save_ids));
707 737
708 if (download_) { 738 if (download_) {
709 download_->OnAllDataSaved(all_save_items_count_, 739 if (save_type_ != content::SAVE_PAGE_TYPE_AS_MHTML) {
Randy Smith (Not in Mondays) 2012/04/16 17:45:47 I'm somewhat torn about this and related logic. I
benjhayden 2012/04/16 19:08:06 Done.
710 DownloadItem::kEmptyFileHash); 740 download_->OnAllDataSaved(all_save_items_count_,
Randy Smith (Not in Mondays) 2012/04/16 17:45:47 nit: If there's an easy, not too ugly way to do it
benjhayden 2012/04/16 19:08:06 Done.
741 DownloadItem::kEmptyFileHash);
742 }
711 download_->MarkAsComplete(); 743 download_->MarkAsComplete();
712 FinalizeDownloadEntry(); 744 FinalizeDownloadEntry();
713 } 745 }
714 } 746 }
715 747
716 // Called for updating end state. 748 // Called for updating end state.
717 void SavePackage::SaveFinished(int32 save_id, int64 size, bool is_success) { 749 void SavePackage::SaveFinished(int32 save_id, int64 size, bool is_success) {
718 // Because we might have canceled this saving job before, 750 // Because we might have canceled this saving job before,
719 // so we might not find corresponding SaveItem. Just ignore it. 751 // so we might not find corresponding SaveItem. Just ignore it.
720 SaveItem* save_item = LookupItemInProcessBySaveId(save_id); 752 SaveItem* save_item = LookupItemInProcessBySaveId(save_id);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
768 800
769 save_item->Finish(0, false); 801 save_item->Finish(0, false);
770 802
771 PutInProgressItemToSavedMap(save_item); 803 PutInProgressItemToSavedMap(save_item);
772 804
773 // Inform the DownloadItem to update UI. 805 // Inform the DownloadItem to update UI.
774 // We use the received bytes as number of saved files. 806 // We use the received bytes as number of saved files.
775 if (download_) 807 if (download_)
776 download_->UpdateProgress(completed_count(), CurrentSpeed(), ""); 808 download_->UpdateProgress(completed_count(), CurrentSpeed(), "");
777 809
778 if (save_type_ == content::SAVE_PAGE_TYPE_AS_ONLY_HTML || 810 if ((save_type_ == content::SAVE_PAGE_TYPE_AS_ONLY_HTML) ||
779 save_item->save_source() == SaveFileCreateInfo::SAVE_FILE_FROM_DOM) { 811 (save_type_ == content::SAVE_PAGE_TYPE_AS_MHTML) ||
812 (save_item->save_source() == SaveFileCreateInfo::SAVE_FILE_FROM_DOM)) {
780 // We got error when saving page. Treat it as disk error. 813 // We got error when saving page. Treat it as disk error.
781 Cancel(true); 814 Cancel(true);
782 } 815 }
783 816
784 if (canceled()) { 817 if (canceled()) {
785 DCHECK(finished_); 818 DCHECK(finished_);
786 return; 819 return;
787 } 820 }
788 821
789 // Continue processing the save page job. 822 // Continue processing the save page job.
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
875 wait_state_ = HTML_DATA; 908 wait_state_ = HTML_DATA;
876 // All non-HTML resources have been finished, start all remaining 909 // All non-HTML resources have been finished, start all remaining
877 // HTML files. 910 // HTML files.
878 SaveNextFile(true); 911 SaveNextFile(true);
879 } 912 }
880 } else if (in_process_count()) { 913 } else if (in_process_count()) {
881 // Continue asking for HTML data. 914 // Continue asking for HTML data.
882 DCHECK(wait_state_ == HTML_DATA); 915 DCHECK(wait_state_ == HTML_DATA);
883 } 916 }
884 } else { 917 } else {
885 // Save as HTML only. 918 // Save as HTML only or MHTML.
886 DCHECK(wait_state_ == NET_FILES); 919 DCHECK(wait_state_ == NET_FILES);
887 DCHECK(save_type_ == content::SAVE_PAGE_TYPE_AS_ONLY_HTML); 920 DCHECK((save_type_ == content::SAVE_PAGE_TYPE_AS_ONLY_HTML) ||
921 (save_type_ == content::SAVE_PAGE_TYPE_AS_MHTML));
888 if (waiting_item_queue_.size()) { 922 if (waiting_item_queue_.size()) {
889 DCHECK(all_save_items_count_ == waiting_item_queue_.size()); 923 DCHECK(all_save_items_count_ == waiting_item_queue_.size());
890 SaveNextFile(false); 924 SaveNextFile(false);
891 } 925 }
892 } 926 }
893 } 927 }
894 928
895 bool SavePackage::OnMessageReceived(const IPC::Message& message) { 929 bool SavePackage::OnMessageReceived(const IPC::Message& message) {
896 bool handled = true; 930 bool handled = true;
897 IPC_BEGIN_MESSAGE_MAP(SavePackage, message) 931 IPC_BEGIN_MESSAGE_MAP(SavePackage, message)
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after
1315 StopObservation(); 1349 StopObservation();
1316 } 1350 }
1317 1351
1318 void SavePackage::FinalizeDownloadEntry() { 1352 void SavePackage::FinalizeDownloadEntry() {
1319 DCHECK(download_); 1353 DCHECK(download_);
1320 DCHECK(download_manager_); 1354 DCHECK(download_manager_);
1321 1355
1322 download_manager_->SavePageDownloadFinished(download_); 1356 download_manager_->SavePageDownloadFinished(download_);
1323 StopObservation(); 1357 StopObservation();
1324 } 1358 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698