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

Side by Side Diff: mojo/shell/dynamic_application_loader.cc

Issue 696543003: Mojo content handler shebang support (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Relocated data pipe peek utilities, added basic content-handler detection 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 unified diff | Download patch
« no previous file with comments | « mojo/shell/data_pipe_peek_unittest.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "mojo/shell/dynamic_application_loader.h" 5 #include "mojo/shell/dynamic_application_loader.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/files/file_path.h" 9 #include "base/files/file_path.h"
10 #include "base/files/file_util.h" 10 #include "base/files/file_util.h"
11 #include "base/memory/scoped_ptr.h" 11 #include "base/memory/scoped_ptr.h"
12 #include "base/memory/weak_ptr.h" 12 #include "base/memory/weak_ptr.h"
13 #include "base/message_loop/message_loop.h" 13 #include "base/message_loop/message_loop.h"
14 #include "base/strings/utf_string_conversions.h" 14 #include "base/strings/utf_string_conversions.h"
15 #include "mojo/common/common_type_converters.h" 15 #include "mojo/common/common_type_converters.h"
16 #include "mojo/common/data_pipe_utils.h" 16 #include "mojo/common/data_pipe_utils.h"
17 #include "mojo/services/public/interfaces/network/url_loader.mojom.h" 17 #include "mojo/services/public/interfaces/network/url_loader.mojom.h"
18 #include "mojo/shell/context.h" 18 #include "mojo/shell/context.h"
19 #include "mojo/shell/data_pipe_peek.h"
19 #include "mojo/shell/filename_util.h" 20 #include "mojo/shell/filename_util.h"
20 #include "mojo/shell/switches.h" 21 #include "mojo/shell/switches.h"
21 #include "url/url_util.h" 22 #include "url/url_util.h"
22 23
23 namespace mojo { 24 namespace mojo {
24 namespace shell { 25 namespace shell {
25 26
26 // Encapsulates loading and running one individual application. 27 // Encapsulates loading and running one individual application.
27 // 28 //
28 // Loaders are owned by DynamicApplicationLoader. DynamicApplicationLoader must 29 // Loaders are owned by DynamicApplicationLoader. DynamicApplicationLoader must
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 base::Bind(&NetworkLoader::OnLoadComplete, 152 base::Bind(&NetworkLoader::OnLoadComplete,
152 weak_ptr_factory_.GetWeakPtr())); 153 weak_ptr_factory_.GetWeakPtr()));
153 } 154 }
154 155
155 ~NetworkLoader() override { 156 ~NetworkLoader() override {
156 if (!file_.empty()) 157 if (!file_.empty())
157 base::DeleteFile(file_, false); 158 base::DeleteFile(file_, false);
158 } 159 }
159 160
160 private: 161 private:
162 bool PeekContentHandler(DataPipeConsumerHandle source,
163 std::string* mojo_shebang,
164 GURL* mojo_content_handler_url)
165 {
166 const std::string kMojoMagic("#!mojo:");
Aaron Boodman 2014/11/03 23:50:36 No real reason to make this a string, const char*
hansmuller 2014/11/04 00:26:03 Done.
167 const MojoDeadline kPeekTimeout = 1000 * 5; // 5ms
Aaron Boodman 2014/11/03 23:50:36 urgh. Can you put a TODO on this to fix once peeki
hansmuller 2014/11/04 00:26:03 Done. I've defeated the timeout for now, it's MOJO
168 const size_t kMaxShebangLength = 2048;
169
170 std::string magic;
171 std::string shebang;
172 if (BlockingPeekNBytes(source, &magic, kMojoMagic.size(), kPeekTimeout) &&
173 magic == kMojoMagic &&
174 BlockingPeekLine(source, &shebang, kMaxShebangLength, kPeekTimeout)) {
175 GURL url(shebang.substr(2, std::string::npos));
176 if (url.is_valid()) {
177 *mojo_shebang = shebang;
178 *mojo_content_handler_url = url;
179 return true;
180 }
181 }
182 return false;
183 }
184
161 void OnLoadComplete(URLResponsePtr response) { 185 void OnLoadComplete(URLResponsePtr response) {
Aaron Boodman 2014/11/03 23:50:36 Note that this is about to move around some: http
hansmuller 2014/11/04 00:26:03 It looks like the shebang code will merge with qsr
162 if (response->error) { 186 if (response->error) {
163 LOG(ERROR) << "Error (" << response->error->code << ": " 187 LOG(ERROR) << "Error (" << response->error->code << ": "
164 << response->error->description << ") while fetching " 188 << response->error->description << ") while fetching "
165 << response->url; 189 << response->url;
166 LoaderComplete(); 190 LoaderComplete();
167 return; 191 return;
168 } 192 }
169 193
194 // If the response begins with a #!mojo:<content-handler-url>, use it.
195 {
196 GURL url;
197 std::string shebang;
198 if (PeekContentHandler(response->body.get(), &shebang, &url)) {
199 // TBD(hansmuller): content-handlers should skip the shebang themselves.
Aaron Boodman 2014/11/03 23:50:36 I'm not sure I agree with this statement. How abo
hansmuller 2014/11/04 00:26:03 I thought that content-handlers would check the sh
200 uint32_t num_skip_bytes = shebang.size();
201 if (ReadDataRaw(response->body.get(),
202 nullptr,
203 &num_skip_bytes,
204 MOJO_READ_DATA_FLAG_ALL_OR_NONE |
205 MOJO_READ_DATA_FLAG_DISCARD) ==
206 MOJO_RESULT_OK) {
207 load_callbacks_->LoadWithContentHandler(url, response.Pass());
208 return;
209 }
210 }
211 }
212
170 MimeTypeToURLMap::iterator iter = 213 MimeTypeToURLMap::iterator iter =
171 mime_type_to_url_->find(response->mime_type); 214 mime_type_to_url_->find(response->mime_type);
172 if (iter != mime_type_to_url_->end()) { 215 if (iter != mime_type_to_url_->end()) {
173 load_callbacks_->LoadWithContentHandler(iter->second, response.Pass()); 216 load_callbacks_->LoadWithContentHandler(iter->second, response.Pass());
174 return; 217 return;
175 } 218 }
176 219
177 LOG(INFO) << "Failed to find content handler for " << response->url 220 LOG(WARNING) << "Failed to find content handler for " << response->url
Aaron Boodman 2014/11/03 23:50:36 Let's just remove this. I don't think it warrants
hansmuller 2014/11/04 00:26:03 Done.
178 << " (mimetype: " << response->url << ")" << std::endl 221 << " (mimetype: " << response->url << ")" << std::endl
179 << "Attempting to load as native library instead..."; 222 << "Attempting to load as native library instead...";
180 223
181 // TODO(aa): Santify check that the thing we got looks vaguely like a mojo 224 // TODO(aa): Sanity check that the thing we got looks vaguely like a mojo
182 // application. That could either mean looking for the platform-specific dll 225 // application. That could either mean looking for the platform-specific dll
183 // header, or looking for some specific mojo signature prepended to the 226 // header, or looking for some specific mojo signature prepended to the
184 // library. 227 // library.
185 228
186 base::CreateTemporaryFile(&file_); 229 base::CreateTemporaryFile(&file_);
187 common::CopyToFile( 230 common::CopyToFile(
188 response->body.Pass(), 231 response->body.Pass(),
189 file_, 232 file_,
190 context_->task_runners()->blocking_pool(), 233 context_->task_runners()->blocking_pool(),
191 base::Bind( 234 base::Bind(
192 &NetworkLoader::RunLibrary, weak_ptr_factory_.GetWeakPtr(), file_)); 235 &NetworkLoader::RunLibrary, weak_ptr_factory_.GetWeakPtr(), file_));
193 } 236 }
194 237
195 MimeTypeToURLMap* mime_type_to_url_; 238 MimeTypeToURLMap* mime_type_to_url_;
196 URLLoaderPtr url_loader_; 239 URLLoaderPtr url_loader_;
197 base::FilePath file_; 240 base::FilePath file_;
198 base::WeakPtrFactory<NetworkLoader> weak_ptr_factory_; 241 base::WeakPtrFactory<NetworkLoader> weak_ptr_factory_;
199 }; 242 };
200
201 DynamicApplicationLoader::DynamicApplicationLoader( 243 DynamicApplicationLoader::DynamicApplicationLoader(
202 Context* context, 244 Context* context,
203 scoped_ptr<DynamicServiceRunnerFactory> runner_factory) 245 scoped_ptr<DynamicServiceRunnerFactory> runner_factory)
204 : context_(context), 246 : context_(context),
205 runner_factory_(runner_factory.Pass()), 247 runner_factory_(runner_factory.Pass()),
206 248
207 // Unretained() is correct here because DynamicApplicationLoader owns the 249 // Unretained() is correct here because DynamicApplicationLoader owns the
208 // loaders that we pass this callback to. 250 // loaders that we pass this callback to.
209 loader_complete_callback_( 251 loader_complete_callback_(
210 base::Bind(&DynamicApplicationLoader::LoaderComplete, 252 base::Bind(&DynamicApplicationLoader::LoaderComplete,
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 // TODO(darin): What should we do about service errors? This implies that 301 // TODO(darin): What should we do about service errors? This implies that
260 // the app closed its handle to the service manager. Maybe we don't care? 302 // the app closed its handle to the service manager. Maybe we don't care?
261 } 303 }
262 304
263 void DynamicApplicationLoader::LoaderComplete(Loader* loader) { 305 void DynamicApplicationLoader::LoaderComplete(Loader* loader) {
264 loaders_.erase(std::find(loaders_.begin(), loaders_.end(), loader)); 306 loaders_.erase(std::find(loaders_.begin(), loaders_.end(), loader));
265 } 307 }
266 308
267 } // namespace shell 309 } // namespace shell
268 } // namespace mojo 310 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/shell/data_pipe_peek_unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698