summaryrefslogtreecommitdiff
path: root/src/server/wsgi_interp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/wsgi_interp.c')
-rw-r--r--src/server/wsgi_interp.c137
1 files changed, 95 insertions, 42 deletions
diff --git a/src/server/wsgi_interp.c b/src/server/wsgi_interp.c
index 6d8e765..7d0c1a7 100644
--- a/src/server/wsgi_interp.c
+++ b/src/server/wsgi_interp.c
@@ -1935,6 +1935,8 @@ void wsgi_python_init(apr_pool_t *p)
{
const char *python_home = 0;
+ int is_pyvenv = 0;
+
/* Perform initialisation if required. */
if (!Py_IsInitialized()) {
@@ -2003,19 +2005,16 @@ void wsgi_python_init(apr_pool_t *p)
python_home = wsgi_server_config->python_home;
-#if defined(MOD_WSGI_WITH_DAEMONS)
- if (wsgi_daemon_process && wsgi_daemon_process->group->python_home)
- python_home = wsgi_daemon_process->group->python_home;
-#endif
-
-#if PY_MAJOR_VERSION >= 3
if (python_home) {
- wchar_t *s = NULL;
- int len = strlen(python_home)+1;
-
ap_log_error(APLOG_MARK, APLOG_INFO, 0, wsgi_server,
"mod_wsgi (pid=%d): Python home %s.", getpid(),
python_home);
+ }
+
+ if (python_home) {
+#if PY_MAJOR_VERSION >= 3
+ wchar_t *s = NULL;
+ int len = strlen(python_home)+1;
s = (wchar_t *)apr_palloc(p, len*sizeof(wchar_t));
@@ -2025,23 +2024,21 @@ void wsgi_python_init(apr_pool_t *p)
mbstowcs(s, python_home, len);
#endif
Py_SetPythonHome(s);
- }
#else
- if (python_home) {
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, wsgi_server,
- "mod_wsgi (pid=%d): Python home %s.", getpid(),
- python_home);
-
Py_SetPythonHome((char *)python_home);
- }
#endif
+ }
+
#else
/*
- * Check for Python HOME being overridden. What we are actually
- * going to do though is work out where the Python executable
- * would be that the designated installation and set the
- * location for where it is. This avoids bugs in pyvenv support
- * for embedded systems.
+ * Now for the UNIX version of the code to set the Python HOME.
+ * For this things are a mess. If using pyvenv with Python 3.3+
+ * then setting Python HOME doesn't work. For it we need to use
+ * Python executable location. Everything else seems to be cool
+ * with setting Python HOME. We therefore need to detect when we
+ * have a pyvenv by looking for the presence of pyvenv.cfg file.
+ * We can simply just set Python executable everywhere as that
+ * doesn't work with brew Python on MacOS X.
*/
python_home = wsgi_server_config->python_home;
@@ -2051,43 +2048,99 @@ void wsgi_python_init(apr_pool_t *p)
python_home = wsgi_daemon_process->group->python_home;
#endif
-#if PY_MAJOR_VERSION >= 3
if (python_home) {
+ apr_status_t rv;
+ apr_finfo_t finfo;
+
+ char *pyvenv_cfg;
+
const char *python_exe = 0;
+
+#if PY_MAJOR_VERSION >= 3
wchar_t *s = NULL;
int len = 0;
+#endif
- python_exe = apr_pstrcat(p, python_home, "/bin/python", NULL);
-
- len = strlen(python_exe)+1;
+ /*
+ * Is common to see people set the directory to an incorrect
+ * location, including to a location within an inaccessible
+ * user home directory, or to the 'python' executable itself.
+ * Try and validate that the location is accessible and is a
+ * directory.
+ */
ap_log_error(APLOG_MARK, APLOG_INFO, 0, wsgi_server,
"mod_wsgi (pid=%d): Python home %s.", getpid(),
python_home);
- s = (wchar_t *)apr_palloc(p, len*sizeof(wchar_t));
+ rv = apr_stat(&finfo, python_home, APR_FINFO_NORM, p);
-#if defined(WIN32) && defined(APR_HAS_UNICODE_FS)
- wsgi_utf8_to_unicode_path(s, len, python_exe);
-#else
- mbstowcs(s, python_exe, len);
-#endif
- Py_SetProgramName(s);
- }
-#else
- if (python_home) {
- const char *python_exe = 0;
+ if (rv != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_WARNING, rv, wsgi_server,
+ "mod_wsgi (pid=%d): Unable to stat Python home "
+ "%s. Python interpreter may not be able to be "
+ "initialized correctly. Verify the supplied path "
+ "and access permissions for whole of the path.",
+ getpid(), python_home);
+ }
+ else {
+ if (finfo.filetype != APR_DIR) {
+ ap_log_error(APLOG_MARK, APLOG_WARNING, rv, wsgi_server,
+ "mod_wsgi (pid=%d): Python home %s is not "
+ "a directory. Python interpreter may not "
+ "be able to be initialized correctly. "
+ "Verify the supplied path.", getpid(),
+ python_home);
+ }
+ else if (access(python_home, X_OK) == -1) {
+ ap_log_error(APLOG_MARK, APLOG_WARNING, rv, wsgi_server,
+ "mod_wsgi (pid=%d): Python home %s is not "
+ "accessible. Python interpreter may not "
+ "be able to be initialized correctly. "
+ "Verify the supplied path and access "
+ "permissions on the directory.", getpid(),
+ python_home);
+ }
+ }
- python_exe = apr_pstrcat(p, python_home, "/bin/python", NULL);
+ /* Now detect whether have a pyvenv with Python 3.3+. */
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, wsgi_server,
- "mod_wsgi (pid=%d): Python home %s.", getpid(),
- python_home);
+ pyvenv_cfg = apr_pstrcat(p, python_home, "/pyvenv.cfg", NULL);
- Py_SetProgramName((char *)python_exe);
- }
+ if (access(pyvenv_cfg, R_OK) == 0)
+ is_pyvenv = 1;
+
+ if (is_pyvenv) {
+ /*
+ * Embedded support for pyvenv is broken so need to
+ * set Python executable location and cannot set the
+ * Python HOME as is more desirable.
+ */
+
+ python_exe = apr_pstrcat(p, python_home, "/bin/python", NULL);
+#if PY_MAJOR_VERSION >= 3
+ len = strlen(python_exe)+1;
+ s = (wchar_t *)apr_palloc(p, len*sizeof(wchar_t));
+ mbstowcs(s, python_exe, len);
+
+ Py_SetProgramName(s);
+#else
+ Py_SetProgramName((char *)python_exe);
+#endif
+ }
+ else {
+#if PY_MAJOR_VERSION >= 3
+ len = strlen(python_home)+1;
+ s = (wchar_t *)apr_palloc(p, len*sizeof(wchar_t));
+ mbstowcs(s, python_home, len);
+
+ Py_SetPythonHome(s);
+#else
+ Py_SetPythonHome((char *)python_home);
#endif
+ }
#endif
+ }
/*
* Set environment variable PYTHONHASHSEED. We need to