I'm trying to set up Apache, Django and mod_xsendfile to allow me to control access to certain files using Django authentication while still using Apache to send the actual file data.
I have a problem with this configuration:
# Some files must be publicly available without the Django auth check.
# When I comment this out, public media is not accessible but the WSGI script for
# /media/attachment DOES get called.
# So I think I need to somehow exclude /media/attachment from the effect of this Alias
Alias /media/ /var/www/vhosts/domain.com/subdomains/project/httpdocs/media/
# This <Location> block disables everything (Forbidden) regardless of the WSGI stuff
#
#<Location /media/attachments>
# Deny from all
#</Location>
WSGIScriptAlias / /var/www/vhosts/cdomain.com/subdomains/project/httpdocs/web/apache/django.wsgi
WSGIScriptAlias /media/attachments /var/www/vhosts/domain.com/subdomains/project/httpdocs/web/apache/django.wsgi
XSendFile On
How can I tell Apache to route requests to /media/attachments through the WSGI scripts and serve the rest of /media directly?
The Alias directive takes precedence over WSGIScriptAlias, so you cannot mount WSGI application under a URL specified by Alias directive.
As is, you would also have had an issue here with multiple instances of Django being started up in each process, due to multiple WSGIScriptAlias directives, unless you have used WSGIApplicationGroup directive to force them to be delegated to the same Python sub interpreter within the processes.
As to a solution, it is a bit tricky to do what you want because of the layout you are using. I have an idea, but would need to test it out first.
UPDATE 1
First possibility is that if you have everything in traditional sub directories of 'css', 'img' and 'js' as used by Django, instead of the Alias directive above, use:
and delete:
This should mean that only the static files in those subdirectories will match the Alias directive and be served directly.
UPDATE 2
The other option, which I had to test, is to not use WSGIScriptAlias, but use Alias directive for everything. This would be done like:
Because Alias directive alone is used, all evaluated at same precedence level. You just need to ensure that more deeply nested URLs come first.
Instead of WSGIScriptAlias, we use AddHandler to map .wsgi file as a WSGI script file, and set ExecCGI option so mod_wsgi will allow it to be used as WSGI script file.
We set WSGIApplicationGroup just to make sure only one Django instance is created in each process. The value of %{GLOBAL} makes it use main Python interpreter.
So, two options depending on your fancy.