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

Side by Side Diff: services/nacl/content_handler_main.cc

Issue 1303343007: Created a blocking copy to temporary file function. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Less NULL, more nullptr Created 5 years, 3 months 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
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 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 "base/files/file_path.h"
6 #include "base/files/file_util.h" 5 #include "base/files/file_util.h"
6 #include "base/files/scoped_file.h"
7 #include "base/message_loop/message_loop.h" 7 #include "base/message_loop/message_loop.h"
8 #include "build/build_config.h" 8 #include "build/build_config.h"
9 #include "mojo/application/application_runner_chromium.h" 9 #include "mojo/application/application_runner_chromium.h"
10 #include "mojo/application/content_handler_factory.h" 10 #include "mojo/application/content_handler_factory.h"
11 #include "mojo/data_pipe_utils/data_pipe_utils.h" 11 #include "mojo/data_pipe_utils/data_pipe_utils.h"
12 #include "mojo/message_pump/message_pump_mojo.h" 12 #include "mojo/message_pump/message_pump_mojo.h"
13 #include "mojo/public/c/system/main.h" 13 #include "mojo/public/c/system/main.h"
14 #include "mojo/public/cpp/application/application_connection.h" 14 #include "mojo/public/cpp/application/application_connection.h"
15 #include "mojo/public/cpp/application/application_delegate.h" 15 #include "mojo/public/cpp/application/application_delegate.h"
16 #include "mojo/public/cpp/application/application_impl.h" 16 #include "mojo/public/cpp/application/application_impl.h"
17 #include "mojo/services/network/public/interfaces/network_service.mojom.h" 17 #include "mojo/services/network/public/interfaces/network_service.mojom.h"
18 #include "mojo/services/network/public/interfaces/url_loader.mojom.h" 18 #include "mojo/services/network/public/interfaces/url_loader.mojom.h"
19 #include "nacl_bindings/monacl_sel_main.h" 19 #include "nacl_bindings/monacl_sel_main.h"
20 #include "native_client/src/public/nacl_desc.h" 20 #include "native_client/src/public/nacl_desc.h"
21 #include "url/gurl.h" 21 #include "url/gurl.h"
22 22
23 namespace nacl { 23 namespace nacl {
24 namespace content_handler { 24 namespace content_handler {
25 25
26 namespace { 26 namespace {
27 bool URLResponseToTempFile(mojo::URLResponsePtr& response, 27 base::ScopedFILE TempFileForURL(mojo::URLLoaderPtr& url_loader,
28 base::FilePath* file_path) { 28 const GURL& url) {
29 if (!base::CreateTemporaryFile(file_path)) {
30 return false;
31 }
32
33 if (!mojo::common::BlockingCopyToFile(response->body.Pass(), *file_path)) {
34 base::DeleteFile(*file_path, false);
35 return false;
36 }
37
38 // TODO(ncbray): can we ensure temp file deletion even if we crash?
39 return true;
40 }
41
42 bool TempFileForURL(mojo::URLLoaderPtr& url_loader,
43 const GURL& url,
44 base::FilePath* path) {
45 mojo::URLRequestPtr request(mojo::URLRequest::New()); 29 mojo::URLRequestPtr request(mojo::URLRequest::New());
46 request->url = url.spec(); 30 request->url = url.spec();
47 request->method = "GET"; 31 request->method = "GET";
48 request->auto_follow_redirects = true; 32 request->auto_follow_redirects = true;
49 33
50 // Handle the callback synchonously. 34 // Handle the callback synchonously.
51 mojo::URLResponsePtr response; 35 mojo::URLResponsePtr response;
52 url_loader->Start(request.Pass(), [&response](mojo::URLResponsePtr r) { 36 url_loader->Start(request.Pass(), [&response](mojo::URLResponsePtr r) {
53 response = r.Pass(); 37 response = r.Pass();
54 }); 38 });
55 url_loader.WaitForIncomingResponse(); 39 url_loader.WaitForIncomingResponse();
56 if (response.is_null()) { 40 if (response.is_null()) {
57 LOG(FATAL) << "something went horribly wrong (missed a callback?)"; 41 LOG(FATAL) << "something went horribly wrong (missed a callback?)";
58 } 42 }
59 43
60 if (response->error) { 44 if (response->error) {
61 LOG(ERROR) << "could not load " << url.spec() << " (" 45 LOG(ERROR) << "could not load " << url.spec() << " ("
62 << response->error->code << ") " 46 << response->error->code << ") "
63 << response->error->description.get().c_str(); 47 << response->error->description.get().c_str();
64 return false; 48 return nullptr;
65 } 49 }
66 50
67 return URLResponseToTempFile(response, path); 51 return mojo::common::BlockingCopyToTempFile(response->body.Pass());
68 } 52 }
69 53
70 NaClDesc* NaClDescFromNexePath(base::FilePath& path) { 54 NaClDesc* FileStreamToNaClDesc(FILE* file_stream) {
71 base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ | 55 // Get file handle
72 base::File::FLAG_EXECUTE); 56 int fd = fileno(file_stream);
73 if (!file.IsValid()) { 57 if (fd == -1) {
74 LOG(FATAL) << "failed to open " << path.value(); 58 LOG(FATAL) << "Could not open the stream pointer's file descriptor";
75 } 59 }
76 // Note: potentially unsafe, assumes the file is immutable. This should be 60
77 // OK because we're currently only using temp files. 61 // These file descriptors must be dup'd, since NaClDesc takes ownership
78 return NaClDescCreateWithFilePathMetadata(file.TakePlatformFile(), 62 // of the file descriptor. The descriptor is still needed to close
79 path.AsUTF8Unsafe().c_str()); 63 // the file stream.
64 fd = dup(fd);
65 if (fd == -1) {
66 LOG(FATAL) << "Could not dup the file descriptor";
67 }
68
69 NaClDesc* desc = NaClDescCreateWithFilePathMetadata(fd, "");
70
71 // Clean up.
72 if (fclose(file_stream)) {
73 LOG(FATAL) << "Failed to close temp file";
74 }
75
76 return desc;
80 } 77 }
81 78
82 } // namespace 79 } // namespace
83 80
84 class NaClContentHandler : public mojo::ApplicationDelegate, 81 class NaClContentHandler : public mojo::ApplicationDelegate,
85 public mojo::ContentHandlerFactory::Delegate { 82 public mojo::ContentHandlerFactory::Delegate {
86 public: 83 public:
87 NaClContentHandler() : content_handler_factory_(this) {} 84 NaClContentHandler() : content_handler_factory_(this) {}
88 85
89 private: 86 private:
(...skipping 12 matching lines...) Expand all
102 GURL irt_url; 99 GURL irt_url;
103 #if defined(ARCH_CPU_X86_64) 100 #if defined(ARCH_CPU_X86_64)
104 irt_url = url_.Resolve("irt_x64/irt_mojo.nexe"); 101 irt_url = url_.Resolve("irt_x64/irt_mojo.nexe");
105 #else 102 #else
106 #error "Unknown / unsupported CPU architecture." 103 #error "Unknown / unsupported CPU architecture."
107 #endif 104 #endif
108 if (!irt_url.is_valid()) { 105 if (!irt_url.is_valid()) {
109 LOG(FATAL) << "Cannot resolve IRT URL"; 106 LOG(FATAL) << "Cannot resolve IRT URL";
110 } 107 }
111 108
112 if (!TempFileForURL(url_loader, irt_url, &irt_path_)) { 109 irt_fp_ = TempFileForURL(url_loader, irt_url);
113 LOG(FATAL) << "Could not aquire the IRT"; 110 if (irt_fp_ == nullptr) {
Mark Seaborn 2015/09/03 06:33:16 "!irt_fp_" is the normal style for Chromium code.
Sean Klein 2015/09/03 15:51:50 Done.
111 LOG(FATAL) << "Could not acquire the IRT";
114 } 112 }
115 } 113 }
116 114
117 // Overridden from ApplicationDelegate: 115 // Overridden from ApplicationDelegate:
118 bool ConfigureIncomingConnection( 116 bool ConfigureIncomingConnection(
119 mojo::ApplicationConnection* connection) override { 117 mojo::ApplicationConnection* connection) override {
120 connection->AddService(&content_handler_factory_); 118 connection->AddService(&content_handler_factory_);
121 return true; 119 return true;
122 } 120 }
123 121
124 // Overridden from ContentHandlerFactory::ManagedDelegate: 122 // Overridden from ContentHandlerFactory::ManagedDelegate:
125 void RunApplication( 123 void RunApplication(
126 mojo::InterfaceRequest<mojo::Application> application_request, 124 mojo::InterfaceRequest<mojo::Application> application_request,
127 mojo::URLResponsePtr response) override { 125 mojo::URLResponsePtr response) override {
128 // Needed to use Mojo interfaces on this thread. 126 // Needed to use Mojo interfaces on this thread.
129 base::MessageLoop loop(mojo::common::MessagePumpMojo::Create()); 127 base::MessageLoop loop(mojo::common::MessagePumpMojo::Create());
130 128
131 // Aquire the nexe. 129 // Acquire the nexe.
132 base::FilePath nexe_path; 130 base::ScopedFILE nexe_fp =
133 if (!URLResponseToTempFile(response, &nexe_path)) { 131 mojo::common::BlockingCopyToTempFile(response->body.Pass());
132 if (nexe_fp == nullptr) {
Mark Seaborn 2015/09/03 06:33:16 Ditto: "!nexe_fp"
Sean Klein 2015/09/03 15:51:50 Done.
134 LOG(FATAL) << "could not redirect nexe to temp file"; 133 LOG(FATAL) << "could not redirect nexe to temp file";
135 } 134 }
136 135
137 // Aquire the IRT. 136 // Acquire the IRT.
138 mojo::URLLoaderPtr url_loader = url_loader_.Pass(); 137 mojo::URLLoaderPtr url_loader = url_loader_.Pass();
139 LoadIRT(url_loader); 138 LoadIRT(url_loader);
140 139
141 // Get file handles to the IRT and nexe. 140 NaClDesc* irt_desc = FileStreamToNaClDesc(irt_fp_.release());
142 NaClDesc* irt_desc = NaClDescFromNexePath(irt_path_); 141 NaClDesc* nexe_desc = FileStreamToNaClDesc(nexe_fp.release());
143 NaClDesc* nexe_desc = NaClDescFromNexePath(nexe_path);
144 142
145 // Run. 143 // Run.
146 int exit_code = mojo::LaunchNaCl( 144 int exit_code = mojo::LaunchNaCl(
147 nexe_desc, irt_desc, 0, NULL, 145 nexe_desc, irt_desc, 0, nullptr,
148 application_request.PassMessagePipe().release().value()); 146 application_request.PassMessagePipe().release().value());
149 147
150 // TODO(ncbray): are the file handles actually closed at this point?
151
152 // Clean up.
153 if (!base::DeleteFile(irt_path_, false)) {
154 LOG(FATAL) << "Failed to remove irt temp file " << irt_path_.value();
155 }
156 if (!base::DeleteFile(nexe_path, false)) {
157 LOG(FATAL) << "Failed to remove nexe temp file " << nexe_path.value();
158 }
159
160 // Exits the process cleanly, does not return. 148 // Exits the process cleanly, does not return.
161 mojo::NaClExit(exit_code); 149 mojo::NaClExit(exit_code);
162 NOTREACHED(); 150 NOTREACHED();
163 } 151 }
164 152
165 mojo::ContentHandlerFactory content_handler_factory_; 153 mojo::ContentHandlerFactory content_handler_factory_;
166 GURL url_; 154 GURL url_;
167 base::FilePath irt_path_; 155 base::ScopedFILE irt_fp_;
168 156
169 mojo::URLLoaderPtr url_loader_; 157 mojo::URLLoaderPtr url_loader_;
170 158
171 DISALLOW_COPY_AND_ASSIGN(NaClContentHandler); 159 DISALLOW_COPY_AND_ASSIGN(NaClContentHandler);
172 }; 160 };
173 161
174 } // namespace content_handler 162 } // namespace content_handler
175 } // namespace nacl 163 } // namespace nacl
176 164
177 MojoResult MojoMain(MojoHandle application_request) { 165 MojoResult MojoMain(MojoHandle application_request) {
178 mojo::ApplicationRunnerChromium runner( 166 mojo::ApplicationRunnerChromium runner(
179 new nacl::content_handler::NaClContentHandler()); 167 new nacl::content_handler::NaClContentHandler());
180 return runner.Run(application_request); 168 return runner.Run(application_request);
181 } 169 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698