Skip to content

Commit f72a3e7

Browse files
Merge branch 'release/4.5.16'
2 parents 3bdb340 + 8feb427 commit f72a3e7

File tree

9 files changed

+145
-31
lines changed

9 files changed

+145
-31
lines changed

docs/release-notes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Release Notes
55
.. toctree::
66
:maxdepth: 2
77

8+
release-notes/version-4.5.16
89
release-notes/version-4.5.15
910
release-notes/version-4.5.14
1011
release-notes/version-4.5.13
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
==============
2+
Version 4.5.16
3+
==============
4+
5+
Version 4.5.16 of mod_wsgi can be obtained from:
6+
7+
https://codeload.github.com/GrahamDumpleton/mod_wsgi/tar.gz/4.5.16
8+
9+
Bugs Fixed
10+
----------
11+
12+
* The ``WSGIDontWriteBytecode`` option wasn't available when using Python 3.3
13+
and later. This feature of Python wasn't in initial Python 3 versions, but
14+
when was later added, mod_wsgi was updated to allow it.
15+
16+
* The feature behind the ``startup-timeout`` option of ``WSGIDaemonProcess``
17+
was broken by prior fix related to feature in 4.5.10. This meant the option
18+
was not resulting in daemon processes being restarted when the WSGI script
19+
file could not be loaded successfully by the specified timeout.
20+
21+
* When using ``WSGIImportScript``, or ``WSGIScriptAlias`` with both the
22+
``process-group`` and ``application-group`` options, with the intent of
23+
preloading a WSGI script file, the ability to reach across to a daemon
24+
process defined in a different virtual host with same ``ServerName`` was
25+
always failing and the target daemon process group would be flagged as
26+
not accessible when instead it should have been.
27+
28+
New Features
29+
------------
30+
31+
* Added ``--allow-override`` option to ``mod_wsgi-express`` to allow use of
32+
a ``.htaccess`` in document root directory and any directories mapped
33+
using a URL alias. The argument to the directive should be the directive
34+
type which can be overridden in the ``.htaccess`` file. The option can be
35+
used more than once if needing to allow overriding of more than one
36+
directive type. Argument can be anything allowed by ``AllowOverride``
37+
directive.

docs/user-guides/application-issues.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,9 @@ check out:
169169
* http://www.globalherald.net/jb01/weblog/21.html
170170
* http://blog.endpoint.com/2010/02/selinux-httpd-modwsgi-26-rhel-centos-5.html
171171

172-
Overall, if you don't have a specific need for SELinux, it is suggested
173-
you consider disabling it if it gives you problems.
172+
If you suspect that an issue may be caused by SELinux, you could
173+
temporarily try disabling it and doing a restart to verify whether it is
174+
the cause, but always re-enable it and do not disable it completely.
174175

175176
Application Working Directory
176177
-----------------------------

docs/user-guides/checking-your-installation.rst

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -483,15 +483,15 @@ use a test WSGI script to output the value of 'sys.prefix'::
483483
def application(environ, start_response):
484484
status = '200 OK'
485485

486-
output = ''
487-
output += 'sys.version = %s\n' % repr(sys.version)
488-
output += 'sys.prefix = %s\n' % repr(sys.prefix)
486+
output = u''
487+
output += u'sys.version = %s\n' % repr(sys.version)
488+
output += u'sys.prefix = %s\n' % repr(sys.prefix)
489489

490490
response_headers = [('Content-type', 'text/plain'),
491491
('Content-Length', str(len(output)))]
492492
start_response(status, response_headers)
493493

494-
return [output]
494+
return [output.encode('UTF-8')]
495495

496496
For standard Python installation on a Linux system, this would produce
497497
something like::
@@ -511,13 +511,13 @@ value of 'sys.path'::
511511

512512
def application(environ, start_response):
513513
status = '200 OK'
514-
output = 'sys.path = %s' % repr(sys.path)
514+
output = u'sys.path = %s' % repr(sys.path)
515515

516516
response_headers = [('Content-type', 'text/plain'),
517517
('Content-Length', str(len(output)))]
518518
start_response(status, response_headers)
519519

520-
return [output]
520+
return [output.encode('UTF-8')]
521521

