Chromium Code Reviews| Index: shell/dynamic_application_loader.cc |
| diff --git a/shell/dynamic_application_loader.cc b/shell/dynamic_application_loader.cc |
| index 374484531eaba8ca9b5b7f9f5703bfdeeaf22309..21ebf40dc6fa7884d679ce1c7614b73bc8249851 100644 |
| --- a/shell/dynamic_application_loader.cc |
| +++ b/shell/dynamic_application_loader.cc |
| @@ -6,10 +6,12 @@ |
| #include "base/bind.h" |
| #include "base/command_line.h" |
| +#include "base/files/file.h" |
| #include "base/files/file_path.h" |
| #include "base/files/file_util.h" |
| #include "base/format_macros.h" |
| #include "base/logging.h" |
| +#include "base/md5.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/message_loop/message_loop.h" |
| @@ -296,7 +298,7 @@ class DynamicApplicationLoader::NetworkLoader : public Loader { |
| // TODO(eseidel): Paths or URLs with spaces will need quoting. |
| std::string map_entry = |
| - base::StringPrintf("%s %s\n", path.value().data(), url.spec().data()); |
| + base::StringPrintf("%s %s\n", path.value().c_str(), url.spec().c_str()); |
| // TODO(eseidel): AppendToFile is missing O_CREAT, crbug.com/450696 |
| if (!PathExists(map_path)) |
| base::WriteFile(map_path, map_entry.data(), map_entry.length()); |
| @@ -304,6 +306,68 @@ class DynamicApplicationLoader::NetworkLoader : public Loader { |
| base::AppendToFile(map_path, map_entry.data(), map_entry.length()); |
| } |
| + // AppIds should be be both predictable and unique, but any crypto would work. |
|
Aaron Boodman
2015/01/23 22:56:01
nit: s/crypto/hash.
|
| + // TODO(eseidel): Use sha256 once it has an incremental API, crbug.com/451588 |
| + // Derived from tools/android/md5sum/md5sum.cc with fstream usage removed. |
| + static bool ComputeAppId(const base::FilePath& path, |
| + std::string* digest_string) { |
| + |
| + base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ); |
| + if (!file.IsValid()) { |
| + LOG(ERROR) << "Failed to open " << path.value() << " for computing AppId"; |
| + return false; |
| + } |
| + base::MD5Context ctx; |
| + base::MD5Init(&ctx); |
| + char buf[1024]; |
| + while (file.IsValid()) { |
| + int bytes_read = file.ReadAtCurrentPos(buf, sizeof(buf)); |
| + if (bytes_read == 0) |
| + break; |
| + base::MD5Update(&ctx, base::StringPiece(buf, bytes_read)); |
| + } |
| + if (!file.IsValid()) { |
| + LOG(ERROR) << "Error reading " << path.value(); |
| + return false; |
| + } |
| + base::MD5Digest digest; |
| + base::MD5Final(&digest, &ctx); |
| + *digest_string = base::MD5DigestToBase16(digest); |
| + return true; |
| + } |
| + |
| + static bool RenameToAppId(const base::FilePath& old_path, |
| + base::FilePath* new_path) { |
| + std::string app_id; |
| + if (!ComputeAppId(old_path, &app_id)) |
| + return false; |
| + |
| + base::FilePath temp_dir; |
| + base::GetTempDir(&temp_dir); |
| + std::string unique_name = base::StringPrintf("%s.mojo", app_id.c_str()); |
| + *new_path = temp_dir.Append(unique_name); |
| + return base::Move(old_path, *new_path); |
| + } |
| + |
| + void CopyCompleted(base::Callback<void(const base::FilePath&, bool)> callback, |
| + bool success) { |
| + // The copy completed, now move to $TMP/$APP_ID.mojo before the dlopen. |
| + if (success) { |
| + success = false; |
| + base::FilePath new_path; |
| + if (RenameToAppId(path_, &new_path)) { |
| + if (base::PathExists(new_path)) { |
| + path_ = new_path; |
| + success = true; |
| + RecordCacheToURLMapping(path_, url_); |
| + } |
| + } |
| + } |
| + |
| + base::MessageLoop::current()->PostTask( |
| + FROM_HERE, base::Bind(callback, path_, success)); |
| + } |
| + |
| void AsPath( |
| base::TaskRunner* task_runner, |
| base::Callback<void(const base::FilePath&, bool)> callback) override { |
| @@ -312,14 +376,11 @@ class DynamicApplicationLoader::NetworkLoader : public Loader { |
| FROM_HERE, base::Bind(callback, path_, base::PathExists(path_))); |
| return; |
| } |
| - // We don't use the created file, just want the directory and random name. |
| + |
| base::CreateTemporaryFile(&path_); |
| - base::DeleteFile(path_, false); |
| - path_ = path_.AddExtension(".mojo"); // Make libraries easy to spot. |
| common::CopyToFile(response_->body.Pass(), path_, task_runner, |
| - base::Bind(callback, path_)); |
| - |
| - RecordCacheToURLMapping(path_, url_); |
| + base::Bind(&NetworkLoader::CopyCompleted, |
| + weak_ptr_factory_.GetWeakPtr(), callback)); |
| } |
| std::string MimeType() override { |