After some digging, seems that UserDir directive from mod_userdir not
overriding WSGIScriptAlias where WSGI application is mounted at root
of web site, ie., '/', is deliberate.
The reason it was done that way was to mirror what happens with the
Alias and ScriptAlias directives in Apache and for them, if they are
used for '/', they too override the UserDir directive.
Note that this isn't a problem when mounting something at a sub URL,
only at '/'.
The solution is to use the style of configuration described in:
http://code.google.com/p/modwsgi/wiki/ConfigurationGuidelines#The_Apache_Alias_Directive
So, instead of having:
UserDir public_html
WSGIScriptAlias / /usr/local/wsgi/scripts/site.wsgi
<Directory /usr/local/wsgi/scripts>
Order allow,deny
Allow from all
</Directory>
You would need to use:
DocumentRoot /usr/local/wsgi/scripts
UserDir public_html
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /site.wsgi/$1 [QSA,PT,L
Options ExecCGI Indexes
<Directory /usr/local/wsgi/scripts>
Options ExecCGI Indexes
AddHandler wsgi-script .wsgi
Order allow,deny
Allow from all
</Directory>
The WSGI script itself would need to include the fixup:
def _application(environ, start_response):
# The original application.
...
import posixpath
def application(environ, start_response):
# Wrapper to set SCRIPT_NAME to actual mount point.
environ['SCRIPT_NAME'] = posixpath.dirname(environ['SCRIPT_NAME'])
if environ['SCRIPT_NAME'] == '/':
environ['SCRIPT_NAME'] = ''
return _application(environ, start_response
What will happen with this is that UserDir would be checked first and
then the contents of DocumentRoot. If either of those do not match a
resource corresponding to a static file, be that an actual static
file, or a mapped resource such as .cgi or .wsgi script, then the
rewrite rule is applied and the request internally redirect to
site.wsgi in the DocumentRoot directory.
In effect this allows the WSGI application to overlay the file system
based resources accessible by UserDIr and DocumentRoot with the WSGI
application only handling a request where resource couldn't otherwise
be found.
With this approach, instead of needing to do something like:
Alias /robots.txt /usr/local/wsgi/static/robots.txt
Alias /favicon.ico /usr/local/wsgi/static/favicon.ico
AliasMatch /([^/]*\.css) /usr/local/wsgi/static/styles/$1
Alias /media/ /usr/local/wsgi/static/media/
you would instead stick all those static media files in your new
DocumentRoot directory and they will be found automatically without
needing to add explicitly Alias directives.
Because though anything in your new DocumentRoot can be served up as a
static file, that DocumentRoot directory SHOULD be a subdirectory
which ONLY contains the WSGI script file and the static media files.
In other words, if using Django and you stuck the WSGI script file in
your site directory along with your settings file, you SHOULD NOT,
then make the site directory your DocumentRoot as it would make all
your site source code, including settings file with passwords,
downloadable as static files.
Graham
Plus that once you do that you need FollowSymlinks with Options
directive else RewriteRule isn't allowed for some silly reason.
Graham