522522
In both cases, even if incorrect location is being used for Python
523523
installation and even if there is no actual Python installation of the
@@ -557,12 +557,12 @@ WSGI script with the test WSGI script as follows::
557557

558558
def application(environ, start_response):
559559
status = '200 OK'
560-
output = 'mod_wsgi.process_group = %s' % repr(environ['mod_wsgi.process_group'])
560+
output = u'mod_wsgi.process_group = %s' % repr(environ['mod_wsgi.process_group'])
561561
response_headers = [('Content-type', 'text/plain'),
562562
('Content-Length', str(len(output)))]
563563
start_response(status, response_headers)
564564

565-
return [output]
565+
return [output.encode('UTF-8')]
566566

567567
If the configuration is such that the WSGI application is running in embedded
568568
mode, then you will see::
@@ -595,13 +595,13 @@ the WSGI application is being run use the test WSGI script of::
595595

596596
def application(environ, start_response):
597597
status = '200 OK'
598-
output = 'mod_wsgi.application_group = %s' % repr(environ['mod_wsgi.application_group'])
598+
output = u'mod_wsgi.application_group = %s' % repr(environ['mod_wsgi.application_group'])
599599

600600
response_headers = [('Content-type', 'text/plain'),
601601
('Content-Length', str(len(output)))]
602602
start_response(status, response_headers)
603603

604-
return [output]
604+
return [output.encode('UTF-8')]
605605

606606
If being run in the main interpreter, ie., the first interpreter created by
607607
Python, this will output::
@@ -652,13 +652,13 @@ multithread configuration is as follows::
652652

653653
def application(environ, start_response):
654654
status = '200 OK'
655-
output = 'wsgi.multithread = %s' % repr(environ['wsgi.multithread'])
655+
output = u'wsgi.multithread = %s' % repr(environ['wsgi.multithread'])
656656

657657
response_headers = [('Content-type', 'text/plain'),
658658
('Content-Length', str(len(output)))]
659659
start_response(status, response_headers)
660660

661-
return [output]
661+
return [output.encode('UTF-8')]
662662

663663
If multithreaded, this will yield::
664664

docs/user-guides/reloading-source-code.rst

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,16 @@ then substitute your WSGI application entry point with::
3737
status = '200 OK'
3838

3939
if not environ['mod_wsgi.process_group']:
40-
output = 'EMBEDDED MODE'
40+
output = u'EMBEDDED MODE'
4141
else:
42-
output = 'DAEMON MODE'
42+
output = u'DAEMON MODE'
4343

4444
response_headers = [('Content-Type', 'text/plain'),
4545
('Content-Length', str(len(output)))]
4646

4747
start_response(status, response_headers)
4848

49-
return [output]
49+
return [output.encode('UTF-8')]
5050

5151
If your WSGI application is running in embedded mode, this will output to
5252
the browser 'EMBEDDED MODE'. If your WSGI application is running in daemon
@@ -264,27 +264,33 @@ a restart if they have.
264264
Example code for such an automatic restart mechanism which is compatible
265265
with how mod_wsgi works is shown below::
266266

267+
from __future__ import print_function
268+
267269
import os
268270
import sys
269271
import time
270272
import signal
271273
import threading
272274
import atexit
273-
import Queue
275+
276+
try:
277+
import Queue as queue
278+
except ImportError:
279+
import queue
274280

275281
_interval = 1.0
276282
_times = {}
277283
_files = []
278284

279285
_running = False
280-
_queue = Queue.Queue()
286+
_queue = queue.Queue()
281287
_lock = threading.Lock()
282288

283289
def _restart(path):
284290
_queue.put(True)
285291
prefix = 'monitor (pid=%d):' % os.getpid()
286-
print >> sys.stderr, '%s Change detected to \'%s\'.' % (prefix, path)
287-
print >> sys.stderr, '%s Triggering process restart.' % prefix
292+
print('%s Change detected to \'%s\'.' % (prefix, path), file=sys.stderr)
293+
print('%s Triggering process restart.' % prefix, file=sys.stderr)
288294
os.kill(os.getpid(), signal.SIGINT)
289295

