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

Unified Diff: mojo/shell/dynamic_application_loader.cc

Issue 694303002: Allow local file to run though content handler. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Remove mime mapping Created 6 years, 1 month 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
« mojo/common/data_pipe_utils.cc ('K') | « mojo/common/data_pipe_utils.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: mojo/shell/dynamic_application_loader.cc
diff --git a/mojo/shell/dynamic_application_loader.cc b/mojo/shell/dynamic_application_loader.cc
index 71dcada0d129f2125307e42199d59ae6da248cc3..b7d745c770e1b67c9571615fde76f7d071bc5ab7 100644
--- a/mojo/shell/dynamic_application_loader.cc
+++ b/mojo/shell/dynamic_application_loader.cc
@@ -8,12 +8,16 @@
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
+#include "base/format_macros.h"
+#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
+#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "mojo/common/common_type_converters.h"
#include "mojo/common/data_pipe_utils.h"
+#include "mojo/public/cpp/system/data_pipe.h"
#include "mojo/services/public/interfaces/network/url_loader.mojom.h"
#include "mojo/shell/context.h"
#include "mojo/shell/filename_util.h"
@@ -23,6 +27,77 @@
namespace mojo {
namespace shell {
+namespace {
+
+void IgnoreResult(bool result) {
+}
+
+class LoaderResponse {
Aaron Boodman 2014/11/03 19:20:15 Is there some better way to factor this? It seems
qsr 2014/11/04 11:58:34 Not easily. But I can definitively make this class
Aaron Boodman 2014/11/04 18:05:01 Really? It seems like all the methods of this clas
qsr 2014/11/05 10:21:54 We could do this, but it would mean adding the fie
+ public:
+ explicit LoaderResponse(URLResponsePtr response)
+ : file_needs_cleanup_(true), response_(response.Pass()) {}
+ LoaderResponse(const GURL& url, base::FilePath path)
+ : file_needs_cleanup_(false), url_(url), path_(path) {}
+
+ ~LoaderResponse() {
+ if (file_needs_cleanup_ && !path_.empty())
+ base::DeleteFile(path_, false);
+ }
+
+ URLResponsePtr AsURLResponse(base::TaskRunner* task_runner) {
+ if (response_ || path_.empty())
+ return response_.Pass();
+ URLResponsePtr response(URLResponse::New());
+ response->url = String::From(url_);
+ DataPipe data_pipe;
+ response->body = data_pipe.consumer_handle.Pass();
+ int64 file_size;
+ if (base::GetFileSize(path_, &file_size)) {
+ response->headers = Array<String>(1);
+ response->headers[0] =
+ base::StringPrintf("Content-Length: %" PRId64, file_size);
+ }
+ common::CopyFromFile(path_,
+ data_pipe.producer_handle.Pass(),
+ task_runner,
+ base::Bind(&IgnoreResult));
Aaron Boodman 2014/11/04 18:05:00 I think you can also do this? base::Callback<void
qsr 2014/11/05 10:21:54 Not really. See the comment in base/task_runner_ut
+ return response.Pass();
+ }
+
+ void AsPath(base::TaskRunner* task_runner,
+ base::Callback<void(const base::FilePath&, bool)> callback) {
+ if (!path_.empty() || !response_) {
+ callback.Run(path_, base::PathExists(path_));
+ return;
+ }
+ base::CreateTemporaryFile(&path_);
+ common::CopyToFile(response_->body.Pass(),
+ path_,
+ task_runner,
+ base::Bind(callback, path_));
+ }
+
+ std::string MimeType() {
+ if (response_)
+ return response_->mime_type;
+ return "";
+ }
+
+ std::string Url() {
+ if (response_)
+ return response_->url;
+ return String::From(url_);
+ }
+
+ private:
+ bool file_needs_cleanup_;
+ URLResponsePtr response_;
+ GURL url_;
+ base::FilePath path_;
+};
+
+} // namespace
+
// Encapsulates loading and running one individual application.
//
// Loaders are owned by DynamicApplicationLoader. DynamicApplicationLoader must
@@ -35,12 +110,14 @@ namespace shell {
class DynamicApplicationLoader::Loader {
public:
Loader(Context* context,
+ MimeTypeToURLMap* mime_type_to_url,
DynamicServiceRunnerFactory* runner_factory,
scoped_refptr<ApplicationLoader::LoadCallbacks> load_callbacks,
const LoaderCompleteCallback& loader_complete_callback)
: load_callbacks_(load_callbacks),
loader_complete_callback_(loader_complete_callback),
context_(context),
+ mime_type_to_url_(mime_type_to_url),
runner_factory_(runner_factory),
weak_ptr_factory_(this) {}
@@ -71,9 +148,34 @@ class DynamicApplicationLoader::Loader {
void LoaderComplete() { loader_complete_callback_.Run(this); }
+ void OnResponse(scoped_ptr<LoaderResponse> response) {
+ MimeTypeToURLMap::iterator iter =
+ mime_type_to_url_->find(response->MimeType());
+ if (iter != mime_type_to_url_->end()) {
+ load_callbacks_->LoadWithContentHandler(
+ iter->second,
+ response->AsURLResponse(context_->task_runners()->blocking_pool()));
+ return;
+ }
+
+ LOG(INFO) << "Failed to find content handler for " << response->Url()
+ << " (mimetype: " << response->MimeType() << ")" << std::endl
+ << "Attempting to load as native library instead...";
+
+ // TODO(aa): Santify check that the thing we got looks vaguely like a mojo
+ // application. That could either mean looking for the platform-specific dll
+ // header, or looking for some specific mojo signature prepended to the
+ // library.
+
+ response->AsPath(
+ context_->task_runners()->blocking_pool(),
+ base::Bind(&Loader::RunLibrary, weak_ptr_factory_.GetWeakPtr()));
+ }
+
scoped_refptr<ApplicationLoader::LoadCallbacks> load_callbacks_;
LoaderCompleteCallback loader_complete_callback_;
Context* context_;
+ MimeTypeToURLMap* mime_type_to_url_;
private:
DynamicServiceRunnerFactory* runner_factory_;
@@ -86,14 +188,15 @@ class DynamicApplicationLoader::LocalLoader : public Loader {
public:
LocalLoader(const GURL& url,
Context* context,
+ MimeTypeToURLMap* mime_type_to_url,
DynamicServiceRunnerFactory* runner_factory,
scoped_refptr<ApplicationLoader::LoadCallbacks> load_callbacks,
const LoaderCompleteCallback& loader_complete_callback)
: Loader(context,
+ mime_type_to_url,
runner_factory,
load_callbacks,
- loader_complete_callback),
- weak_ptr_factory_(this) {
+ loader_complete_callback) {
DCHECK(url.SchemeIsFile());
url::RawCanonOutputW<1024> output;
url::DecodeURLEscapeSequences(
@@ -106,19 +209,10 @@ class DynamicApplicationLoader::LocalLoader : public Loader {
base::FilePath path(base::UTF16ToUTF8(decoded_path));
#endif
- // Async for consistency with network case.
- base::MessageLoop::current()->PostTask(
- FROM_HERE,
- base::Bind(&LocalLoader::RunLibrary,
- weak_ptr_factory_.GetWeakPtr(),
- path,
- base::PathExists(path)));
+ OnResponse(make_scoped_ptr(new LoaderResponse(url, path)));
}
~LocalLoader() override {}
-
- private:
- base::WeakPtrFactory<LocalLoader> weak_ptr_factory_;
};
// A loader for network files.
@@ -132,10 +226,10 @@ class DynamicApplicationLoader::NetworkLoader : public Loader {
scoped_refptr<ApplicationLoader::LoadCallbacks> load_callbacks,
const LoaderCompleteCallback& loader_complete_callback)
: Loader(context,
+ mime_type_to_url,
runner_factory,
load_callbacks,
loader_complete_callback),
- mime_type_to_url_(mime_type_to_url),
weak_ptr_factory_(this) {
URLRequestPtr request(URLRequest::New());
request->url = String::From(url);
@@ -152,11 +246,6 @@ class DynamicApplicationLoader::NetworkLoader : public Loader {
weak_ptr_factory_.GetWeakPtr()));
}
- ~NetworkLoader() override {
- if (!file_.empty())
- base::DeleteFile(file_, false);
- }
-
private:
void OnLoadComplete(URLResponsePtr response) {
if (response->error) {
@@ -167,34 +256,10 @@ class DynamicApplicationLoader::NetworkLoader : public Loader {
return;
}
- MimeTypeToURLMap::iterator iter =
- mime_type_to_url_->find(response->mime_type);
- if (iter != mime_type_to_url_->end()) {
- load_callbacks_->LoadWithContentHandler(iter->second, response.Pass());
- return;
- }
-
- LOG(INFO) << "Failed to find content handler for " << response->url
- << " (mimetype: " << response->url << ")" << std::endl
- << "Attempting to load as native library instead...";
-
- // TODO(aa): Santify check that the thing we got looks vaguely like a mojo
- // application. That could either mean looking for the platform-specific dll
- // header, or looking for some specific mojo signature prepended to the
- // library.
-
- base::CreateTemporaryFile(&file_);
- common::CopyToFile(
- response->body.Pass(),
- file_,
- context_->task_runners()->blocking_pool(),
- base::Bind(
- &NetworkLoader::RunLibrary, weak_ptr_factory_.GetWeakPtr(), file_));
+ OnResponse(make_scoped_ptr(new LoaderResponse(response.Pass())));
}
- MimeTypeToURLMap* mime_type_to_url_;
URLLoaderPtr url_loader_;
- base::FilePath file_;
base::WeakPtrFactory<NetworkLoader> weak_ptr_factory_;
};
@@ -234,6 +299,7 @@ void DynamicApplicationLoader::Load(
if (resolved_url.SchemeIsFile()) {
loaders_.push_back(new LocalLoader(resolved_url,
context_,
+ &mime_type_to_url_,
runner_factory_.get(),
load_callbacks,
loader_complete_callback_));
« mojo/common/data_pipe_utils.cc ('K') | « mojo/common/data_pipe_utils.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698