| OLD | NEW |
| (Empty) |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "base/files/file_util.h" | |
| 6 #include "base/files/scoped_file.h" | |
| 7 #include "base/message_loop/message_loop.h" | |
| 8 #include "build/build_config.h" | |
| 9 #include "mojo/application/content_handler_factory.h" | |
| 10 #include "mojo/data_pipe_utils/data_pipe_utils.h" | |
| 11 #include "mojo/environment/scoped_chromium_init.h" | |
| 12 #include "mojo/message_pump/message_pump_mojo.h" | |
| 13 #include "mojo/nacl/sfi/nacl_bindings/monacl_sel_main.h" | |
| 14 #include "mojo/public/c/system/main.h" | |
| 15 #include "mojo/public/cpp/application/application_impl_base.h" | |
| 16 #include "mojo/public/cpp/application/connect.h" | |
| 17 #include "mojo/public/cpp/application/run_application.h" | |
| 18 #include "mojo/public/cpp/application/service_provider_impl.h" | |
| 19 #include "mojo/services/network/interfaces/network_service.mojom.h" | |
| 20 #include "mojo/services/network/interfaces/url_loader.mojom.h" | |
| 21 #include "native_client/src/public/nacl_desc.h" | |
| 22 #include "url/gurl.h" | |
| 23 | |
| 24 namespace nacl { | |
| 25 namespace content_handler { | |
| 26 | |
| 27 namespace { | |
| 28 base::ScopedFILE TempFileForURL(mojo::URLLoaderPtr& url_loader, | |
| 29 const GURL& url) { | |
| 30 mojo::URLRequestPtr request(mojo::URLRequest::New()); | |
| 31 request->url = url.spec(); | |
| 32 request->method = "GET"; | |
| 33 request->auto_follow_redirects = true; | |
| 34 | |
| 35 // Handle the callback synchonously. | |
| 36 mojo::URLResponsePtr response; | |
| 37 url_loader->Start(request.Pass(), [&response](mojo::URLResponsePtr r) { | |
| 38 response = r.Pass(); | |
| 39 }); | |
| 40 url_loader.WaitForIncomingResponse(); | |
| 41 CHECK(!response.is_null()) << "Empty response (missed a callback?)"; | |
| 42 | |
| 43 if (response->error) { | |
| 44 LOG(ERROR) << "could not load " << url.spec() << " (" | |
| 45 << response->error->code << ") " | |
| 46 << response->error->description.get().c_str(); | |
| 47 return nullptr; | |
| 48 } | |
| 49 | |
| 50 return mojo::common::BlockingCopyToTempFile(response->body.Pass()); | |
| 51 } | |
| 52 | |
| 53 NaClDesc* FileStreamToNaClDesc(FILE* file_stream) { | |
| 54 // Get file handle | |
| 55 int fd = fileno(file_stream); | |
| 56 CHECK_NE(fd, -1) << "Could not open the stream pointer's file descriptor"; | |
| 57 | |
| 58 // These file descriptors must be dup'd, since NaClDesc takes ownership | |
| 59 // of the file descriptor. The descriptor is still needed to close | |
| 60 // the file stream. | |
| 61 fd = dup(fd); | |
| 62 CHECK_NE(fd, -1) << "Could not dup the file descriptor"; | |
| 63 | |
| 64 NaClDesc* desc = NaClDescCreateWithFilePathMetadata(fd, ""); | |
| 65 | |
| 66 // Clean up. | |
| 67 CHECK_EQ(fclose(file_stream), 0) << "Failed to close temp file"; | |
| 68 | |
| 69 return desc; | |
| 70 } | |
| 71 | |
| 72 } // namespace | |
| 73 | |
| 74 class NaClContentHandler : public mojo::ApplicationImplBase, | |
| 75 public mojo::ContentHandlerFactory::Delegate { | |
| 76 public: | |
| 77 NaClContentHandler() {} | |
| 78 | |
| 79 private: | |
| 80 // Overridden from ApplicationImplBase: | |
| 81 void OnInitialize() override { | |
| 82 url_ = GURL(url()); | |
| 83 | |
| 84 mojo::NetworkServicePtr network_service; | |
| 85 mojo::ConnectToService(shell(), "mojo:network_service", | |
| 86 GetProxy(&network_service)); | |
| 87 | |
| 88 network_service->CreateURLLoader(GetProxy(&url_loader_)); | |
| 89 } | |
| 90 | |
| 91 // Overridden from ApplicationImplBase: | |
| 92 bool OnAcceptConnection( | |
| 93 mojo::ServiceProviderImpl* service_provider_impl) override { | |
| 94 service_provider_impl->AddService<mojo::ContentHandler>( | |
| 95 mojo::ContentHandlerFactory::GetInterfaceRequestHandler(this)); | |
| 96 return true; | |
| 97 } | |
| 98 | |
| 99 void LoadIRT(mojo::URLLoaderPtr& url_loader) { | |
| 100 // TODO(ncbray): support other architectures. | |
| 101 GURL irt_url; | |
| 102 #if defined(ARCH_CPU_X86_64) | |
| 103 irt_url = url_.Resolve("irt_x64/irt_mojo.nexe"); | |
| 104 #else | |
| 105 #error "Unknown / unsupported CPU architecture." | |
| 106 #endif | |
| 107 CHECK(irt_url.is_valid()) << "Cannot resolve IRT URL"; | |
| 108 | |
| 109 irt_fp_ = TempFileForURL(url_loader, irt_url); | |
| 110 CHECK(irt_fp_) << "Could not acquire the IRT"; | |
| 111 } | |
| 112 | |
| 113 // Overridden from ContentHandlerFactory::Delegate: | |
| 114 void RunApplication( | |
| 115 mojo::InterfaceRequest<mojo::Application> application_request, | |
| 116 mojo::URLResponsePtr response) override { | |
| 117 // Needed to use Mojo interfaces on this thread. | |
| 118 base::MessageLoop loop(mojo::common::MessagePumpMojo::Create()); | |
| 119 | |
| 120 // Acquire the nexe. | |
| 121 base::ScopedFILE nexe_fp = | |
| 122 mojo::common::BlockingCopyToTempFile(response->body.Pass()); | |
| 123 CHECK(nexe_fp) << "could not redirect nexe to temp file"; | |
| 124 | |
| 125 // Acquire the IRT. | |
| 126 mojo::URLLoaderPtr url_loader = url_loader_.Pass(); | |
| 127 LoadIRT(url_loader); | |
| 128 | |
| 129 NaClDesc* irt_desc = FileStreamToNaClDesc(irt_fp_.release()); | |
| 130 NaClDesc* nexe_desc = FileStreamToNaClDesc(nexe_fp.release()); | |
| 131 | |
| 132 // Run. | |
| 133 int exit_code = mojo::LaunchNaCl( | |
| 134 nexe_desc, irt_desc, 0, nullptr, | |
| 135 application_request.PassMessagePipe().release().value()); | |
| 136 | |
| 137 // Exits the process cleanly, does not return. | |
| 138 mojo::NaClExit(exit_code); | |
| 139 NOTREACHED(); | |
| 140 } | |
| 141 | |
| 142 GURL url_; | |
| 143 base::ScopedFILE irt_fp_; | |
| 144 | |
| 145 mojo::URLLoaderPtr url_loader_; | |
| 146 | |
| 147 DISALLOW_COPY_AND_ASSIGN(NaClContentHandler); | |
| 148 }; | |
| 149 | |
| 150 } // namespace content_handler | |
| 151 } // namespace nacl | |
| 152 | |
| 153 MojoResult MojoMain(MojoHandle application_request) { | |
| 154 mojo::ScopedChromiumInit init; | |
| 155 nacl::content_handler::NaClContentHandler nacl_content_handler; | |
| 156 return mojo::RunApplication(application_request, &nacl_content_handler); | |
| 157 } | |
| OLD | NEW |