290296
def _modified(path):
@@ -373,7 +379,7 @@ with how mod_wsgi works is shown below::
373379
_lock.acquire()
374380
if not _running:
375381
prefix = 'monitor (pid=%d):' % os.getpid()
376-
print >> sys.stderr, '%s Starting change monitor.' % prefix
382+
print('%s Starting change monitor.' % prefix, file=sys.stderr)
377383
_running = True
378384
_thread.start()
379385
_lock.release()
@@ -470,8 +476,8 @@ function in the previous code with the following::
470476
def _restart(path):
471477
_queue.put(True)
472478
prefix = 'monitor (pid=%d):' % os.getpid()
473-
print >> sys.stderr, '%s Change detected to \'%s\'.' % (prefix, path)
474-
print >> sys.stderr, '%s Triggering Apache restart.' % prefix
479+
print('%s Change detected to \'%s\'.' % (prefix, path), file=sys.stderr)
480+
print('%s Triggering Apache restart.' % prefix, file=sys.stderr)
475481
import ctypes
476482
ctypes.windll.libhttpd.ap_signal_parent(1)
477483

src/server/__init__.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -690,7 +690,10 @@ def find_mimetypes():
690690
691691
DocumentRoot '%(document_root)s'
692692
693+
AccessFileName .htaccess
694+
693695
<Directory '%(server_root)s'>
696+
AllowOverride %(allow_override)s
694697
<Files handler.wsgi>
695698
<IfVersion < 2.4>
696699
Order allow,deny
@@ -703,6 +706,7 @@ def find_mimetypes():
703706
</Directory>
704707
705708
<Directory '%(document_root)s%(mount_point)s'>
709+
AllowOverride %(allow_override)s
706710
<IfDefine MOD_WSGI_DIRECTORY_INDEX>
707711
DirectoryIndex %(directory_index)s
708712
</IfDefine>
@@ -840,6 +844,7 @@ def find_mimetypes():
840844
Alias '%(mount_point)s' '%(directory)s'
841845
842846
<Directory '%(directory)s'>
847+
AllowOverride %(allow_override)s
843848
<IfVersion < 2.4>
844849
Order allow,deny
845850
Allow from all
@@ -2225,6 +2230,12 @@ def check_percentage(option, opt_str, value, parser):
22252230
'should be enabled where static file application type is '
22262231
'being used and no directory index file has been specified.'),
22272232

2233+
optparse.make_option('--allow-override', metavar='DIRECTIVE-TYPE',
2234+
action='append', help='Allow directives to be overridden from a '
2235+
'\'.htaccess\' file. Defaults to \'None\', indicating that any '
2236+
'\'.htaccess\' file will be ignored with override directives '
2237+
'not being permitted.'),
2238+
22282239
optparse.make_option('--mount-point', metavar='URL-PATH', default='/',
22292240
help='The URL path at which the WSGI application will be '
22302241
'mounted. Defaults to being mounted at the root URL of the '
@@ -2707,6 +2718,11 @@ def _cmd_setup_server(command, args, options):
27072718
except Exception:
27082719
pass
27092720

2721+
if not options['allow_override']:
2722+
options['allow_override'] = 'None'
2723+
else:
2724+
options['allow_override'] = ' '.join(options['allow_override'])
2725+
27102726
if not options['mount_point'].startswith('/'):
27112727
options['mount_point'] = os.path.normpath('/' + options['mount_point'])
27122728

src/server/mod_wsgi.c

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4054,10 +4054,15 @@ static int wsgi_execute_script(request_rec *r)
40544054
apr_thread_mutex_unlock(wsgi_module_lock);
40554055
#endif
40564056

4057-
/* Clear startup timeout and prevent from running again. */
4057+
/*
4058+
* Clear startup timeout and prevent from running again if the
4059+
* module was successfully loaded.
4060+
*/
40584061

40594062
#if defined(MOD_WSGI_WITH_DAEMONS)
4060-
wsgi_startup_shutdown_time = -1;
4063+
if (module && wsgi_startup_shutdown_time > 0) {
4064+
wsgi_startup_shutdown_time = -1;
4065+
}
40614066
#endif
40624067

40634068
/* Assume an internal server error unless everything okay. */
@@ -4616,8 +4621,28 @@ static const char *wsgi_add_script_alias(cmd_parms *cmd, void *mconfig,
46164621
if (!group)
46174622
return "WSGI process group not yet configured.";
46184623

4619-
if (group->server != cmd->server && group->server->is_virtual)
4624+
if (cmd->server->server_hostname &&
4625+
group->server->server_hostname &&
4626+
strcmp(cmd->server->server_hostname,
4627+
group->server->server_hostname) &&
4628+
group->server->is_virtual) {
4629+
46204630
return "WSGI process group not accessible.";
4631+
}
4632+
4633+
if (!cmd->server->server_hostname &&
4634+
group->server->server_hostname &&
4635+
group->server->is_virtual) {
4636+
4637+
return "WSGI process group not matchable.";
4638+
}
4639+
4640+
if (cmd->server->server_hostname &&
4641+
!group->server->server_hostname &&
4642+
group->server->is_virtual) {
4643+
4644+
return "WSGI process group not matchable.";
4645+
}
46214646
}
46224647
#endif
46234648
}
@@ -4713,7 +4738,10 @@ static const char *wsgi_set_py3k_warning_flag(cmd_parms *cmd, void *mconfig,
47134738

47144739
return NULL;
47154740
}
4741+
#endif
47164742

