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

Side by Side Diff: mojo/python/content_handler/content_handler_main.cc

Issue 855043003: Revert "Content handler for python." (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 11 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include <python2.7/Python.h>
6 #include <dlfcn.h>
7
8 #include "base/files/file_path.h"
9 #include "base/files/scoped_temp_dir.h"
10 #include "base/i18n/icu_util.h"
11 #include "mojo/application/application_runner_chromium.h"
12 #include "mojo/application/content_handler_factory.h"
13 #include "mojo/common/common_type_converters.h"
14 #include "mojo/common/data_pipe_utils.h"
15 #include "mojo/public/c/system/main.h"
16 #include "mojo/public/cpp/application/application_delegate.h"
17 #include "mojo/public/cpp/application/application_impl.h"
18 #include "mojo/public/cpp/application/interface_factory_impl.h"
19 #include "mojo/public/python/src/common.h"
20 #include "third_party/zlib/google/zip_reader.h"
21
22 char kMojoSystem[] = "mojo_system";
23 char kMojoSystemImpl[] = "mojo_system_impl";
24 char kMojoMain[] = "MojoMain";
25
26 extern "C" {
27 void initmojo_system();
28 void initmojo_system_impl();
29 }
30
31 namespace mojo {
32 namespace python {
33
34 class PythonContentHandler : public ApplicationDelegate,
35 public ContentHandlerFactory::Delegate {
36 public:
37 PythonContentHandler() : content_handler_factory_(this) {}
38
39 private:
40 // Overridden from ApplicationDelegate:
41 bool ConfigureIncomingConnection(ApplicationConnection* connection) override {
42 connection->AddService(&content_handler_factory_);
43 return true;
44 }
45
46 // Extracts the target application into a temporary directory. This directory
47 // is deleted at the end of the life of the PythonContentHandler object.
48 std::unique_ptr<base::ScopedTempDir> ExtractApplication(
49 URLResponsePtr response) {
50 std::unique_ptr<base::ScopedTempDir> temp_dir(new base::ScopedTempDir);
51 MOJO_CHECK(temp_dir->CreateUniqueTempDir());
52
53 zip::ZipReader reader;
54 const std::string input_data = CopyToString(response->body.Pass());
55 MOJO_DCHECK(reader.OpenFromString(input_data));
56 base::FilePath temp_dir_path = temp_dir->path();
57 while (reader.HasMore()) {
58 MOJO_DCHECK(reader.OpenCurrentEntryInZip());
59 MOJO_DCHECK(reader.ExtractCurrentEntryIntoDirectory(temp_dir_path));
60 MOJO_DCHECK(reader.AdvanceToNextEntry());
61 }
62 return temp_dir;
63 }
64
65 // Sets up the Python interpreter and loads mojo system modules. This method
66 // returns the global dictionary for the python environment that should be
67 // used for subsequent calls. Takes as input the path of the unpacked
68 // application files.
69 PyObject* SetupPythonEnvironment(const std::string& application_path) {
70 // TODO(etiennej): Build python ourselves so we don't have to rely on
71 // dynamically loading a system library.
72 dlopen("libpython2.7.so", RTLD_LAZY | RTLD_GLOBAL);
73
74 PyImport_AppendInittab(kMojoSystemImpl, &initmojo_system_impl);
75 PyImport_AppendInittab(kMojoSystem, &initmojo_system);
76
77 Py_Initialize();
78
79 PyObject *m, *d;
80 m = PyImport_AddModule("__main__");
81 if (m == NULL)
82 return NULL;
83 d = PyModule_GetDict(m);
84
85 // Inject the application path into the python search path so that imports
86 // from the application work as expected.
87 std::string search_path_py_command =
88 "import sys; sys.path.append('" + application_path + "');";
89 ScopedPyRef result(
90 PyRun_String(search_path_py_command.c_str(), Py_file_input, d, d));
91
92 if (result == nullptr) {
93 LOG(ERROR) << "Error while configuring path";
94 PyErr_Print();
95 return NULL;
96 }
97
98 return d;
99 }
100
101 // Overridden from ContentHandlerFactory::ManagedDelegate:
102 void RunApplication(ShellPtr shell, URLResponsePtr response) override {
103 std::unique_ptr<base::ScopedTempDir> temp_dir =
104 ExtractApplication(response.Pass());
105 base::FilePath directory_path = temp_dir->path();
106
107 PyObject* d = SetupPythonEnvironment(directory_path.value());
108 MOJO_DCHECK(d);
109
110 base::FilePath entry_path = directory_path.Append("__mojo__.py");
111
112 FILE* entry_file = base::OpenFile(entry_path, "r");
113 MOJO_DCHECK(entry_file);
114
115 // Ensure that all created objects are destroyed before calling Py_Finalize.
116 {
117 // Load the __mojo__.py file into the interpreter. MojoMain hasn't run
118 // yet.
119 ScopedPyRef result(PyRun_File(entry_file, entry_path.value().c_str(),
120 Py_file_input, d, d));
121 if (result == nullptr) {
122 LOG(ERROR) << "Error while loading script";
123 PyErr_Print();
124 return;
125 }
126
127 // Find MojoMain.
128 ScopedPyRef py_function(PyMapping_GetItemString(d, kMojoMain));
129
130 if (py_function == NULL) {
131 LOG(ERROR) << "Locals size: " << PyMapping_Size(d);
132 LOG(ERROR) << "MojoMain not found";
133 PyErr_Print();
134 return;
135 }
136
137 if (PyCallable_Check(py_function)) {
138 MojoHandle shell_handle = shell.PassMessagePipe().release().value();
139 ScopedPyRef py_input(PyInt_FromLong(shell_handle));
140 ScopedPyRef py_arguments(PyTuple_New(1));
141 // py_input reference is stolen by py_arguments
142 PyTuple_SetItem(py_arguments, 0, py_input.Release());
143 // Run MojoMain with shell_handle as the first and only argument.
144 ScopedPyRef py_output(PyObject_CallObject(py_function, py_arguments));
145
146 if (!py_output) {
147 LOG(ERROR) << "Error while executing MojoMain";
148 PyErr_Print();
149 return;
150 }
151 } else {
152 LOG(ERROR) << "MojoMain is not callable; it should be a function";
153 }
154 }
155 Py_Finalize();
156 }
157
158 std::string CopyToString(ScopedDataPipeConsumerHandle body) {
159 std::string body_str;
160 bool result = common::BlockingCopyToString(body.Pass(), &body_str);
161 DCHECK(result);
162 return body_str;
163 }
164
165 ContentHandlerFactory content_handler_factory_;
166
167 DISALLOW_COPY_AND_ASSIGN(PythonContentHandler);
168 };
169
170 } // namespace python
171 } // namespace mojo
172
173 MojoResult MojoMain(MojoHandle shell_handle) {
174 mojo::ApplicationRunnerChromium runner(
175 new mojo::python::PythonContentHandler());
176 return runner.Run(shell_handle);
177 }
OLDNEW
« no previous file with comments | « mojo/python/content_handler/c_base.pxd ('k') | mojo/python/content_handler/mojo_system_impl.pyx » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698