1 /* ------------------------------------------------------------------------- */
2
3 /*
4 * Copyright 2007-2019 GRAHAM DUMPLETON
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 /* ------------------------------------------------------------------------- */
20
21 #include "wsgi_interp.h"
22
23 #include "wsgi_version.h"
24
25 #include "wsgi_apache.h"
26 #include "wsgi_server.h"
27 #include "wsgi_logger.h"
28 #include "wsgi_restrict.h"
29 #include "wsgi_stream.h"
30 #include "wsgi_metrics.h"
31 #include "wsgi_daemon.h"
32 #include "wsgi_metrics.h"
33 #include "wsgi_thread.h"
34
35 #if APR_HAVE_UNISTD_H
36 #include <unistd.h>
37 #endif
38
39 #ifndef WIN32
40 #include <pwd.h>
41 #endif
42
43 /* ------------------------------------------------------------------------- */
44
45 /* Function to restrict access to use of signal(). */
46
SignalIntercept_dealloc(SignalInterceptObject * self)47 static void SignalIntercept_dealloc(SignalInterceptObject *self)
48 {
49 Py_DECREF(self->wrapped);
50 }
51
newSignalInterceptObject(PyObject * wrapped)52 static SignalInterceptObject *newSignalInterceptObject(PyObject *wrapped)
53 {
54 SignalInterceptObject *self = NULL;
55
56 self = PyObject_New(SignalInterceptObject, &SignalIntercept_Type);
57 if (self == NULL)
58 return NULL;
59
60 Py_INCREF(wrapped);
61 self->wrapped = wrapped;
62
63 return self;
64 }
65
SignalIntercept_call(SignalInterceptObject * self,PyObject * args,PyObject * kwds)66 static PyObject *SignalIntercept_call(
67 SignalInterceptObject *self, PyObject *args, PyObject *kwds)
68 {
69 PyObject *h = NULL;
70 int n = 0;
71
72 PyObject *m = NULL;
73
74 if (wsgi_daemon_pid != 0 && wsgi_daemon_pid != getpid())
75 return PyObject_Call(self->wrapped, args, kwds);
76
77 if (wsgi_worker_pid != 0 && wsgi_worker_pid != getpid())
78 return PyObject_Call(self->wrapped, args, kwds);
79
80 if (!PyArg_ParseTuple(args, "iO:signal", &n, &h))
81 return NULL;
82
83 Py_BEGIN_ALLOW_THREADS
84 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, wsgi_server,
85 "mod_wsgi (pid=%d): Callback registration for "
86 "signal %d ignored.", getpid(), n);
87 Py_END_ALLOW_THREADS
88
89 m = PyImport_ImportModule("traceback");
90
91 if (m) {
92 PyObject *d = NULL;
93 PyObject *o = NULL;
94 d = PyModule_GetDict(m);
95 o = PyDict_GetItemString(d, "print_stack");
96 if (o) {
97 PyObject *log = NULL;
98 PyObject *args = NULL;
99 PyObject *result = NULL;
100 Py_INCREF(o);
101 log = newLogObject(NULL, APLOG_WARNING, NULL, 0);
102 args = Py_BuildValue("(OOO)", Py_None, Py_None, log);
103 result = PyEval_CallObject(o, args);
104 Py_XDECREF(result);
105 Py_DECREF(args);
106 Py_DECREF(log);
107 Py_DECREF(o);
108 }
109 }
110
111 Py_XDECREF(m);
112
113 Py_INCREF(h);
114
115 return h;
116 }
117
118 PyTypeObject SignalIntercept_Type = {
119 PyVarObject_HEAD_INIT(NULL, 0)
120 "mod_wsgi.SignalIntercept", /*tp_name*/
121 sizeof(SignalInterceptObject), /*tp_basicsize*/
122 0, /*tp_itemsize*/
123 /* methods */
124 (destructor)SignalIntercept_dealloc, /*tp_dealloc*/
125 0, /*tp_print*/
126 0, /*tp_getattr*/
127 0, /*tp_setattr*/
128 0, /*tp_compare*/
129 0, /*tp_repr*/
130 0, /*tp_as_number*/
131 0, /*tp_as_sequence*/
132 0, /*tp_as_mapping*/
133 0, /*tp_hash*/
134 (ternaryfunc)SignalIntercept_call, /*tp_call*/
135 0, /*tp_str*/
136 0, /*tp_getattro*/
137 0, /*tp_setattro*/
138 0, /*tp_as_buffer*/
139 Py_TPFLAGS_DEFAULT, /*tp_flags*/
140 0, /*tp_doc*/
141 0, /*tp_traverse*/
142 0, /*tp_clear*/
143 0, /*tp_richcompare*/
144 0, /*tp_weaklistoffset*/
145 0, /*tp_iter*/
146 0, /*tp_iternext*/
147 0, /*tp_methods*/
148 0, /*tp_members*/
149 0, /*tp_getset*/
150 0, /*tp_base*/
151 0, /*tp_dict*/
152 0, /*tp_descr_get*/
153 0, /*tp_descr_set*/
154 0, /*tp_dictoffset*/
155 0, /*tp_init*/
156 0, /*tp_alloc*/
157 0, /*tp_new*/
158 0, /*tp_free*/
159 0, /*tp_is_gc*/
160 };
161
162 /* ------------------------------------------------------------------------- */
163
wsgi_system_exit(PyObject * self,PyObject * args)164 static PyObject *wsgi_system_exit(PyObject *self, PyObject *args)
165 {
166 PyErr_SetObject(PyExc_SystemExit, 0);
167
168 return NULL;
169 }
170
171 /* ------------------------------------------------------------------------- */
172
173 static PyMethodDef wsgi_system_exit_method[] = {
174 { "system_exit", (PyCFunction)wsgi_system_exit, METH_VARARGS, 0 },
175 { NULL },
176 };
177
178 /* ------------------------------------------------------------------------- */
179
180 /* Wrapper around Python interpreter instances. */
181
182 const char *wsgi_python_path = NULL;
183 const char *wsgi_python_eggs = NULL;
184
185 #if PY_MAJOR_VERSION > 3 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 4)
ShutdownInterpreter_dealloc(ShutdownInterpreterObject * self)186 static void ShutdownInterpreter_dealloc(ShutdownInterpreterObject *self)
187 {
188 Py_DECREF(self->wrapped);
189 }
190
newShutdownInterpreterObject(PyObject * wrapped)191 static ShutdownInterpreterObject *newShutdownInterpreterObject(
192 PyObject *wrapped)
193 {
194 ShutdownInterpreterObject *self = NULL;
195
196 self = PyObject_New(ShutdownInterpreterObject, &ShutdownInterpreter_Type);
197 if (self == NULL)
198 return NULL;
199
200 Py_INCREF(wrapped);
201 self->wrapped = wrapped;
202
203 return self;
204 }
205
ShutdownInterpreter_call(ShutdownInterpreterObject * self,PyObject * args,PyObject * kwds)206 static PyObject *ShutdownInterpreter_call(
207 ShutdownInterpreterObject *self, PyObject *args, PyObject *kwds)
208 {
209 PyObject *result = NULL;
210
211 result = PyObject_Call(self->wrapped, args, kwds);
212
213 if (result) {
214 PyObject *module = NULL;
215 PyObject *exitfunc = NULL;
216
217 PyThreadState *tstate = PyThreadState_Get();
218
219 PyThreadState *tstate_save = tstate;
220 PyThreadState *tstate_next = NULL;
221
222 #if PY_MAJOR_VERSION >= 3
223 module = PyImport_ImportModule("atexit");
224
225 if (module) {
226 PyObject *dict = NULL;
227
228 dict = PyModule_GetDict(module);
229 exitfunc = PyDict_GetItemString(dict, "_run_exitfuncs");
230 }
231 else
232 PyErr_Clear();
233 #else
234 exitfunc = PySys_GetObject("exitfunc");
235 #endif
236
237 if (exitfunc) {
238 PyObject *res = NULL;
239 Py_INCREF(exitfunc);
240 PySys_SetObject("exitfunc", (PyObject *)NULL);
241 res = PyEval_CallObject(exitfunc, (PyObject *)NULL);
242
243 if (res == NULL) {
244 PyObject *m = NULL;
245 PyObject *result = NULL;
246
247 PyObject *type = NULL;
248 PyObject *value = NULL;
249 PyObject *traceback = NULL;
250
251 if (PyErr_ExceptionMatches(PyExc_SystemExit)) {
252 Py_BEGIN_ALLOW_THREADS
253 ap_log_error(APLOG_MARK, APLOG_ERR, 0, wsgi_server,
254 "mod_wsgi (pid=%d): SystemExit exception "
255 "raised by exit functions ignored.", getpid());
256 Py_END_ALLOW_THREADS
257 }
258 else {
259 Py_BEGIN_ALLOW_THREADS
260 ap_log_error(APLOG_MARK, APLOG_ERR, 0, wsgi_server,
261 "mod_wsgi (pid=%d): Exception occurred within "
262 "exit functions.", getpid());
263 Py_END_ALLOW_THREADS
264 }
265
266 PyErr_Fetch(&type, &value, &traceback);
267 PyErr_NormalizeException(&type, &value, &traceback);
268
269 if (!value) {
270 value = Py_None;
271 Py_INCREF(value);
272 }
273
274 if (!traceback) {
275 traceback = Py_None;
276 Py_INCREF(traceback);
277 }
278
279 m = PyImport_ImportModule("traceback");
280
281 if (m) {
282 PyObject *d = NULL;
283 PyObject *o = NULL;
284 d = PyModule_GetDict(m);
285 o = PyDict_GetItemString(d, "print_exception");
286 if (o) {
287 PyObject *log = NULL;
288 PyObject *args = NULL;
289 Py_INCREF(o);
290 log = newLogObject(NULL, APLOG_ERR, NULL, 0);
291 args = Py_BuildValue("(OOOOO)", type, value,
292 traceback, Py_None, log);
293 result = PyEval_CallObject(o, args);
294 Py_DECREF(args);
295 Py_DECREF(log);
296 Py_DECREF(o);
297 }
298 }
299
300 if (!result) {
301 /*
302 * If can't output exception and traceback then
303 * use PyErr_Print to dump out details of the
304 * exception. For SystemExit though if we do
305 * that the process will actually be terminated
306 * so can only clear the exception information
307 * and keep going.
308 */
309
310 PyErr_Restore(type, value, traceback);
311
312 if (!PyErr_ExceptionMatches(PyExc_SystemExit)) {
313 PyErr_Print();
314 PyErr_Clear();
315 }
316 else {
317 PyErr_Clear();
318 }
319 }
320 else {
321 Py_XDECREF(type);
322 Py_XDECREF(value);
323 Py_XDECREF(traceback);
324 }
325
326 Py_XDECREF(result);
327
328 Py_XDECREF(m);
329 }
330
331 Py_XDECREF(res);
332 Py_DECREF(exitfunc);
333 }
334
335 Py_XDECREF(module);
336
337 /* Delete remaining thread states. */
338
339 PyThreadState_Swap(NULL);
340
341 tstate = PyInterpreterState_ThreadHead(tstate->interp);
342
343 while (tstate) {
344 tstate_next = PyThreadState_Next(tstate);
345 if (tstate != tstate_save) {
346 PyThreadState_Swap(tstate);
347 PyThreadState_Clear(tstate);
348 PyThreadState_Swap(NULL);
349 PyThreadState_Delete(tstate);
350 }
351 tstate = tstate_next;
352 }
353 tstate = tstate_save;
354
355 PyThreadState_Swap(tstate);
356 }
357
358 return result;
359 }
360
361 PyTypeObject ShutdownInterpreter_Type = {
362 PyVarObject_HEAD_INIT(NULL, 0)
363 "mod_wsgi.ShutdownInterpreter", /*tp_name*/
364 sizeof(ShutdownInterpreterObject), /*tp_basicsize*/
365 0, /*tp_itemsize*/
366 /* methods */
367 (destructor)ShutdownInterpreter_dealloc, /*tp_dealloc*/
368 0, /*tp_print*/
369 0, /*tp_getattr*/
370 0, /*tp_setattr*/
371 0, /*tp_compare*/
372 0, /*tp_repr*/
373 0, /*tp_as_number*/
374 0, /*tp_as_sequence*/
375 0, /*tp_as_mapping*/
376 0, /*tp_hash*/
377 (ternaryfunc)ShutdownInterpreter_call, /*tp_call*/
378 0, /*tp_str*/
379 0, /*tp_getattro*/
380 0, /*tp_setattro*/
381 0, /*tp_as_buffer*/
382 Py_TPFLAGS_DEFAULT, /*tp_flags*/
383 0, /*tp_doc*/
384 0, /*tp_traverse*/
385 0, /*tp_clear*/
386 0, /*tp_richcompare*/
387 0, /*tp_weaklistoffset*/
388 0, /*tp_iter*/
389 0, /*tp_iternext*/
390 0, /*tp_methods*/
391 0, /*tp_members*/
392 0, /*tp_getset*/
393 0, /*tp_base*/
394 0, /*tp_dict*/
395 0, /*tp_descr_get*/
396 0, /*tp_descr_set*/
397 0, /*tp_dictoffset*/
398 0, /*tp_init*/
399 0, /*tp_alloc*/
400 0, /*tp_new*/
401 0, /*tp_free*/
402 0, /*tp_is_gc*/
403 };
404 #endif
405
406 PyTypeObject Interpreter_Type;
407
newInterpreterObject(const char * name)408 InterpreterObject *newInterpreterObject(const char *name)
409 {
410 PyInterpreterState *interp = NULL;
411 InterpreterObject *self = NULL;
412 PyThreadState *tstate = NULL;
413 PyThreadState *save_tstate = NULL;
414 PyObject *module = NULL;
415 PyObject *object = NULL;
416 PyObject *item = NULL;
417
418 int max_threads = 0;
419 int max_processes = 0;
420 int is_threaded = 0;
421 int is_forked = 0;
422
423 int is_service_script = 0;
424
425 const char *str = NULL;
426
427 /* Create handle for interpreter and local data. */
428
429 self = PyObject_New(InterpreterObject, &Interpreter_Type);
430 if (self == NULL)
431 return NULL;
432
433 /*
434 * If interpreter not named, then we want to bind
435 * to the first Python interpreter instance created.
436 * Give this interpreter an empty string as name.
437 */
438
439 if (!name) {
440 #if PY_MAJOR_VERSION > 3 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 7)
441 interp = PyInterpreterState_Main();
442 #else
443 interp = PyInterpreterState_Head();
444 while (PyInterpreterState_Next(interp))
445 interp = PyInterpreterState_Next(interp);
446 #endif
447
448 name = "";
449 }
450
451 /* Save away the interpreter name. */
452
453 self->name = strdup(name);
454
455 if (interp) {
456 /*
457 * Interpreter provided to us so will not be
458 * responsible for deleting it later. This will
459 * be the case for the main Python interpreter.
460 */
461
462 ap_log_error(APLOG_MARK, APLOG_INFO, 0, wsgi_server,
463 "mod_wsgi (pid=%d): Attach interpreter '%s'.",
464 getpid(), name);
465
466 self->interp = interp;
467 self->owner = 0;
468 }
469 else {
470 /*
471 * Remember active thread state so can restore
472 * it. This is actually the thread state
473 * associated with simplified GIL state API.
474 */
475
476 save_tstate = PyThreadState_Swap(NULL);
477
478 /*
479 * Create the interpreter. If creation of the
480 * interpreter fails it will restore the
481 * existing active thread state for us so don't
482 * need to worry about it in that case.
483 */
484
485 tstate = Py_NewInterpreter();
486
487 if (!tstate) {
488 PyErr_SetString(PyExc_RuntimeError, "Py_NewInterpreter() failed");
489
490 Py_DECREF(self);
491
492 return NULL;
493 }
494
495 Py_BEGIN_ALLOW_THREADS
496 ap_log_error(APLOG_MARK, APLOG_INFO, 0, wsgi_server,
497 "mod_wsgi (pid=%d): Create interpreter '%s'.",
498 getpid(), name);
499 Py_END_ALLOW_THREADS
500
501 self->interp = tstate->interp;
502 self->owner = 1;
503
504 /*
505 * We need to replace threading._shutdown() with our own
506 * function which will also call atexit callbacks after
507 * threads are shutdown to cope with fact that Python
508 * itself doesn't call the atexit callbacks in sub
509 * interpreters.
510 */
511
512 #if PY_MAJOR_VERSION > 3 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 4)
513 module = PyImport_ImportModule("threading");
514
515 if (module) {
516 PyObject *dict = NULL;
517 PyObject *func = NULL;
518
519 dict = PyModule_GetDict(module);
520 func = PyDict_GetItemString(dict, "_shutdown");
521
522 if (func) {
523 PyObject *wrapper = NULL;
524
525 wrapper = (PyObject *)newShutdownInterpreterObject(func);
526 PyDict_SetItemString(dict, "_shutdown", wrapper);
527 Py_DECREF(wrapper);
528 }
529 }
530
531 Py_XDECREF(module);
532 #endif
533 }
534
535 /*
536 * Install restricted objects for STDIN and STDOUT,
537 * or log object for STDOUT as appropriate. Don't do
538 * this if not running on Win32 and we believe we
539 * are running in single process mode, otherwise
540 * it prevents use of interactive debuggers such as
541 * the 'pdb' module.
542 */
543
544 object = newLogObject(NULL, APLOG_ERR, "<stderr>", 1);
545 PySys_SetObject("stderr", object);
546 Py_DECREF(object);
547
548 #ifndef WIN32
549 if (wsgi_parent_pid != getpid()) {
550 #endif
551 if (wsgi_server_config->restrict_stdout == 1) {
552 object = (PyObject *)newRestrictedObject("sys.stdout");
553 PySys_SetObject("stdout", object);
554 Py_DECREF(object);
555 }
556 else {
557 object = newLogObject(NULL, APLOG_ERR, "<stdout>", 1);
558 PySys_SetObject("stdout", object);
559 Py_DECREF(object);
560 }
561
562 if (wsgi_server_config->restrict_stdin == 1) {
563 object = (PyObject *)newRestrictedObject("sys.stdin");
564 PySys_SetObject("stdin", object);
565 Py_DECREF(object);
566 }
567 #ifndef WIN32
568 }
569 #endif
570
571 /*
572 * Set sys.argv to one element list to fake out
573 * modules that look there for Python command
574 * line arguments as appropriate.
575 */
576
577 object = PyList_New(0);
578 #if PY_MAJOR_VERSION >= 3
579 item = PyUnicode_FromString("mod_wsgi");
580 #else
581 item = PyString_FromString("mod_wsgi");
582 #endif
583 PyList_Append(object, item);
584 PySys_SetObject("argv", object);
585 Py_DECREF(item);
586 Py_DECREF(object);
587
588 /*
589 * Install intercept for signal handler registration
590 * if appropriate. Don't do this though if number of
591 * threads for daemon process was set as 0, indicating
592 * a potential daemon process which is running a
593 * service script.
594 */
595
596 /*
597 * If running in daemon mode and there are no threads
598 * specified, must be running with service script, in
599 * which case we register default signal handler for
600 * SIGINT which throws a SystemExit exception. If
601 * instead restricting signals, replace function for
602 * registering signal handlers so they are ignored.
603 */
604
605 #if defined(MOD_WSGI_WITH_DAEMONS)
606 if (wsgi_daemon_process && wsgi_daemon_process->group->threads == 0) {
607 is_service_script = 1;
608
609 module = PyImport_ImportModule("signal");
610
611 if (module) {
612 PyObject *dict = NULL;
613 PyObject *func = NULL;
614
615 dict = PyModule_GetDict(module);
616 func = PyDict_GetItemString(dict, "signal");
617
618 if (func) {
619 PyObject *res = NULL;
620 PyObject *args = NULL;
621 PyObject *callback = NULL;
622
623 Py_INCREF(func);
624
625 callback = PyCFunction_New(&wsgi_system_exit_method[0], NULL);
626
627 args = Py_BuildValue("(iO)", SIGTERM, callback);
628 res = PyEval_CallObject(func, args);
629
630 if (!res) {
631 Py_BEGIN_ALLOW_THREADS
632 ap_log_error(APLOG_MARK, APLOG_ERR, 0, wsgi_server,
633 "mod_wsgi (pid=%d): Call to "
634 "'signal.signal()' to register exit "
635 "function failed, ignoring.", getpid());
636 Py_END_ALLOW_THREADS
637 }
638
639 Py_XDECREF(res);
640 Py_XDECREF(args);
641
642 Py_XDECREF(callback);
643
644 Py_DECREF(func);
645 }
646 }
647
648 Py_XDECREF(module);
649 }
650 #endif
651
652 if (!is_service_script && wsgi_server_config->restrict_signal != 0) {
653 module = PyImport_ImportModule("signal");
654
655 if (module) {
656 PyObject *dict = NULL;
657 PyObject *func = NULL;
658
659 dict = PyModule_GetDict(module);
660 func = PyDict_GetItemString(dict, "signal");
661
662 if (func) {
663 PyObject *wrapper = NULL;
664
665 wrapper = (PyObject *)newSignalInterceptObject(func);
666 PyDict_SetItemString(dict, "signal", wrapper);
667 Py_DECREF(wrapper);
668 }
669 }
670
671 Py_XDECREF(module);
672 }
673
674 /*
675 * Force loading of codecs into interpreter. This has to be
676 * done as not otherwise done in sub interpreters and if not
677 * done, code running in sub interpreters can fail on some
678 * platforms if a unicode string is added in sys.path and an
679 * import then done.
680 */
681
682 item = PyCodec_Encoder("ascii");
683 Py_XDECREF(item);
684
685 /*
686 * If running in daemon process, override as appropriate
687 * the USER, USERNAME or LOGNAME environment variables
688 * so that they match the user that the process is running
689 * as. Need to do this else we inherit the value from the
690 * Apache parent process which is likely wrong as will be
691 * root or the user than ran sudo when Apache started.
692 * Can't update these for normal Apache child processes
693 * as that would change the expected environment of other
694 * Apache modules.
695 */
696
697 #ifndef WIN32
698 if (wsgi_daemon_pool) {
699 module = PyImport_ImportModule("os");
700
701 if (module) {
702 PyObject *dict = NULL;
703 PyObject *key = NULL;
704 PyObject *value = NULL;
705
706 dict = PyModule_GetDict(module);
707 object = PyDict_GetItemString(dict, "environ");
708
709 if (object) {
710 struct passwd *pwent;
711
712 pwent = getpwuid(geteuid());
713
714 if (pwent && getenv("USER")) {
715 #if PY_MAJOR_VERSION >= 3
716 key = PyUnicode_FromString("USER");
717 value = PyUnicode_Decode(pwent->pw_name,
718 strlen(pwent->pw_name),
719 Py_FileSystemDefaultEncoding,
720 "surrogateescape");
721 #else
722 key = PyString_FromString("USER");
723 value = PyString_FromString(pwent->pw_name);
724 #endif
725
726 PyObject_SetItem(object, key, value);
727
728 Py_DECREF(key);
729 Py_DECREF(value);
730 }
731
732 if (pwent && getenv("USERNAME")) {
733 #if PY_MAJOR_VERSION >= 3
734 key = PyUnicode_FromString("USERNAME");
735 value = PyUnicode_Decode(pwent->pw_name,
736 strlen(pwent->pw_name),
737 Py_FileSystemDefaultEncoding,
738 "surrogateescape");
739 #else
740 key = PyString_FromString("USERNAME");
741 value = PyString_FromString(pwent->pw_name);
742 #endif
743
744 PyObject_SetItem(object, key, value);
745
746 Py_DECREF(key);
747 Py_DECREF(value);
748 }
749
750 if (pwent && getenv("LOGNAME")) {
751 #if PY_MAJOR_VERSION >= 3
752 key = PyUnicode_FromString("LOGNAME");
753 value = PyUnicode_Decode(pwent->pw_name,
754 strlen(pwent->pw_name),
755 Py_FileSystemDefaultEncoding,
756 "surrogateescape");
757 #else
758 key = PyString_FromString("LOGNAME");
759 value = PyString_FromString(pwent->pw_name);
760 #endif
761
762 PyObject_SetItem(object, key, value);
763
764 Py_DECREF(key);
765 Py_DECREF(value);
766 }
767 }
768
769 Py_DECREF(module);
770 }
771 }
772 #endif
773
774 /*
775 * If running in daemon process, override HOME environment
776 * variable so that is matches the home directory of the
777 * user that the process is running as. Need to do this as
778 * Apache will inherit HOME from root user or user that ran
779 * sudo and started Apache and this would be wrong. Can't
780 * update HOME for normal Apache child processes as that
781 * would change the expected environment of other Apache
782 * modules.
783 */
784
785 #ifndef WIN32
786 if (wsgi_daemon_pool) {
787 module = PyImport_ImportModule("os");
788
789 if (module) {
790 PyObject *dict = NULL;
791 PyObject *key = NULL;
792 PyObject *value = NULL;
793
794 dict = PyModule_GetDict(module);
795 object = PyDict_GetItemString(dict, "environ");
796
797 if (object) {
798 struct passwd *pwent;
799
800 pwent = getpwuid(geteuid());
801
802 if (pwent) {
803 #if PY_MAJOR_VERSION >= 3
804 key = PyUnicode_FromString("HOME");
805 value = PyUnicode_Decode(pwent->pw_dir,
806 strlen(pwent->pw_dir),
807 Py_FileSystemDefaultEncoding,
808 "surrogateescape");
809 #else
810 key = PyString_FromString("HOME");
811 value = PyString_FromString(pwent->pw_dir);
812 #endif
813
814 PyObject_SetItem(object, key, value);
815
816 Py_DECREF(key);
817 Py_DECREF(value);
818 }
819 }
820
821 Py_DECREF(module);
822 }
823 }
824 #endif
825
826 /*
827 * Explicitly override the PYTHON_EGG_CACHE variable if it
828 * was defined by Apache configuration. For embedded processes
829 * this would have been done by using WSGIPythonEggs directive.
830 * For daemon processes the 'python-eggs' option to the
831 * WSGIDaemonProcess directive would have needed to be used.
832 */
833
834 if (!wsgi_daemon_pool)
835 wsgi_python_eggs = wsgi_server_config->python_eggs;
836
837 if (wsgi_python_eggs) {
838 module = PyImport_ImportModule("os");
839
840 if (module) {
841 PyObject *dict = NULL;
842 PyObject *key = NULL;
843 PyObject *value = NULL;
844
845 dict = PyModule_GetDict(module);
846 object = PyDict_GetItemString(dict, "environ");
847
848 if (object) {
849 #if PY_MAJOR_VERSION >= 3
850 key = PyUnicode_FromString("PYTHON_EGG_CACHE");
851 value = PyUnicode_Decode(wsgi_python_eggs,
852 strlen(wsgi_python_eggs),
853 Py_FileSystemDefaultEncoding,
854 "surrogateescape");
855 #else
856 key = PyString_FromString("PYTHON_EGG_CACHE");
857 value = PyString_FromString(wsgi_python_eggs);
858 #endif
859
860 PyObject_SetItem(object, key, value);
861
862 Py_DECREF(key);
863 Py_DECREF(value);
864 }
865
866 Py_DECREF(module);
867 }
868 }
869
870 /*
871 * Install user defined Python module search path. This is
872 * added using site.addsitedir() so that any Python .pth
873 * files are opened and additional directories so defined
874 * are added to default Python search path as well. This
875 * allows virtual Python environments to work. Note that
876 * site.addsitedir() adds new directories at the end of
877 * sys.path when they really need to be added in order at
878 * the start. We therefore need to do a fiddle and shift
879 * any newly added directories to the start of sys.path.
880 */
881
882 if (!wsgi_daemon_pool)
883 wsgi_python_path = wsgi_server_config->python_path;
884
885 module = PyImport_ImportModule("site");
886
887 if (wsgi_python_path && *wsgi_python_path) {
888 PyObject *path = NULL;
889
890 path = PySys_GetObject("path");
891
892 if (module && path) {
893 PyObject *dict = NULL;
894
895 PyObject *old = NULL;
896 PyObject *new = NULL;
897 PyObject *tmp = NULL;
898
899 PyObject *item = NULL;
900
901 int i = 0;
902
903 old = PyList_New(0);
904 new = PyList_New(0);
905 tmp = PyList_New(0);
906
907 for (i=0; i<PyList_Size(path); i++)
908 PyList_Append(old, PyList_GetItem(path, i));
909
910 dict = PyModule_GetDict(module);
911 object = PyDict_GetItemString(dict, "addsitedir");
912
913 if (object) {
914 const char *start;
915 const char *end;
916 const char *value;
917
918 PyObject *item;
919 PyObject *args;
920
921 PyObject *result = NULL;
922
923 Py_INCREF(object);
924
925 start = wsgi_python_path;
926 end = strchr(start, DELIM);
927
928 if (end) {
929 #if PY_MAJOR_VERSION >= 3
930 item = PyUnicode_DecodeFSDefaultAndSize(start, end-start);
931 value = PyUnicode_AsUTF8(item);
932 #else
933 item = PyString_FromStringAndSize(start, end-start);
934 value = PyString_AsString(item);
935 #endif
936 start = end+1;
937
938 Py_BEGIN_ALLOW_THREADS
939 ap_log_error(APLOG_MARK, APLOG_INFO, 0, wsgi_server,
940 "mod_wsgi (pid=%d): Adding '%s' to "
941 "path.", getpid(), value);
942 Py_END_ALLOW_THREADS
943
944 args = Py_BuildValue("(O)", item);
945 result = PyEval_CallObject(object, args);
946
947 if (!result) {
948 Py_BEGIN_ALLOW_THREADS
949 ap_log_error(APLOG_MARK, APLOG_ERR, 0, wsgi_server,
950 "mod_wsgi (pid=%d): Call to "
951 "'site.addsitedir()' failed for '%s', "
952 "stopping.", getpid(), value);
953 Py_END_ALLOW_THREADS
954 }
955
956 Py_XDECREF(result);
957 Py_DECREF(item);
958 Py_DECREF(args);
959
960 end = strchr(start, DELIM);
961
962 while (result && end) {
963 #if PY_MAJOR_VERSION >= 3
964 item = PyUnicode_DecodeFSDefaultAndSize(start,
965 end-start);
966 value = PyUnicode_AsUTF8(item);
967 #else
968 item = PyString_FromStringAndSize(start, end-start);
969 value = PyString_AsString(item);
970 #endif
971 start = end+1;
972
973 Py_BEGIN_ALLOW_THREADS
974 ap_log_error(APLOG_MARK, APLOG_INFO, 0, wsgi_server,
975 "mod_wsgi (pid=%d): Adding '%s' to "
976 "path.", getpid(), value);
977 Py_END_ALLOW_THREADS
978
979 args = Py_BuildValue("(O)", item);
980 result = PyEval_CallObject(object, args);
981
982 if (!result) {
983 Py_BEGIN_ALLOW_THREADS
984 ap_log_error(APLOG_MARK, APLOG_ERR, 0,
985 wsgi_server, "mod_wsgi (pid=%d): "
986 "Call to 'site.addsitedir()' failed "
987 "for '%s', stopping.",
988 getpid(), value);
989 Py_END_ALLOW_THREADS
990 }
991
992 Py_XDECREF(result);
993 Py_DECREF(item);
994 Py_DECREF(args);
995
996 end = strchr(start, DELIM);
997 }
998 }
999
1000 #if PY_MAJOR_VERSION >= 3
1001 item = PyUnicode_DecodeFSDefault(start);
1002 value = PyUnicode_AsUTF8(item);
1003 #else
1004 item = PyString_FromString(start);
1005 value = PyString_AsString(item);
1006 #endif
1007
1008 Py_BEGIN_ALLOW_THREADS
1009 ap_log_error(APLOG_MARK, APLOG_INFO, 0, wsgi_server,
1010 "mod_wsgi (pid=%d): Adding '%s' to "
1011 "path.", getpid(), value);
1012 Py_END_ALLOW_THREADS
1013
1014 args = Py_BuildValue("(O)", item);
1015 result = PyEval_CallObject(object, args);
1016
1017 if (!result) {
1018 Py_BEGIN_ALLOW_THREADS
1019 ap_log_error(APLOG_MARK, APLOG_ERR, 0, wsgi_server,
1020 "mod_wsgi (pid=%d): Call to "
1021 "'site.addsitedir()' failed for '%s'.",
1022 getpid(), start);
1023 Py_END_ALLOW_THREADS
1024 }
1025
1026 Py_XDECREF(result);
1027 Py_XDECREF(item);
1028 Py_DECREF(args);
1029
1030 Py_DECREF(object);
1031 }
1032 else {
1033 Py_BEGIN_ALLOW_THREADS
1034 ap_log_error(APLOG_MARK, APLOG_ERR, 0, wsgi_server,
1035 "mod_wsgi (pid=%d): Unable to locate "
1036 "'site.addsitedir()'.", getpid());
1037 Py_END_ALLOW_THREADS
1038 }
1039
1040 for (i=0; i<PyList_Size(path); i++)
1041 PyList_Append(tmp, PyList_GetItem(path, i));
1042
1043 for (i=0; i<PyList_Size(tmp); i++) {
1044 item = PyList_GetItem(tmp, i);
1045 if (!PySequence_Contains(old, item)) {
1046 long index = PySequence_Index(path, item);
1047 PyList_Append(new, item);
1048 if (index != -1)
1049 PySequence_DelItem(path, index);
1050 }
1051 }
1052
1053 PyList_SetSlice(path, 0, 0, new);
1054
1055 Py_DECREF(old);
1056 Py_DECREF(new);
1057 Py_DECREF(tmp);
1058 }
1059 else {
1060 if (!module) {
1061 Py_BEGIN_ALLOW_THREADS
1062 ap_log_error(APLOG_MARK, APLOG_ERR, 0, wsgi_server,
1063 "mod_wsgi (pid=%d): Unable to import 'site' "
1064 "module.", getpid());
1065 Py_END_ALLOW_THREADS
1066 }
1067
1068 if (!path) {
1069 Py_BEGIN_ALLOW_THREADS
1070 ap_log_error(APLOG_MARK, APLOG_ERR, 0, wsgi_server,
1071 "mod_wsgi (pid=%d): Lookup for 'sys.path' "
1072 "failed.", getpid());
1073 Py_END_ALLOW_THREADS
1074 }
1075 }
1076 }
1077
1078 /*
1079 * If running in daemon mode and a home directory was set then
1080 * insert the home directory at the start of the Python module
1081 * search path. This makes things similar to when using the Python
1082 * interpreter on the command line with a script.
1083 */
1084
1085 #if defined(MOD_WSGI_WITH_DAEMONS)
1086 if (wsgi_daemon_process && wsgi_daemon_process->group->home) {
1087 PyObject *path = NULL;
1088 const char *home = wsgi_daemon_process->group->home;
1089
1090 path = PySys_GetObject("path");
1091
1092 if (module && path) {
1093 PyObject *item;
1094
1095 #if PY_MAJOR_VERSION >= 3
1096 item = PyUnicode_Decode(home, strlen(home),
1097 Py_FileSystemDefaultEncoding,
1098 "surrogateescape");
1099 #else
1100 item = PyString_FromString(home);
1101 #endif
1102 PyList_Insert(path, 0, item);
1103 Py_DECREF(item);
1104 }
1105 }
1106 #endif
1107
1108 Py_XDECREF(module);
1109
1110 /*
1111 * Create 'mod_wsgi' Python module. We first try and import an
1112 * external Python module of the same name. The intent is
1113 * that this external module would provide optional features
1114 * implementable using pure Python code. Don't want to
1115 * include them in the main Apache mod_wsgi package as that
1116 * complicates that package and also wouldn't allow them to
1117 * be released to a separate schedule. It is easier for
1118 * people to replace Python modules package with a new
1119 * version than it is to replace Apache module package.
1120 */
1121
1122 module = PyImport_ImportModule("mod_wsgi");
1123
1124 if (!module) {
1125 PyObject *modules = NULL;
1126
1127 modules = PyImport_GetModuleDict();
1128 module = PyDict_GetItemString(modules, "mod_wsgi");
1129
1130 if (module) {
1131 PyErr_Print();
1132
1133 PyDict_DelItemString(modules, "mod_wsgi");
1134 }
1135
1136 PyErr_Clear();
1137
1138 module = PyImport_AddModule("mod_wsgi");
1139
1140 Py_INCREF(module);
1141 }
1142 else if (!*name) {
1143 Py_BEGIN_ALLOW_THREADS
1144 ap_log_error(APLOG_MARK, APLOG_INFO, 0, wsgi_server,
1145 "mod_wsgi (pid=%d): Imported 'mod_wsgi'.",
1146 getpid());
1147 Py_END_ALLOW_THREADS
1148 }
1149
1150 /*
1151 * Add Apache module version information to the Python
1152 * 'mod_wsgi' module.
1153 */
1154
1155 PyModule_AddObject(module, "version", Py_BuildValue("(iii)",
1156 MOD_WSGI_MAJORVERSION_NUMBER,
1157 MOD_WSGI_MINORVERSION_NUMBER,
1158 MOD_WSGI_MICROVERSION_NUMBER));
1159
1160 /* Add type object for file wrapper. */
1161
1162 Py_INCREF(&Stream_Type);
1163 PyModule_AddObject(module, "FileWrapper", (PyObject *)&Stream_Type);
1164
1165 /*
1166 * Add information about process group and application
1167 * group to the Python 'mod_wsgi' module.
1168 */
1169
1170 #if PY_MAJOR_VERSION >= 3
1171 PyModule_AddObject(module, "process_group",
1172 PyUnicode_DecodeLatin1(wsgi_daemon_group,
1173 strlen(wsgi_daemon_group), NULL));
1174 PyModule_AddObject(module, "application_group",
1175 PyUnicode_DecodeLatin1(name, strlen(name), NULL));
1176 #else
1177 PyModule_AddObject(module, "process_group",
1178 PyString_FromString(wsgi_daemon_group));
1179 PyModule_AddObject(module, "application_group",
1180 PyString_FromString(name));
1181 #endif
1182
1183 /*
1184 * Add information about number of processes and threads
1185 * available to the WSGI application to the 'mod_wsgi' module.
1186 * When running in embedded mode, this will be the same as
1187 * what the 'apache' module records for Apache itself.
1188 */
1189
1190 #if defined(MOD_WSGI_WITH_DAEMONS)
1191 if (wsgi_daemon_process) {
1192 object = PyLong_FromLong(wsgi_daemon_process->group->processes);
1193 PyModule_AddObject(module, "maximum_processes", object);
1194
1195 object = PyLong_FromLong(wsgi_daemon_process->group->threads);
1196 PyModule_AddObject(module, "threads_per_process", object);
1197 }
1198 else {
1199 ap_mpm_query(AP_MPMQ_IS_THREADED, &is_threaded);
1200 if (is_threaded != AP_MPMQ_NOT_SUPPORTED) {
1201 ap_mpm_query(AP_MPMQ_MAX_THREADS, &max_threads);
1202 }
1203 ap_mpm_query(AP_MPMQ_IS_FORKED, &is_forked);
1204 if (is_forked != AP_MPMQ_NOT_SUPPORTED) {
1205 ap_mpm_query(AP_MPMQ_MAX_DAEMON_USED, &max_processes);
1206 if (max_processes == -1) {
1207 ap_mpm_query(AP_MPMQ_MAX_DAEMONS, &max_processes);
1208 }
1209 }
1210
1211 max_threads = (max_threads <= 0) ? 1 : max_threads;
1212 max_processes = (max_processes <= 0) ? 1 : max_processes;
1213
1214 object = PyLong_FromLong(max_processes);
1215 PyModule_AddObject(module, "maximum_processes", object);
1216
1217 object = PyLong_FromLong(max_threads);
1218 PyModule_AddObject(module, "threads_per_process", object);
1219 }
1220 #else
1221 ap_mpm_query(AP_MPMQ_IS_THREADED, &is_threaded);
1222 if (is_threaded != AP_MPMQ_NOT_SUPPORTED) {
1223 ap_mpm_query(AP_MPMQ_MAX_THREADS, &max_threads);
1224 }
1225 ap_mpm_query(AP_MPMQ_IS_FORKED, &is_forked);
1226 if (is_forked != AP_MPMQ_NOT_SUPPORTED) {
1227 ap_mpm_query(AP_MPMQ_MAX_DAEMON_USED, &max_processes);
1228 if (max_processes == -1) {
1229 ap_mpm_query(AP_MPMQ_MAX_DAEMONS, &max_processes);
1230 }
1231 }
1232
1233 max_threads = (max_threads <= 0) ? 1 : max_threads;
1234 max_processes = (max_processes <= 0) ? 1 : max_processes;
1235
1236 object = PyLong_FromLong(max_processes);
1237 PyModule_AddObject(module, "maximum_processes", object);
1238
1239 object = PyLong_FromLong(max_threads);
1240 PyModule_AddObject(module, "threads_per_process", object);
1241 #endif
1242
1243 PyModule_AddObject(module, "server_metrics", PyCFunction_New(
1244 &wsgi_server_metrics_method[0], NULL));
1245
1246 PyModule_AddObject(module, "process_metrics", PyCFunction_New(
1247 &wsgi_process_metrics_method[0], NULL));
1248
1249 PyModule_AddObject(module, "subscribe_events", PyCFunction_New(
1250 &wsgi_process_events_method[0], NULL));
1251
1252 PyModule_AddObject(module, "event_callbacks", PyList_New(0));
1253
1254 PyModule_AddObject(module, "active_requests", PyDict_New());
1255
1256 PyModule_AddObject(module, "request_data", PyCFunction_New(
1257 &wsgi_request_data_method[0], NULL));
1258
1259 /* Done with the 'mod_wsgi' module. */
1260
1261 Py_DECREF(module);
1262
1263 /*
1264 * Create 'apache' Python module. If this is not a daemon
1265 * process and it is the first interpreter created by
1266 * Python, we first try and import an external Python module
1267 * of the same name. The intent is that this external module
1268 * would provide the SWIG bindings for the internal Apache
1269 * APIs. Only support use of such bindings in the first
1270 * interpreter created due to threading issues in SWIG
1271 * generated.
1272 */
1273
1274 module = NULL;
1275
1276 if (!wsgi_daemon_pool) {
1277 module = PyImport_ImportModule("apache");
1278
1279 if (!module) {
1280 PyObject *modules = NULL;
1281
1282 modules = PyImport_GetModuleDict();
1283 module = PyDict_GetItemString(modules, "apache");
1284
1285 if (module) {
1286 Py_BEGIN_ALLOW_THREADS
1287 ap_log_error(APLOG_MARK, APLOG_INFO, 0, wsgi_server,
1288 "mod_wsgi (pid=%d): Unable to import "
1289 "'apache' extension module.", getpid());
1290 Py_END_ALLOW_THREADS
1291
1292 PyErr_Print();
1293
1294 PyDict_DelItemString(modules, "apache");
1295
1296 module = NULL;
1297 }
1298
1299 PyErr_Clear();
1300 }
1301 else {
1302 Py_BEGIN_ALLOW_THREADS
1303 ap_log_error(APLOG_MARK, APLOG_INFO, 0, wsgi_server,
1304 "mod_wsgi (pid=%d): Imported 'apache'.",
1305 getpid());
1306 Py_END_ALLOW_THREADS
1307 }
1308 }
1309
1310 if (!module) {
1311 module = PyImport_AddModule("apache");
1312
1313 Py_INCREF(module);
1314 }
1315
1316 /*
1317 * Add Apache version information to the Python 'apache'
1318 * module.
1319 */
1320
1321 PyModule_AddObject(module, "version", Py_BuildValue("(iii)",
1322 AP_SERVER_MAJORVERSION_NUMBER,
1323 AP_SERVER_MINORVERSION_NUMBER,
1324 AP_SERVER_PATCHLEVEL_NUMBER));
1325
1326 /*
1327 * Add information about the Apache MPM configuration and
1328 * the number of processes and threads available.
1329 */
1330
1331 ap_mpm_query(AP_MPMQ_IS_THREADED, &is_threaded);
1332 if (is_threaded != AP_MPMQ_NOT_SUPPORTED) {
1333 ap_mpm_query(AP_MPMQ_MAX_THREADS, &max_threads);
1334 }
1335 ap_mpm_query(AP_MPMQ_IS_FORKED, &is_forked);
1336 if (is_forked != AP_MPMQ_NOT_SUPPORTED) {
1337 ap_mpm_query(AP_MPMQ_MAX_DAEMON_USED, &max_processes);
1338 if (max_processes == -1) {
1339 ap_mpm_query(AP_MPMQ_MAX_DAEMONS, &max_processes);
1340 }
1341 }
1342
1343 max_threads = (max_threads <= 0) ? 1 : max_threads;
1344 max_processes = (max_processes <= 0) ? 1 : max_processes;
1345
1346 object = PyLong_FromLong(max_processes);
1347 PyModule_AddObject(module, "maximum_processes", object);
1348
1349 object = PyLong_FromLong(max_threads);
1350 PyModule_AddObject(module, "threads_per_process", object);
1351
1352 #if AP_MODULE_MAGIC_AT_LEAST(20051115,4)
1353 str = ap_get_server_description();
1354 #else
1355 str = ap_get_server_version();
1356 #endif
1357 #if PY_MAJOR_VERSION >= 3
1358 object = PyUnicode_DecodeLatin1(str, strlen(str), NULL);
1359 #else
1360 object = PyString_FromString(str);
1361 #endif
1362 PyModule_AddObject(module, "description", object);
1363
1364 str = MPM_NAME;
1365 #if PY_MAJOR_VERSION >= 3
1366 object = PyUnicode_DecodeLatin1(str, strlen(str), NULL);
1367 #else
1368 object = PyString_FromString(str);
1369 #endif
1370 PyModule_AddObject(module, "mpm_name", object);
1371
1372 str = ap_get_server_built();
1373 #if PY_MAJOR_VERSION >= 3
1374 object = PyUnicode_DecodeLatin1(str, strlen(str), NULL);
1375 #else
1376 object = PyString_FromString(str);
1377 #endif
1378 PyModule_AddObject(module, "build_date", object);
1379
1380 /* Done with the 'apache' module. */
1381
1382 Py_DECREF(module);
1383
1384 /*
1385 * If support for New Relic monitoring is enabled then
1386 * import New Relic agent module and initialise it.
1387 */
1388
1389 if (!wsgi_daemon_pool) {
1390 wsgi_newrelic_config_file = wsgi_server_config->newrelic_config_file;
1391 wsgi_newrelic_environment = wsgi_server_config->newrelic_environment;
1392 }
1393
1394 if (wsgi_newrelic_config_file) {
1395 PyObject *dict = NULL;
1396
1397 module = PyImport_ImportModule("newrelic.agent");
1398
1399 if (module) {
1400 Py_BEGIN_ALLOW_THREADS
1401 ap_log_error(APLOG_MARK, APLOG_INFO, 0, wsgi_server,
1402 "mod_wsgi (pid=%d, process='%s', application='%s'): "
1403 "Imported 'newrelic.agent'.", getpid(),
1404 wsgi_daemon_group , name);
1405 Py_END_ALLOW_THREADS
1406
1407 dict = PyModule_GetDict(module);
1408 object = PyDict_GetItemString(dict, "initialize");
1409
1410 if (object) {
1411 PyObject *config_file = NULL;
1412 PyObject *environment = NULL;
1413 PyObject *result = NULL;
1414
1415 #if PY_MAJOR_VERSION >= 3
1416 config_file = PyUnicode_Decode(wsgi_newrelic_config_file,
1417 strlen(wsgi_newrelic_config_file),
1418 Py_FileSystemDefaultEncoding,
1419 "surrogateescape");
1420 #else
1421 config_file = PyString_FromString(wsgi_newrelic_config_file);
1422 #endif
1423
1424 if (wsgi_newrelic_environment) {
1425 #if PY_MAJOR_VERSION >= 3
1426 environment = PyUnicode_Decode(wsgi_newrelic_environment,
1427 strlen(wsgi_newrelic_environment),
1428 Py_FileSystemDefaultEncoding,
1429 "surrogateescape");
1430 #else
1431 environment = PyString_FromString(
1432 wsgi_newrelic_environment);
1433 #endif
1434 }
1435 else {
1436 Py_INCREF(Py_None);
1437 environment = Py_None;
1438 }
1439
1440 result = PyObject_CallFunctionObjArgs(object, config_file,
1441 environment, NULL);
1442
1443 if (!result) {
1444 Py_BEGIN_ALLOW_THREADS
1445 ap_log_error(APLOG_MARK, APLOG_INFO, 0, wsgi_server,
1446 "mod_wsgi (pid=%d): Unable to initialise "
1447 "New Relic agent with config '%s'.", getpid(),
1448 wsgi_newrelic_config_file);
1449 Py_END_ALLOW_THREADS
1450 }
1451
1452 Py_DECREF(config_file);
1453 Py_DECREF(environment);
1454
1455 Py_XDECREF(result);
1456
1457 Py_DECREF(object);
1458 }
1459
1460 Py_XDECREF(module);
1461 }
1462 else {
1463 Py_BEGIN_ALLOW_THREADS
1464 ap_log_error(APLOG_MARK, APLOG_INFO, 0, wsgi_server,
1465 "mod_wsgi (pid=%d): Unable to import "
1466 "'newrelic.agent' module.", getpid());
1467 Py_END_ALLOW_THREADS
1468
1469 PyErr_Print();
1470 PyErr_Clear();
1471 }
1472 }
1473
1474 /*
1475 * Restore previous thread state. Only need to do
1476 * this where had to create a new interpreter. This
1477 * is basically anything except the first Python
1478 * interpreter instance. We need to restore it in
1479 * these cases as came into the function holding the
1480 * simplified GIL state for this thread but creating
1481 * the interpreter has resulted in a new thread
1482 * state object being created bound to the newly
1483 * created interpreter. In doing this though we want
1484 * to cache the thread state object which has been
1485 * created when interpreter is created. This is so
1486 * it can be reused later ensuring that thread local
1487 * data persists between requests.
1488 */
1489
1490 if (self->owner) {
1491 #if APR_HAS_THREADS
1492 WSGIThreadInfo *thread_handle = NULL;
1493
1494 self->tstate_table = apr_hash_make(wsgi_server->process->pool);
1495
1496 thread_handle = wsgi_thread_info(1, 0);
1497
1498 if (wsgi_server_config->verbose_debugging) {
1499 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, wsgi_server,
1500 "mod_wsgi (pid=%d): Bind thread state for "
1501 "thread %d against interpreter '%s'.", getpid(),
1502 thread_handle->thread_id, self->name);
1503 }
1504
1505 apr_hash_set(self->tstate_table, &thread_handle->thread_id,
1506 sizeof(thread_handle->thread_id), tstate);
1507
1508 PyThreadState_Swap(save_tstate);
1509 #else
1510 self->tstate = tstate;
1511 PyThreadState_Swap(save_tstate);
1512 #endif
1513 }
1514
1515 return self;
1516 }
1517
Interpreter_dealloc(InterpreterObject * self)1518 static void Interpreter_dealloc(InterpreterObject *self)
1519 {
1520 PyThreadState *tstate = NULL;
1521 PyObject *module = NULL;
1522
1523 PyThreadState *tstate_enter = NULL;
1524
1525 #if PY_MAJOR_VERSION < 3 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 4)
1526 PyObject *exitfunc = NULL;
1527 #endif
1528
1529 /*
1530 * We should always enter here with the Python GIL
1531 * held and an active thread state. This should only
1532 * now occur when shutting down interpreter and not
1533 * when releasing interpreter as don't support
1534 * recyling of interpreters within the process. Thus
1535 * the thread state should be that for the main
1536 * Python interpreter. Where dealing with a named
1537 * sub interpreter, we need to change the thread
1538 * state to that which was originally used to create
1539 * that sub interpreter before doing anything.
1540 */
1541
1542 tstate_enter = PyThreadState_Get();
1543
1544 if (*self->name) {
1545 #if APR_HAS_THREADS
1546 WSGIThreadInfo *thread_handle = NULL;
1547
1548 thread_handle = wsgi_thread_info(1, 0);
1549
1550 tstate = apr_hash_get(self->tstate_table, &thread_handle->thread_id,
1551 sizeof(thread_handle->thread_id));
1552
1553 if (!tstate) {
1554 tstate = PyThreadState_New(self->interp);
1555
1556 if (wsgi_server_config->verbose_debugging) {
1557 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, wsgi_server,
1558 "mod_wsgi (pid=%d): Create thread state for "
1559 "thread %d against interpreter '%s'.", getpid(),
1560 thread_handle->thread_id, self->name);
1561 }
1562
1563 apr_hash_set(self->tstate_table, &thread_handle->thread_id,
1564 sizeof(thread_handle->thread_id), tstate);
1565 }
1566 #else
1567 tstate = self->tstate;
1568 #endif
1569
1570 /*
1571 * Swap to interpreter thread state that was used when
1572 * the sub interpreter was created.
1573 */
1574
1575 PyThreadState_Swap(tstate);
1576 }
1577
1578 /* Now destroy the sub interpreter. */
1579
1580 if (self->owner) {
1581 Py_BEGIN_ALLOW_THREADS
1582 ap_log_error(APLOG_MARK, APLOG_INFO, 0, wsgi_server,
1583 "mod_wsgi (pid=%d): Destroy interpreter '%s'.",
1584 getpid(), self->name);
1585 Py_END_ALLOW_THREADS
1586 }
1587 else {
1588 Py_BEGIN_ALLOW_THREADS
1589 ap_log_error(APLOG_MARK, APLOG_INFO, 0, wsgi_server,
1590 "mod_wsgi (pid=%d): Cleanup interpreter '%s'.",
1591 getpid(), self->name);
1592 Py_END_ALLOW_THREADS
1593 }
1594
1595 /*
1596 * Because the thread state we are using was created outside
1597 * of any Python code and is not the same as the Python main
1598 * thread, there is no record of it within the 'threading'
1599 * module. We thus need to access current thread function of
1600 * the 'threading' module to force it to create a thread
1601 * handle for the thread. If we do not do this, then the
1602 * 'threading' modules exit function will always fail
1603 * because it will not be able to find a handle for this
1604 * thread.
1605 */
1606
1607 module = PyImport_ImportModule("threading");
1608
1609 if (!module)
1610 PyErr_Clear();
1611
1612 if (module) {
1613 PyObject *dict = NULL;
1614 PyObject *func = NULL;
1615
1616 dict = PyModule_GetDict(module);
1617 #if PY_MAJOR_VERSION >= 3
1618 func = PyDict_GetItemString(dict, "current_thread");
1619 #else
1620 func = PyDict_GetItemString(dict, "currentThread");
1621 #endif
1622 if (func) {
1623 PyObject *res = NULL;
1624 Py_INCREF(func);
1625 res = PyEval_CallObject(func, (PyObject *)NULL);
1626 if (!res) {
1627 PyErr_Clear();
1628 }
1629 Py_XDECREF(res);
1630 Py_DECREF(func);
1631 }
1632 }
1633
1634 /*
1635 * In Python 2.5.1 an exit function is no longer used to
1636 * shutdown and wait on non daemon threads which were created
1637 * from Python code. Instead, in Py_Main() it explicitly
1638 * calls 'threading._shutdown()'. Thus need to emulate this
1639 * behaviour for those versions.
1640 */
1641
1642 #if PY_MAJOR_VERSION < 3 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 4)
1643 if (module) {
1644 PyObject *dict = NULL;
1645 PyObject *func = NULL;
1646
1647 dict = PyModule_GetDict(module);
1648 func = PyDict_GetItemString(dict, "_shutdown");
1649 if (func) {
1650 PyObject *res = NULL;
1651 Py_INCREF(func);
1652 res = PyEval_CallObject(func, (PyObject *)NULL);
1653
1654 if (res == NULL) {
1655 PyObject *m = NULL;
1656 PyObject *result = NULL;
1657
1658 PyObject *type = NULL;
1659 PyObject *value = NULL;
1660 PyObject *traceback = NULL;
1661
1662 Py_BEGIN_ALLOW_THREADS
1663 ap_log_error(APLOG_MARK, APLOG_ERR, 0, wsgi_server,
1664 "mod_wsgi (pid=%d): Exception occurred within "
1665 "threading._shutdown().", getpid());
1666 Py_END_ALLOW_THREADS
1667
1668 PyErr_Fetch(&type, &value, &traceback);
1669 PyErr_NormalizeException(&type, &value, &traceback);
1670
1671 if (!value) {
1672 value = Py_None;
1673 Py_INCREF(value);
1674 }
1675
1676 if (!traceback) {
1677 traceback = Py_None;
1678 Py_INCREF(traceback);
1679 }
1680
1681 m = PyImport_ImportModule("traceback");
1682
1683 if (m) {
1684 PyObject *d = NULL;
1685 PyObject *o = NULL;
1686 d = PyModule_GetDict(m);
1687 o = PyDict_GetItemString(d, "print_exception");
1688 if (o) {
1689 PyObject *log = NULL;
1690 PyObject *args = NULL;
1691 Py_INCREF(o);
1692 log = newLogObject(NULL, APLOG_ERR, NULL, 0);
1693 args = Py_BuildValue("(OOOOO)", type, value,
1694 traceback, Py_None, log);
1695 result = PyEval_CallObject(o, args);
1696 Py_DECREF(args);
1697 Py_DECREF(log);
1698 Py_DECREF(o);
1699 }
1700 }
1701
1702 if (!result) {
1703 /*
1704 * If can't output exception and traceback then
1705 * use PyErr_Print to dump out details of the
1706 * exception. For SystemExit though if we do
1707 * that the process will actually be terminated
1708 * so can only clear the exception information
1709 * and keep going.
1710 */
1711
1712 PyErr_Restore(type, value, traceback);
1713
1714 if (!PyErr_ExceptionMatches(PyExc_SystemExit)) {
1715 PyErr_Print();
1716 PyErr_Clear();
1717 }
1718 else {
1719 PyErr_Clear();
1720 }
1721 }
1722 else {
1723 Py_XDECREF(type);
1724 Py_XDECREF(value);
1725 Py_XDECREF(traceback);
1726 }
1727
1728 Py_XDECREF(result);
1729
1730 Py_XDECREF(m);
1731 }
1732
1733 Py_XDECREF(res);
1734 Py_DECREF(func);
1735 }
1736 }
1737
1738 /* Finally done with 'threading' module. */
1739
1740 Py_XDECREF(module);
1741
1742 /*
1743 * Invoke exit functions by calling sys.exitfunc() for
1744 * Python 2.X and atexit._run_exitfuncs() for Python 3.X.
1745 * Note that in Python 3.X we can't call this on main Python
1746 * interpreter as for Python 3.X it doesn't deregister
1747 * functions as called, so have no choice but to rely on
1748 * Py_Finalize() to do it for the main interpreter. Now
1749 * that simplified GIL state API usage sorted out, this
1750 * should be okay.
1751 */
1752
1753 module = NULL;
1754
1755 #if PY_MAJOR_VERSION >= 3
1756 if (self->owner) {
1757 module = PyImport_ImportModule("atexit");
1758
1759 if (module) {
1760 PyObject *dict = NULL;
1761
1762 dict = PyModule_GetDict(module);
1763 exitfunc = PyDict_GetItemString(dict, "_run_exitfuncs");
1764 }
1765 else
1766 PyErr_Clear();
1767 }
1768 #else
1769 exitfunc = PySys_GetObject("exitfunc");
1770 #endif
1771
1772 if (exitfunc) {
1773 PyObject *res = NULL;
1774 Py_INCREF(exitfunc);
1775 PySys_SetObject("exitfunc", (PyObject *)NULL);
1776 res = PyEval_CallObject(exitfunc, (PyObject *)NULL);
1777
1778 if (res == NULL) {
1779 PyObject *m = NULL;
1780 PyObject *result = NULL;
1781
1782 PyObject *type = NULL;
1783 PyObject *value = NULL;
1784 PyObject *traceback = NULL;
1785
1786 if (PyErr_ExceptionMatches(PyExc_SystemExit)) {
1787 Py_BEGIN_ALLOW_THREADS
1788 ap_log_error(APLOG_MARK, APLOG_ERR, 0, wsgi_server,
1789 "mod_wsgi (pid=%d): SystemExit exception "
1790 "raised by exit functions ignored.", getpid());
1791 Py_END_ALLOW_THREADS
1792 }
1793 else {
1794 Py_BEGIN_ALLOW_THREADS
1795 ap_log_error(APLOG_MARK, APLOG_ERR, 0, wsgi_server,
1796 "mod_wsgi (pid=%d): Exception occurred within "
1797 "exit functions.", getpid());
1798 Py_END_ALLOW_THREADS
1799 }
1800
1801 PyErr_Fetch(&type, &value, &traceback);
1802 PyErr_NormalizeException(&type, &value, &traceback);
1803
1804 if (!value) {
1805 value = Py_None;
1806 Py_INCREF(value);
1807 }
1808
1809 if (!traceback) {
1810 traceback = Py_None;
1811 Py_INCREF(traceback);
1812 }
1813
1814 m = PyImport_ImportModule("traceback");
1815
1816 if (m) {
1817 PyObject *d = NULL;
1818 PyObject *o = NULL;
1819 d = PyModule_GetDict(m);
1820 o = PyDict_GetItemString(d, "print_exception");
1821 if (o) {
1822 PyObject *log = NULL;
1823 PyObject *args = NULL;
1824 Py_INCREF(o);
1825 log = newLogObject(NULL, APLOG_ERR, NULL, 0);
1826 args = Py_BuildValue("(OOOOO)", type, value,
1827 traceback, Py_None, log);
1828 result = PyEval_CallObject(o, args);
1829 Py_DECREF(args);
1830 Py_DECREF(log);
1831 Py_DECREF(o);
1832 }
1833 }
1834
1835 if (!result) {
1836 /*
1837 * If can't output exception and traceback then
1838 * use PyErr_Print to dump out details of the
1839 * exception. For SystemExit though if we do
1840 * that the process will actually be terminated
1841 * so can only clear the exception information
1842 * and keep going.
1843 */
1844
1845 PyErr_Restore(type, value, traceback);
1846
1847 if (!PyErr_ExceptionMatches(PyExc_SystemExit)) {
1848 PyErr_Print();
1849 PyErr_Clear();
1850 }
1851 else {
1852 PyErr_Clear();
1853 }
1854 }
1855 else {
1856 Py_XDECREF(type);
1857 Py_XDECREF(value);
1858 Py_XDECREF(traceback);
1859 }
1860
1861 Py_XDECREF(result);
1862
1863 Py_XDECREF(m);
1864 }
1865
1866 Py_XDECREF(res);
1867 Py_DECREF(exitfunc);
1868 }
1869
1870 Py_XDECREF(module);
1871 #endif
1872
1873 /* If we own it, we destroy it. */
1874
1875 if (self->owner) {
1876 /*
1877 * We need to destroy all the thread state objects
1878 * associated with the interpreter. If there are
1879 * background threads that were created then this
1880 * may well cause them to crash the next time they
1881 * try to run. Only saving grace is that we are
1882 * trying to shutdown the process.
1883 */
1884
1885 #if PY_MAJOR_VERSION < 3 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 4)
1886 PyThreadState *tstate_save = tstate;
1887 PyThreadState *tstate_next = NULL;
1888
1889 PyThreadState_Swap(NULL);
1890
1891 tstate = PyInterpreterState_ThreadHead(tstate->interp);
1892
1893 while (tstate) {
1894 tstate_next = PyThreadState_Next(tstate);
1895 if (tstate != tstate_save) {
1896 PyThreadState_Swap(tstate);
1897 PyThreadState_Clear(tstate);
1898 PyThreadState_Swap(NULL);
1899 PyThreadState_Delete(tstate);
1900 }
1901 tstate = tstate_next;
1902 }
1903
1904 tstate = tstate_save;
1905
1906 PyThreadState_Swap(tstate);
1907 #endif
1908
1909 /* Can now destroy the interpreter. */
1910
1911 Py_BEGIN_ALLOW_THREADS
1912 ap_log_error(APLOG_MARK, APLOG_INFO, 0, wsgi_server,
1913 "mod_wsgi (pid=%d): End interpreter '%s'.",
1914 getpid(), self->name);
1915 Py_END_ALLOW_THREADS
1916
1917 Py_EndInterpreter(tstate);
1918
1919 PyThreadState_Swap(tstate_enter);
1920 }
1921
1922 free(self->name);
1923
1924 PyObject_Del(self);
1925 }
1926
1927 PyTypeObject Interpreter_Type = {
1928 PyVarObject_HEAD_INIT(NULL, 0)
1929 "mod_wsgi.Interpreter", /*tp_name*/
1930 sizeof(InterpreterObject), /*tp_basicsize*/
1931 0, /*tp_itemsize*/
1932 /* methods */
1933 (destructor)Interpreter_dealloc, /*tp_dealloc*/
1934 0, /*tp_print*/
1935 0, /*tp_getattr*/
1936 0, /*tp_setattr*/
1937 0, /*tp_compare*/
1938 0, /*tp_repr*/
1939 0, /*tp_as_number*/
1940 0, /*tp_as_sequence*/
1941 0, /*tp_as_mapping*/
1942 0, /*tp_hash*/
1943 0, /*tp_call*/
1944 0, /*tp_str*/
1945 0, /*tp_getattro*/
1946 0, /*tp_setattro*/
1947 0, /*tp_as_buffer*/
1948 Py_TPFLAGS_DEFAULT, /*tp_flags*/
1949 0, /*tp_doc*/
1950 0, /*tp_traverse*/
1951 0, /*tp_clear*/
1952 0, /*tp_richcompare*/
1953 0, /*tp_weaklistoffset*/
1954 0, /*tp_iter*/
1955 0, /*tp_iternext*/
1956 0, /*tp_methods*/
1957 0, /*tp_members*/
1958 0, /*tp_getset*/
1959 0, /*tp_base*/
1960 0, /*tp_dict*/
1961 0, /*tp_descr_get*/
1962 0, /*tp_descr_set*/
1963 0, /*tp_dictoffset*/
1964 0, /*tp_init*/
1965 0, /*tp_alloc*/
1966 0, /*tp_new*/
1967 0, /*tp_free*/
1968 0, /*tp_is_gc*/
1969 };
1970
1971 /*
1972 * Startup and shutdown of Python interpreter. In mod_wsgi if
1973 * the Python interpreter hasn't been initialised by another
1974 * Apache module such as mod_python, we will take control and
1975 * initialise it. Need to remember that we initialised Python
1976 * and whether done in parent or child process as when done in
1977 * the parent we also take responsibility for performing special
1978 * Python fixups after Apache is forked and child process has
1979 * run.
1980 *
1981 * Note that by default we now defer initialisation of Python
1982 * until after the fork of processes as Python 3.X by design
1983 * doesn't clean up properly when it is destroyed causing
1984 * significant memory leaks into Apache parent process on an
1985 * Apache restart. Some Python 2.X versions also have real
1986 * memory leaks but not near as much. The result of deferring
1987 * initialisation is that can't benefit from copy on write
1988 * semantics for loaded data across a fork. Each process will
1989 * therefore have higher memory requirement where Python needs
1990 * to be used.
1991 */
1992
1993 int wsgi_python_initialized = 0;
1994
1995 #if defined(MOD_WSGI_DISABLE_EMBEDDED)
1996 int wsgi_python_required = 0;
1997 #else
1998 int wsgi_python_required = -1;
1999 #endif
2000
2001 int wsgi_python_after_fork = 1;
2002
wsgi_python_version(void)2003 void wsgi_python_version(void)
2004 {
2005 const char *compile = PY_VERSION;
2006 const char *dynamic = 0;
2007
2008 dynamic = strtok((char *)Py_GetVersion(), " ");
2009
2010 if (strcmp(compile, dynamic) != 0) {
2011 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, wsgi_server,
2012 "mod_wsgi: Compiled for Python/%s.", compile);
2013 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, wsgi_server,
2014 "mod_wsgi: Runtime using Python/%s.", dynamic);
2015 }
2016 }
2017
wsgi_python_term(void)2018 apr_status_t wsgi_python_term(void)
2019 {
2020 PyObject *module = NULL;
2021
2022 ap_log_error(APLOG_MARK, APLOG_INFO, 0, wsgi_server,
2023 "mod_wsgi (pid=%d): Terminating Python.", getpid());
2024
2025 /*
2026 * We should be executing in the main thread again at this
2027 * point but without the GIL, so simply restore the original
2028 * thread state for that thread that we remembered when we
2029 * initialised the interpreter.
2030 */
2031
2032 PyEval_AcquireThread(wsgi_main_tstate);
2033
2034 /*
2035 * Work around bug in Python 3.X whereby it will crash if
2036 * atexit imported into sub interpreter, but never imported
2037 * into main interpreter before calling Py_Finalize(). We
2038 * perform an import of atexit module and it as side effect
2039 * must be performing required initialisation.
2040 */
2041
2042 module = PyImport_ImportModule("atexit");
2043 Py_XDECREF(module);
2044
2045 /*
2046 * In Python 2.6.5 and Python 3.1.2 the shutdown of
2047 * threading was moved back into Py_Finalize() for the main
2048 * Python interpreter. Because we shutting down threading
2049 * ourselves, the second call results in errors being logged
2050 * when Py_Finalize() is called and the shutdown function
2051 * called a second time. The errors don't indicate any real
2052 * problem and the threading module ignores them anyway.
2053 * Whether we are using Python with this changed behaviour
2054 * can only be checked by looking at run time version.
2055 * Rather than try and add a dynamic check, create a fake
2056 * 'dummy_threading' module as the presence of that shuts up
2057 * the messages. It doesn't matter that the rest of the
2058 * shutdown function still runs as everything is already
2059 * stopped so doesn't do anything.
2060 */
2061
2062 if (!PyImport_AddModule("dummy_threading"))
2063 PyErr_Clear();
2064
2065 /*
2066 * Shutdown Python interpreter completely. Just to be safe
2067 * flag daemon shutdown here again and do it within a lock
2068 * which is then shared with deadlock thread used for the
2069 * daemon. This is just to avoid any risk there is a race
2070 * condition.
2071 */
2072
2073 #if defined(MOD_WSGI_WITH_DAEMONS)
2074 if (wsgi_daemon_process)
2075 apr_thread_mutex_lock(wsgi_shutdown_lock);
2076
2077 wsgi_daemon_shutdown++;
2078 #endif
2079
2080 Py_Finalize();
2081
2082 #if defined(MOD_WSGI_WITH_DAEMONS)
2083 if (wsgi_daemon_process)
2084 apr_thread_mutex_unlock(wsgi_shutdown_lock);
2085 #endif
2086
2087 wsgi_python_initialized = 0;
2088
2089 ap_log_error(APLOG_MARK, APLOG_INFO, 0, wsgi_server,
2090 "mod_wsgi (pid=%d): Python has shutdown.", getpid());
2091
2092 return APR_SUCCESS;
2093 }
2094
wsgi_python_parent_cleanup(void * data)2095 static apr_status_t wsgi_python_parent_cleanup(void *data)
2096 {
2097 if (wsgi_parent_pid == getpid()) {
2098 /*
2099 * Destroy Python itself including the main
2100 * interpreter. If mod_python is being loaded it
2101 * is left to mod_python to destroy Python,
2102 * although it currently doesn't do so.
2103 */
2104
2105 if (wsgi_python_initialized)
2106 wsgi_python_term();
2107 }
2108
2109 return APR_SUCCESS;
2110 }
2111
2112
wsgi_python_init(apr_pool_t * p)2113 void wsgi_python_init(apr_pool_t *p)
2114 {
2115 const char *python_home = 0;
2116
2117 int is_pyvenv = 0;
2118
2119 /* Perform initialisation if required. */
2120
2121 if (!Py_IsInitialized()) {
2122
2123 /* Enable Python 3.0 migration warnings. */
2124
2125 #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 6
2126 if (wsgi_server_config->py3k_warning_flag == 1)
2127 Py_Py3kWarningFlag++;
2128 #endif
2129
2130 /* Disable writing of byte code files. */
2131
2132 #if (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 3) || \
2133 (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 6)
2134 if (wsgi_server_config->dont_write_bytecode == 1)
2135 Py_DontWriteBytecodeFlag++;
2136 #endif
2137
2138 /* Check for Python paths and optimisation flag. */
2139
2140 if (wsgi_server_config->python_optimize > 0)
2141 Py_OptimizeFlag = wsgi_server_config->python_optimize;
2142 else
2143 Py_OptimizeFlag = 0;
2144
2145 /* Check for control options for Python warnings. */
2146
2147 if (wsgi_server_config->python_warnings) {
2148 apr_array_header_t *options = NULL;
2149 char **entries;
2150
2151 int i;
2152
2153 options = wsgi_server_config->python_warnings;
2154 entries = (char **)options->elts;
2155
2156 for (i = 0; i < options->nelts; ++i) {
2157 #if PY_MAJOR_VERSION >= 3
2158 wchar_t *s = NULL;
2159 int len = strlen(entries[i])+1;
2160
2161 s = (wchar_t *)apr_palloc(p, len*sizeof(wchar_t));
2162
2163 #if defined(WIN32) && defined(APR_HAS_UNICODE_FS)
2164 wsgi_utf8_to_unicode_path(s, len, entries[i]);
2165 #else
2166 mbstowcs(s, entries[i], len);
2167 #endif
2168 PySys_AddWarnOption(s);
2169 #else
2170 PySys_AddWarnOption(entries[i]);
2171 #endif
2172 }
2173 }
2174
2175 #if defined(WIN32)
2176 /*
2177 * Check for Python HOME being overridden. This is only being
2178 * used on Windows for now. For UNIX systems we actually do
2179 * a fiddle and work out where the Python executable would be
2180 * and set its location instead. This is to get around some
2181 * brokeness in pyvenv in Python 3.X. We don't know if that
2182 * workaround works for Windows yet, but since not supporting
2183 * Windows for mod_wsgi 4.X as yet, doesn't matter.
2184 */
2185
2186 python_home = wsgi_server_config->python_home;
2187
2188 if (python_home) {
2189 ap_log_error(APLOG_MARK, APLOG_INFO, 0, wsgi_server,
2190 "mod_wsgi (pid=%d): Python home %s.", getpid(),
2191 python_home);
2192 }
2193
2194 if (python_home) {
2195 #if PY_MAJOR_VERSION >= 3
2196 wchar_t *s = NULL;
2197 int len = strlen(python_home)+1;
2198
2199 s = (wchar_t *)apr_palloc(p, len*sizeof(wchar_t));
2200
2201 #if defined(WIN32) && defined(APR_HAS_UNICODE_FS)
2202 wsgi_utf8_to_unicode_path(s, len, python_home);
2203 #else
2204 mbstowcs(s, python_home, len);
2205 #endif
2206 Py_SetPythonHome(s);
2207 #else
2208 Py_SetPythonHome((char *)python_home);
2209 #endif
2210 }
2211
2212 #else
2213 /*
2214 * Now for the UNIX version of the code to set the Python HOME.
2215 * For this things are a mess. If using pyvenv with Python 3.3+
2216 * then setting Python HOME doesn't work. For it we need to use
2217 * Python executable location. Everything else seems to be cool
2218 * with setting Python HOME. We therefore need to detect when we
2219 * have a pyvenv by looking for the presence of pyvenv.cfg file.
2220 * We can simply just set Python executable everywhere as that
2221 * doesn't work with brew Python on MacOS X.
2222 */
2223
2224 python_home = wsgi_server_config->python_home;
2225
2226 #if defined(MOD_WSGI_WITH_DAEMONS)
2227 if (wsgi_daemon_process && wsgi_daemon_process->group->python_home)
2228 python_home = wsgi_daemon_process->group->python_home;
2229 #endif
2230
2231 if (python_home) {
2232 apr_status_t rv;
2233 apr_finfo_t finfo;
2234
2235 char *pyvenv_cfg;
2236
2237 const char *python_exe = 0;
2238
2239 #if PY_MAJOR_VERSION >= 3
2240 wchar_t *s = NULL;
2241 int len = 0;
2242 #endif
2243
2244 /*
2245 * Is common to see people set the directory to an incorrect
2246 * location, including to a location within an inaccessible
2247 * user home directory, or to the 'python' executable itself.
2248 * Try and validate that the location is accessible and is a
2249 * directory.
2250 */
2251
2252 ap_log_error(APLOG_MARK, APLOG_INFO, 0, wsgi_server,
2253 "mod_wsgi (pid=%d): Python home %s.", getpid(),
2254 python_home);
2255
2256 rv = apr_stat(&finfo, python_home, APR_FINFO_NORM, p);
2257
2258 if (rv != APR_SUCCESS) {
2259 ap_log_error(APLOG_MARK, APLOG_WARNING, rv, wsgi_server,
2260 "mod_wsgi (pid=%d): Unable to stat Python home "
2261 "%s. Python interpreter may not be able to be "
2262 "initialized correctly. Verify the supplied path "
2263 "and access permissions for whole of the path.",
2264 getpid(), python_home);
2265 }
2266 else {
2267 if (finfo.filetype != APR_DIR) {
2268 ap_log_error(APLOG_MARK, APLOG_WARNING, rv, wsgi_server,
2269 "mod_wsgi (pid=%d): Python home %s is not "
2270 "a directory. Python interpreter may not "
2271 "be able to be initialized correctly. "
2272 "Verify the supplied path.", getpid(),
2273 python_home);
2274 }
2275 else if (access(python_home, X_OK) == -1) {
2276 ap_log_error(APLOG_MARK, APLOG_WARNING, rv, wsgi_server,
2277 "mod_wsgi (pid=%d): Python home %s is not "
2278 "accessible. Python interpreter may not "
2279 "be able to be initialized correctly. "
2280 "Verify the supplied path and access "
2281 "permissions on the directory.", getpid(),
2282 python_home);
2283 }
2284 }
2285
2286 /* Now detect whether have a pyvenv with Python 3.3+. */
2287
2288 pyvenv_cfg = apr_pstrcat(p, python_home, "/pyvenv.cfg", NULL);
2289
2290 if (access(pyvenv_cfg, R_OK) == 0)
2291 is_pyvenv = 1;
2292
2293 if (is_pyvenv) {
2294 /*
2295 * Embedded support for pyvenv is broken so need to
2296 * set Python executable location and cannot set the
2297 * Python HOME as is more desirable.
2298 */
2299
2300 python_exe = apr_pstrcat(p, python_home, "/bin/python", NULL);
2301 #if PY_MAJOR_VERSION >= 3
2302 len = strlen(python_exe)+1;
2303 s = (wchar_t *)apr_palloc(p, len*sizeof(wchar_t));
2304 mbstowcs(s, python_exe, len);
2305
2306 Py_SetProgramName(s);
2307 #else
2308 Py_SetProgramName((char *)python_exe);
2309 #endif
2310 }
2311 else {
2312 #if PY_MAJOR_VERSION >= 3
2313 len = strlen(python_home)+1;
2314 s = (wchar_t *)apr_palloc(p, len*sizeof(wchar_t));
2315 mbstowcs(s, python_home, len);
2316
2317 Py_SetPythonHome(s);
2318 #else
2319 Py_SetPythonHome((char *)python_home);
2320 #endif
2321 }
2322 }
2323 #endif
2324
2325 /*
2326 * Set environment variable PYTHONHASHSEED. We need to
2327 * make sure we remove the environment variable later
2328 * so that it doesn't remain in the process environment
2329 * and be inherited by execd sub processes.
2330 */
2331
2332 if (wsgi_server_config->python_hash_seed != NULL) {
2333 char *envvar = apr_pstrcat(p, "PYTHONHASHSEED=",
2334 wsgi_server_config->python_hash_seed, NULL);
2335 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, wsgi_server,
2336 "mod_wsgi (pid=%d): Setting hash seed to %s.",
2337 getpid(), wsgi_server_config->python_hash_seed);
2338 putenv(envvar);
2339 }
2340
2341 /*
2342 * Work around bug in Python 3.1 where it will crash
2343 * when used in non console application on Windows if
2344 * stdin/stdout have been initialised and aren't null.
2345 * Supposed to be fixed in Python 3.3.
2346 */
2347
2348 #if defined(WIN32) && PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 3
2349 _wputenv(L"PYTHONIOENCODING=cp1252:backslashreplace");
2350 #endif
2351
2352 /* Initialise Python. */
2353
2354 ap_log_error(APLOG_MARK, APLOG_INFO, 0, wsgi_server,
2355 "mod_wsgi (pid=%d): Initializing Python.", getpid());
2356
2357 Py_Initialize();
2358
2359 /* Initialise threading. */
2360
2361 PyEval_InitThreads();
2362
2363 /*
2364 * Remove the environment variable we set for the hash
2365 * seed. This has to be done in os.environ, which will
2366 * in turn remove it from process environ. This should
2367 * only be necessary for the main interpreter. We need
2368 * to do this before we release the GIL.
2369 */
2370
2371 if (wsgi_server_config->python_hash_seed != NULL) {
2372 PyObject *module = NULL;
2373
2374 module = PyImport_ImportModule("os");
2375
2376 if (module) {
2377 PyObject *dict = NULL;
2378 PyObject *object = NULL;
2379 PyObject *key = NULL;
2380
2381 dict = PyModule_GetDict(module);
2382 object = PyDict_GetItemString(dict, "environ");
2383
2384 if (object) {
2385 #if PY_MAJOR_VERSION >= 3
2386 key = PyUnicode_FromString("PYTHONHASHSEED");
2387 #else
2388 key = PyString_FromString("PYTHONHASHSEED");
2389 #endif
2390
2391 PyObject_DelItem(object, key);
2392
2393 Py_DECREF(key);
2394 }
2395
2396 Py_DECREF(module);
2397 }
2398 }
2399
2400 /*
2401 * We now want to release the GIL. Before we do that
2402 * though we remember what the current thread state is.
2403 * We will use that later to restore the main thread
2404 * state when we want to cleanup interpreters on
2405 * shutdown.
2406 */
2407
2408 wsgi_main_tstate = PyThreadState_Get();
2409 PyEval_ReleaseThread(wsgi_main_tstate);
2410
2411 wsgi_python_initialized = 1;
2412
2413 /*
2414 * Register cleanups to be performed on parent restart
2415 * or shutdown. This will destroy Python itself.
2416 */
2417
2418 apr_pool_cleanup_register(p, NULL, wsgi_python_parent_cleanup,
2419 apr_pool_cleanup_null);
2420 }
2421 }
2422
2423 /*
2424 * Functions for acquiring and subsequently releasing desired
2425 * Python interpreter instance. When acquiring the interpreter
2426 * a new interpreter instance will be created on demand if it
2427 * is required. The Python GIL will be held on return when the
2428 * interpreter is acquired.
2429 */
2430
2431 #if APR_HAS_THREADS
2432 apr_thread_mutex_t* wsgi_interp_lock = NULL;
2433 apr_thread_mutex_t* wsgi_shutdown_lock = NULL;
2434 #endif
2435
2436 PyObject *wsgi_interpreters = NULL;
2437
2438 apr_hash_t *wsgi_interpreters_index = NULL;
2439
wsgi_acquire_interpreter(const char * name)2440 InterpreterObject *wsgi_acquire_interpreter(const char *name)
2441 {
2442 PyThreadState *tstate = NULL;
2443 PyInterpreterState *interp = NULL;
2444 InterpreterObject *handle = NULL;
2445
2446 PyGILState_STATE state;
2447
2448 /*
2449 * In a multithreaded MPM must protect the
2450 * interpreters table. This lock is only needed to
2451 * avoid a secondary thread coming in and creating
2452 * the same interpreter if Python releases the GIL
2453 * when an interpreter is being created.
2454 */
2455
2456 #if APR_HAS_THREADS
2457 apr_thread_mutex_lock(wsgi_interp_lock);
2458 #endif
2459
2460 /*
2461 * This function should never be called when the
2462 * Python GIL is held, so need to acquire it. Even
2463 * though we may need to work with a sub
2464 * interpreter, we need to acquire GIL against main
2465 * interpreter first to work with interpreter
2466 * dictionary.
2467 */
2468
2469 state = PyGILState_Ensure();
2470
2471 /*
2472 * Check if already have interpreter instance and
2473 * if not need to create one.
2474 */
2475
2476 handle = (InterpreterObject *)PyDict_GetItemString(wsgi_interpreters,
2477 name);
2478
2479 if (!handle) {
2480 handle = newInterpreterObject(name);
2481
2482 if (!handle) {
2483 ap_log_error(APLOG_MARK, APLOG_CRIT, 0, wsgi_server,
2484 "mod_wsgi (pid=%d): Cannot create interpreter '%s'.",
2485 getpid(), name);
2486
2487 PyErr_Print();
2488 PyErr_Clear();
2489
2490 PyGILState_Release(state);
2491
2492 #if APR_HAS_THREADS
2493 apr_thread_mutex_unlock(wsgi_interp_lock);
2494 #endif
2495 return NULL;
2496 }
2497
2498 PyDict_SetItemString(wsgi_interpreters, name, (PyObject *)handle);
2499
2500 /*
2501 * Add interpreter name to index kept in Apache data
2502 * strcuture as well. Make a copy of the name just in
2503 * case we have been given temporary value.
2504 */
2505
2506 apr_hash_set(wsgi_interpreters_index, apr_pstrdup(
2507 apr_hash_pool_get(wsgi_interpreters_index), name),
2508 APR_HASH_KEY_STRING, "");
2509 }
2510 else
2511 Py_INCREF(handle);
2512
2513 interp = handle->interp;
2514
2515 /*
2516 * Create new thread state object. We should only be
2517 * getting called where no current active thread
2518 * state, so no need to remember the old one. When
2519 * working with the main Python interpreter always
2520 * use the simplified API for GIL locking so any
2521 * extension modules which use that will still work.
2522 */
2523
2524 PyGILState_Release(state);
2525
2526 #if APR_HAS_THREADS
2527 apr_thread_mutex_unlock(wsgi_interp_lock);
2528 #endif
2529
2530 if (*name) {
2531 #if APR_HAS_THREADS
2532 WSGIThreadInfo *thread_handle = NULL;
2533
2534 thread_handle = wsgi_thread_info(1, 0);
2535
2536 tstate = apr_hash_get(handle->tstate_table, &thread_handle->thread_id,
2537 sizeof(thread_handle->thread_id));
2538
2539 if (!tstate) {
2540 tstate = PyThreadState_New(interp);
2541
2542 if (wsgi_server_config->verbose_debugging) {
2543 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, wsgi_server,
2544 "mod_wsgi (pid=%d): Create thread state for "
2545 "thread %d against interpreter '%s'.", getpid(),
2546 thread_handle->thread_id, handle->name);
2547 }
2548
2549 apr_hash_set(handle->tstate_table, &thread_handle->thread_id,
2550 sizeof(thread_handle->thread_id), tstate);
2551 }
2552 #else
2553 tstate = handle->tstate;
2554 #endif
2555
2556 PyEval_AcquireThread(tstate);
2557 }
2558 else {
2559 PyGILState_Ensure();
2560
2561 /*
2562 * When simplified GIL state API is used, the thread
2563 * local data only persists for the extent of the top
2564 * level matching ensure/release calls. We want to
2565 * extend lifetime of the thread local data beyond
2566 * that, retaining it for all requests within the one
2567 * thread for the life of the process. To do that we
2568 * need to artificially increment the reference count
2569 * for the associated thread state object.
2570 */
2571
2572 tstate = PyThreadState_Get();
2573 if (tstate && tstate->gilstate_counter == 1)
2574 tstate->gilstate_counter++;
2575 }
2576
2577 return handle;
2578 }
2579
wsgi_release_interpreter(InterpreterObject * handle)2580 void wsgi_release_interpreter(InterpreterObject *handle)
2581 {
2582 PyThreadState *tstate = NULL;
2583
2584 PyGILState_STATE state;
2585
2586 /*
2587 * Need to release and destroy the thread state that
2588 * was created against the interpreter. This will
2589 * release the GIL. Note that it should be safe to
2590 * always assume that the simplified GIL state API
2591 * lock was originally unlocked as always calling in
2592 * from an Apache thread when we acquire the
2593 * interpreter in the first place.
2594 */
2595
2596 if (*handle->name) {
2597 tstate = PyThreadState_Get();
2598 PyEval_ReleaseThread(tstate);
2599 }
2600 else
2601 PyGILState_Release(PyGILState_UNLOCKED);
2602
2603 /*
2604 * Need to reacquire the Python GIL just so we can
2605 * decrement our reference count to the interpreter
2606 * itself. If the interpreter has since been removed
2607 * from the table of interpreters this will result
2608 * in its destruction if its the last reference.
2609 */
2610
2611 state = PyGILState_Ensure();
2612
2613 Py_DECREF(handle);
2614
2615 PyGILState_Release(state);
2616 }
2617
2618 /* ------------------------------------------------------------------------- */
2619
wsgi_publish_process_stopping(char * reason)2620 void wsgi_publish_process_stopping(char *reason)
2621 {
2622 InterpreterObject *interp = NULL;
2623 apr_hash_index_t *hi;
2624
2625 hi = apr_hash_first(NULL, wsgi_interpreters_index);
2626
2627 while (hi) {
2628 PyObject *event = NULL;
2629 PyObject *object = NULL;
2630
2631 const void *key;
2632
2633 apr_hash_this(hi, &key, NULL, NULL);
2634
2635 interp = wsgi_acquire_interpreter((char *)key);
2636
2637 event = PyDict_New();
2638
2639 #if PY_MAJOR_VERSION >= 3
2640 object = PyUnicode_DecodeLatin1(reason, strlen(reason), NULL);
2641 #else
2642 object = PyString_FromString(reason);
2643 #endif
2644 PyDict_SetItemString(event, "shutdown_reason", object);
2645 Py_DECREF(object);
2646
2647 wsgi_publish_event("process_stopping", event);
2648
2649 Py_DECREF(event);
2650
2651 wsgi_release_interpreter(interp);
2652
2653 hi = apr_hash_next(hi);
2654 }
2655 }
2656
2657 /* ------------------------------------------------------------------------- */
2658
2659 /* vi: set sw=4 expandtab : */
2660