4743+
#if (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 3) || \
4744+
(PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 6)
47174745
static const char *wsgi_set_dont_write_bytecode(cmd_parms *cmd, void *mconfig,
47184746
const char *f)
47194747
{
@@ -5120,8 +5148,28 @@ static const char *wsgi_add_import_script(cmd_parms *cmd, void *mconfig,
51205148
if (!group)
51215149
return "WSGI process group not yet configured.";
51225150

5123-
if (group->server != cmd->server && group->server->is_virtual)
5151+
if (cmd->server->server_hostname &&
5152+
group->server->server_hostname &&
5153+
strcmp(cmd->server->server_hostname,
5154+
group->server->server_hostname) &&
5155+
group->server->is_virtual) {
5156+
51245157
return "WSGI process group not accessible.";
5158+
}
5159+
5160+
if (!cmd->server->server_hostname &&
5161+
group->server->server_hostname &&
5162+
group->server->is_virtual) {
5163+
5164+
return "WSGI process group not matchable.";
5165+
}
5166+
5167+
if (cmd->server->server_hostname &&
5168+
!group->server->server_hostname &&
5169+
group->server->is_virtual) {
5170+
5171+
return "WSGI process group not matchable.";
5172+
}
51255173
}
51265174
#else
51275175
object->process_group = "";
@@ -15752,6 +15800,10 @@ static const command_rec wsgi_commands[] =
1575215800
#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 6
1575315801
AP_INIT_TAKE1("WSGIPy3kWarningFlag", wsgi_set_py3k_warning_flag,
1575415802
NULL, RSRC_CONF, "Enable/Disable Python 3.0 warnings."),
15803+
#endif
15804+
15805+
#if (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 3) || \
15806+
(PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 6)
1575515807
AP_INIT_TAKE1("WSGIDontWriteBytecode", wsgi_set_dont_write_bytecode,
1575615808
NULL, RSRC_CONF, "Enable/Disable writing of byte code."),
1575715809
#endif

src/server/wsgi_interp.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2035,7 +2035,8 @@ void wsgi_python_init(apr_pool_t *p)
20352035

20362036
/* Disable writing of byte code files. */
20372037

2038-
#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 6
2038+
#if (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 3) || \
2039+
(PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 6)
20392040
if (wsgi_server_config->dont_write_bytecode == 1)
20402041
Py_DontWriteBytecodeFlag++;
20412042
#endif

src/server/wsgi_version.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525

2626
#define MOD_WSGI_MAJORVERSION_NUMBER 4
2727
#define MOD_WSGI_MINORVERSION_NUMBER 5
28-
#define MOD_WSGI_MICROVERSION_NUMBER 15
29-
#define MOD_WSGI_VERSION_STRING "4.5.15"
28+
#define MOD_WSGI_MICROVERSION_NUMBER 16
29+
#define MOD_WSGI_VERSION_STRING "4.5.16"
3030

3131
/* ------------------------------------------------------------------------- */
3232

0 commit comments

Comments
 (0)