| Index: shell/application_manager/network_fetcher.cc
|
| diff --git a/shell/application_manager/network_fetcher.cc b/shell/application_manager/network_fetcher.cc
|
| index 05aba7ab3605b5837b5acdb53e789b03f50c0246..349911ccaeafba4de5140a664bbfa8e8faa9ab3a 100644
|
| --- a/shell/application_manager/network_fetcher.cc
|
| +++ b/shell/application_manager/network_fetcher.cc
|
| @@ -5,6 +5,7 @@
|
| #include "shell/application_manager/network_fetcher.h"
|
|
|
| #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"
|
| @@ -20,6 +21,7 @@
|
| #include "mojo/common/data_pipe_utils.h"
|
| #include "mojo/services/network/public/interfaces/network_service.mojom.h"
|
| #include "shell/application_manager/data_pipe_peek.h"
|
| +#include "shell/switches.h"
|
|
|
| namespace mojo {
|
| namespace shell {
|
| @@ -85,8 +87,9 @@ void NetworkFetcher::RecordCacheToURLMapping(const base::FilePath& path,
|
| base::AppendToFile(map_path, map_entry.data(), map_entry.length());
|
| }
|
|
|
| -// AppIds should be be both predictable and unique, but any hash would work.
|
| -// Currently we use sha256 from crypto/secure_hash.h
|
| +// For remote debugging, GDB needs to be, a apriori, aware of the filename a
|
| +// library will be loaded from. AppIds should be be both predictable and unique,
|
| +// but any hash would work. Currently we use sha256 from crypto/secure_hash.h
|
| bool NetworkFetcher::ComputeAppId(const base::FilePath& path,
|
| std::string* digest_string) {
|
| scoped_ptr<crypto::SecureHash> ctx(
|
| @@ -116,35 +119,55 @@ bool NetworkFetcher::ComputeAppId(const base::FilePath& path,
|
| return true;
|
| }
|
|
|
| -bool NetworkFetcher::RenameToAppId(const base::FilePath& old_path,
|
| +bool NetworkFetcher::RenameToAppId(const GURL& url,
|
| + const base::FilePath& old_path,
|
| base::FilePath* new_path) {
|
| std::string app_id;
|
| if (!ComputeAppId(old_path, &app_id))
|
| return false;
|
|
|
| + // Using a hash of the url as a directory to prevent a race when the same
|
| + // bytes are downloaded from 2 different urls. In particular, if the same
|
| + // application is connected to twice concurrently with different query
|
| + // parameters, the directory will be different, which will prevent the
|
| + // collision.
|
| + std::string dirname = base::HexEncode(
|
| + crypto::SHA256HashString(url.spec()).data(), crypto::kSHA256Length);
|
| +
|
| base::FilePath temp_dir;
|
| base::GetTempDir(&temp_dir);
|
| + base::FilePath app_dir = temp_dir.Append(dirname);
|
| + // The directory is leaked, because it can be reused at any time if the same
|
| + // application is downloaded. Deleting it would be racy. This is only
|
| + // happening when --predictable-app-filenames is used.
|
| + bool result = base::CreateDirectoryAndGetError(app_dir, nullptr);
|
| + DCHECK(result);
|
| std::string unique_name = base::StringPrintf("%s.mojo", app_id.c_str());
|
| - *new_path = temp_dir.Append(unique_name);
|
| + *new_path = app_dir.Append(unique_name);
|
| return base::Move(old_path, *new_path);
|
| }
|
|
|
| void NetworkFetcher::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_);
|
| + if (base::CommandLine::ForCurrentProcess()->HasSwitch(
|
| + switches::kPredictableAppFilenames)) {
|
| + // The copy completed, now move to $TMP/$APP_ID.mojo before the dlopen.
|
| + success = false;
|
| + base::FilePath new_path;
|
| + if (RenameToAppId(url_, path_, &new_path)) {
|
| + if (base::PathExists(new_path)) {
|
| + path_ = new_path;
|
| + success = true;
|
| + }
|
| }
|
| }
|
| }
|
|
|
| + if (success)
|
| + RecordCacheToURLMapping(path_, url_);
|
| +
|
| base::MessageLoop::current()->PostTask(FROM_HERE,
|
| base::Bind(callback, path_, success));
|
| }
|
|
|