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

Unified Diff: chrome/browser/download/download_manager.cc

Issue 3043048: Clean up download code: (Closed)
Patch Set: Created 10 years, 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/download/download_manager.h ('k') | chrome/browser/download/download_manager_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/download/download_manager.cc
diff --git a/chrome/browser/download/download_manager.cc b/chrome/browser/download/download_manager.cc
index f2e3a65b494b28653ced3c3dbdf02c6364c84105..652b9d7fcef9273cc7dacd2e5b2cd6fd020eacc0 100644
--- a/chrome/browser/download/download_manager.cc
+++ b/chrome/browser/download/download_manager.cc
@@ -22,8 +22,6 @@
#include "chrome/browser/download/download_history.h"
#include "chrome/browser/download/download_item.h"
#include "chrome/browser/download/download_util.h"
-#include "chrome/browser/extensions/crx_installer.h"
-#include "chrome/browser/extensions/extension_install_ui.h"
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/browser/history/download_types.h"
#include "chrome/browser/net/chrome_url_request_context.h"
@@ -57,14 +55,6 @@ bool CompareStartTime(DownloadItem* first, DownloadItem* second) {
return first->start_time() > second->start_time();
}
-void DeleteDownloadedFile(const FilePath& path) {
- DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
-
- // Make sure we only delete files.
- if (!file_util::DirectoryExists(path))
- file_util::Delete(path, false);
-}
-
} // namespace
// static
@@ -295,7 +285,7 @@ void DownloadManager::StartDownload(DownloadCreateInfo* info) {
if (info->save_info.file_path.empty()) {
FilePath generated_name;
- GenerateFileNameFromInfo(info, &generated_name);
+ download_util::GenerateFileNameFromInfo(info, &generated_name);
// Freeze the user's preference for showing a Save As dialog. We're going
// to bounce around a bunch of threads and we don't want to worry about race
@@ -330,7 +320,7 @@ void DownloadManager::StartDownload(DownloadCreateInfo* info) {
// Downloads can be marked as dangerous for two reasons:
// a) They have a dangerous-looking filename
// b) They are an extension that is not from the gallery
- if (IsDangerous(info->suggested_path.BaseName()))
+ if (IsExecutableFile(info->suggested_path.BaseName()))
info->is_dangerous = true;
else if (info->is_extension_install &&
!ExtensionsService::IsDownloadFromGallery(info->url,
@@ -596,10 +586,7 @@ void DownloadManager::ContinueDownloadFinished(DownloadItem* download) {
// Handle chrome extensions explicitly and skip the shell execute.
if (download->is_extension_install()) {
- OpenChromeExtension(download->full_path(),
- download->url(),
- download->referrer_url(),
- download->original_mime_type());
+ download_util::OpenChromeExtension(profile_, this, *download);
download->set_auto_opened(true);
} else if (download->open_when_complete() ||
ShouldOpenFileBasedOnExtension(download->full_path()) ||
@@ -715,6 +702,9 @@ void DownloadManager::DownloadCancelledInternal(int download_id,
file_manager_, &DownloadFileManager::CancelDownload, download_id));
}
+// DownloadManager is owned by RDH, no need for reference counting.
+DISABLE_RUNNABLE_METHOD_REFCOUNT(ResourceDispatcherHost);
+
void DownloadManager::PauseDownload(int32 download_id, bool pause) {
DownloadMap::iterator it = in_progress_.find(download_id);
if (it == in_progress_.end())
@@ -727,24 +717,11 @@ void DownloadManager::PauseDownload(int32 download_id, bool pause) {
// Inform the ResourceDispatcherHost of the new pause state.
ChromeThread::PostTask(
ChromeThread::IO, FROM_HERE,
- NewRunnableFunction(&DownloadManager::OnPauseDownloadRequest,
- g_browser_process->resource_dispatcher_host(),
- download->render_process_id(),
- download->request_id(),
- pause));
-}
-
-// static
-void DownloadManager::OnPauseDownloadRequest(ResourceDispatcherHost* rdh,
- int render_process_id,
- int request_id,
- bool pause) {
- rdh->PauseRequest(render_process_id, request_id, pause);
-}
-
-bool DownloadManager::IsDangerous(const FilePath& file_name) {
- // TODO(jcampan): Improve me.
- return IsExecutableFile(file_name);
+ NewRunnableMethod(g_browser_process->resource_dispatcher_host(),
+ &ResourceDispatcherHost::PauseRequest,
+ download->render_process_id(),
+ download->request_id(),
+ pause));
}
void DownloadManager::UpdateAppIcon() {
@@ -770,7 +747,7 @@ void DownloadManager::UpdateAppIcon() {
float progress = 0;
if (progress_known && download_count)
- progress = (float)received_bytes / total_bytes;
+ progress = static_cast<float>(received_bytes) / total_bytes;
download_util::UpdateAppIconDownloadProgress(download_count,
progress_known,
@@ -889,122 +866,6 @@ void DownloadManager::DownloadUrlToFile(const GURL& url,
request_context_getter_));
}
-void DownloadManager::GenerateExtension(
- const FilePath& file_name,
- const std::string& mime_type,
- FilePath::StringType* generated_extension) {
- // We're worried about three things here:
- //
- // 1) Security. Many sites let users upload content, such as buddy icons, to
- // their web sites. We want to mitigate the case where an attacker
- // supplies a malicious executable with an executable file extension but an
- // honest site serves the content with a benign content type, such as
- // image/jpeg.
- //
- // 2) Usability. If the site fails to provide a file extension, we want to
- // guess a reasonable file extension based on the content type.
- //
- // 3) Shell integration. Some file extensions automatically integrate with
- // the shell. We block these extensions to prevent a malicious web site
- // from integrating with the user's shell.
-
- static const FilePath::CharType default_extension[] =
- FILE_PATH_LITERAL("download");
-
- // See if our file name already contains an extension.
- FilePath::StringType extension = file_name.Extension();
- if (!extension.empty())
- extension.erase(extension.begin()); // Erase preceding '.'.
-
-#if defined(OS_WIN)
- // Rename shell-integrated extensions.
- if (win_util::IsShellIntegratedExtension(extension))
- extension.assign(default_extension);
-#endif
-
- std::string mime_type_from_extension;
- net::GetMimeTypeFromFile(file_name,
- &mime_type_from_extension);
- if (mime_type == mime_type_from_extension) {
- // The hinted extension matches the mime type. It looks like a winner.
- generated_extension->swap(extension);
- return;
- }
-
- if (IsExecutableExtension(extension) && !IsExecutableMimeType(mime_type)) {
- // We want to be careful about executable extensions. The worry here is
- // that a trusted web site could be tricked into dropping an executable file
- // on the user's filesystem.
- if (!net::GetPreferredExtensionForMimeType(mime_type, &extension)) {
- // We couldn't find a good extension for this content type. Use a dummy
- // extension instead.
- extension.assign(default_extension);
- }
- }
-
- if (extension.empty()) {
- net::GetPreferredExtensionForMimeType(mime_type, &extension);
- } else {
- // Append extension generated from the mime type if:
- // 1. New extension is not ".txt"
- // 2. New extension is not the same as the already existing extension.
- // 3. New extension is not executable. This action mitigates the case when
- // an executable is hidden in a benign file extension;
- // E.g. my-cat.jpg becomes my-cat.jpg.js if content type is
- // application/x-javascript.
- // 4. New extension is not ".tar" for .tar.gz files. For misconfigured web
- // servers, i.e. bug 5772.
- // 5. The original extension is not ".tgz" & the new extension is not "gz".
- FilePath::StringType append_extension;
- if (net::GetPreferredExtensionForMimeType(mime_type, &append_extension)) {
- if (append_extension != FILE_PATH_LITERAL("txt") &&
- append_extension != extension &&
- !IsExecutableExtension(append_extension) &&
- !(append_extension == FILE_PATH_LITERAL("gz") &&
- extension == FILE_PATH_LITERAL("tgz")) &&
- (append_extension != FILE_PATH_LITERAL("tar") ||
- extension != FILE_PATH_LITERAL("tar.gz"))) {
- extension += FILE_PATH_LITERAL(".");
- extension += append_extension;
- }
- }
- }
-
- generated_extension->swap(extension);
-}
-
-void DownloadManager::GenerateFileNameFromInfo(DownloadCreateInfo* info,
- FilePath* generated_name) {
- GenerateFileName(GURL(info->url),
- info->content_disposition,
- info->referrer_charset,
- info->mime_type,
- generated_name);
-}
-
-void DownloadManager::GenerateFileName(const GURL& url,
- const std::string& content_disposition,
- const std::string& referrer_charset,
- const std::string& mime_type,
- FilePath* generated_name) {
- std::wstring default_name =
- l10n_util::GetString(IDS_DEFAULT_DOWNLOAD_FILENAME);
-#if defined(OS_WIN)
- FilePath default_file_path(default_name);
-#elif defined(OS_POSIX)
- FilePath default_file_path(base::SysWideToNativeMB(default_name));
-#endif
-
- *generated_name = net::GetSuggestedFilename(GURL(url),
- content_disposition,
- referrer_charset,
- default_file_path);
-
- DCHECK(!generated_name->empty());
-
- GenerateSafeFileName(mime_type, generated_name);
-}
-
void DownloadManager::AddObserver(Observer* observer) {
observers_.AddObserver(observer);
observer->ModelChanged();
@@ -1036,66 +897,12 @@ void DownloadManager::OpenDownload(const DownloadItem* download,
// Open Chrome extensions with ExtensionsService. For everything else do shell
// execute.
if (download->is_extension_install()) {
- OpenChromeExtension(download->full_path(),
- download->url(),
- download->referrer_url(),
- download->original_mime_type());
+ download_util::OpenChromeExtension(profile_, this, *download);
} else {
OpenDownloadInShell(download, parent_window);
}
}
-void DownloadManager::OpenChromeExtension(
- const FilePath& full_path,
- const GURL& download_url,
- const GURL& referrer_url,
- const std::string& original_mime_type) {
- // We don't support extensions in OTR mode.
- ExtensionsService* service = profile_->GetExtensionsService();
- if (service) {
- NotificationService* nservice = NotificationService::current();
- GURL nonconst_download_url = download_url;
- nservice->Notify(NotificationType::EXTENSION_READY_FOR_INSTALL,
- Source<DownloadManager>(this),
- Details<GURL>(&nonconst_download_url));
-
- scoped_refptr<CrxInstaller> installer(
- new CrxInstaller(service->install_directory(),
- service,
- new ExtensionInstallUI(profile_)));
- installer->set_delete_source(true);
-
- if (UserScript::HasUserScriptFileExtension(download_url)) {
- installer->InstallUserScript(full_path, download_url);
- } else {
- bool is_gallery_download =
- ExtensionsService::IsDownloadFromGallery(download_url, referrer_url);
- installer->set_original_mime_type(original_mime_type);
- installer->set_apps_require_extension_mime_type(true);
- installer->set_allow_privilege_increase(true);
- installer->set_original_url(download_url);
- installer->set_limit_web_extent_to_download_host(!is_gallery_download);
- installer->InstallCrx(full_path);
- }
- } else {
- TabContents* contents = NULL;
- // Get last active normal browser of profile.
- Browser* last_active = BrowserList::FindBrowserWithType(profile_,
- Browser::TYPE_NORMAL, true);
- if (last_active)
- contents = last_active->GetSelectedTabContents();
- if (contents) {
- contents->AddInfoBar(
- new SimpleAlertInfoBarDelegate(contents,
- l10n_util::GetString(
- IDS_EXTENSION_INCOGNITO_INSTALL_INFOBAR_LABEL),
- ResourceBundle::GetSharedInstance().GetBitmapNamed(
- IDR_INFOBAR_PLUGIN_INSTALL),
- true));
- }
- }
-}
-
void DownloadManager::OpenDownloadInShell(const DownloadItem* download,
gfx::NativeView parent_window) {
DCHECK(file_manager_);
@@ -1119,7 +926,7 @@ void DownloadManager::OpenFilesBasedOnExtension(
return;
DCHECK(extension[0] == FilePath::kExtensionSeparator);
extension.erase(0, 1);
- if (open && !IsExecutableExtension(extension))
+ if (open && !download_util::IsExecutableExtension(extension))
auto_open_.insert(extension);
else
auto_open_.erase(extension);
@@ -1131,7 +938,7 @@ bool DownloadManager::ShouldOpenFileBasedOnExtension(
FilePath::StringType extension = path.Extension();
if (extension.empty())
return false;
- if (IsExecutableExtension(extension))
+ if (download_util::IsExecutableExtension(extension))
return false;
if (Extension::IsExtension(path))
return false;
@@ -1142,59 +949,8 @@ bool DownloadManager::ShouldOpenFileBasedOnExtension(
return false;
}
-static const char* kExecutableWhiteList[] = {
- // JavaScript is just as powerful as EXE.
- "text/javascript",
- "text/javascript;version=*",
- // Registry files can cause critical changes to the MS OS behavior.
- // Addition of this mimetype also addresses bug 7337.
- "text/x-registry",
- // Some sites use binary/octet-stream to mean application/octet-stream.
- // See http://code.google.com/p/chromium/issues/detail?id=1573
- "binary/octet-stream"
-};
-
-static const char* kExecutableBlackList[] = {
- // These application types are not executable.
- "application/*+xml",
- "application/xml"
-};
-
-// static
-bool DownloadManager::IsExecutableMimeType(const std::string& mime_type) {
- for (size_t i = 0; i < arraysize(kExecutableWhiteList); ++i) {
- if (net::MatchesMimeType(kExecutableWhiteList[i], mime_type))
- return true;
- }
- for (size_t i = 0; i < arraysize(kExecutableBlackList); ++i) {
- if (net::MatchesMimeType(kExecutableBlackList[i], mime_type))
- return false;
- }
- // We consider only other application types to be executable.
- return net::MatchesMimeType("application/*", mime_type);
-}
-
bool DownloadManager::IsExecutableFile(const FilePath& path) const {
- return IsExecutableExtension(path.Extension());
-}
-
-bool DownloadManager::IsExecutableExtension(
- const FilePath::StringType& extension) {
- if (extension.empty())
- return false;
- if (!IsStringASCII(extension))
- return false;
-#if defined(OS_WIN)
- std::string ascii_extension = WideToASCII(extension);
-#elif defined(OS_POSIX)
- std::string ascii_extension = extension;
-#endif
-
- // Strip out leading dot if it's still there
- if (ascii_extension[0] == FilePath::kExtensionSeparator)
- ascii_extension.erase(0, 1);
-
- return download_util::IsExecutableExtension(ascii_extension);
+ return download_util::IsExecutableExtension(path.Extension());
}
void DownloadManager::ResetAutoOpenFiles() {
@@ -1253,12 +1009,6 @@ void DownloadManager::FileSelectionCanceled(void* params) {
info->request_id);
}
-void DownloadManager::DeleteDownload(const FilePath& path) {
- ChromeThread::PostTask(
- ChromeThread::FILE, FROM_HERE,
- NewRunnableFunction(&DeleteDownloadedFile, path));
-}
-
void DownloadManager::DangerousDownloadValidated(DownloadItem* download) {
DCHECK_EQ(DownloadItem::DANGEROUS, download->safety_state());
download->set_safety_state(DownloadItem::DANGEROUS_BUT_VALIDATED);
@@ -1277,29 +1027,6 @@ void DownloadManager::DangerousDownloadValidated(DownloadItem* download) {
download->original_name()));
}
-void DownloadManager::GenerateSafeFileName(const std::string& mime_type,
- FilePath* file_name) {
- // Make sure we get the right file extension
- FilePath::StringType extension;
- GenerateExtension(*file_name, mime_type, &extension);
- *file_name = file_name->ReplaceExtension(extension);
-
-#if defined(OS_WIN)
- // Prepend "_" to the file name if it's a reserved name
- FilePath::StringType leaf_name = file_name->BaseName().value();
- DCHECK(!leaf_name.empty());
- if (win_util::IsReservedName(leaf_name)) {
- leaf_name = FilePath::StringType(FILE_PATH_LITERAL("_")) + leaf_name;
- *file_name = file_name->DirName();
- if (file_name->value() == FilePath::kCurrentDirectory) {
- *file_name = FilePath(leaf_name);
- } else {
- *file_name = file_name->Append(leaf_name);
- }
- }
-#endif
-}
-
// Operations posted to us from the history service ----------------------------
// The history service has retrieved all download entries. 'entries' contains
« no previous file with comments | « chrome/browser/download/download_manager.h ('k') | chrome/browser/download/download_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698