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