我正在使用通过 mod_wsgi 在同一个 apache 实例上运行的几个 django 项目,为每个站点配置了虚拟主机,请参阅 httpd.conf这里。对于其中一个网站,我想使用静态缓存(静态发生器),因此我设置了一个带有 .htaccess 文件的目录,其中包含:
RequestHeader unset X-Forwarded-Host
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}/index.html !-f
RewriteRule ^(.*) http://127.0.0.1:3456/$1 [P]
其中 3456 是服务器上的 django 端口。使用此重写规则,即使文件或目录存在,请求也始终会转发到 mod_wsgi 处理程序,如果文件index.html
存在,则请求显示为request-path/index.html
。我尝试了另一种设置:
RequestHeader unset X-Forwarded-Host
RewriteEngine on
RewriteBase /
RewriteCond $1 !-d
RewriteCond $1index.html !-f
RewriteRule ^(.*) http://127.0.0.1:3456/$1 [P]
但结果几乎相同。所有请求都转移到 mod_wsgi 处理程序,但请求路径现在是原始路径。总结一下:
- 这里应使用的正确 RewriteCond 是什么?
- 如何将请求传输到 mod_wsgi 处理程序?这是正确的方法吗?
- 如果这不是解决办法,那么当静态文件存在时,如何从目录中提供静态文件,当它们不存在时,如何从 apache/mode_wsgi 提供静态文件?
感谢您的帮助。
答案1
无需实际测试,使用类似以下方法:
<Virtualhost *:28512>
ServerName site1.com
ServerAlias www.site1.com
DocumentRoot /home/mehome/webapps/djangoprojects/site1
<Directory /home/mehome/webapps/djangoprojects/site1>
Order allow,deny
Allow from all
AddHandler wsgi-script .wsgi
Options ExecCGI
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /site.wsgi/$1 [QSA,PT,L]
</Directory>
</VirtualHost>
将您的 Django WSGI 脚本文件放入:
/home/mehome/webapps/djangoprojects/site1/site.wsgi
它应该包含 mod_wsgi wiki 中记录的修复,因此它的内容如下:
import django.core.handlers.wsgi
_application = django.core.handlers.wsgi.WSGIHandler()
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)
然后让静态文件生成器根据必须匹配的 URL 将文件转储到适当的位置:
/home/mehome/webapps/djangoprojects/site1
应该发生的是,重写规则将检查 Apache 是否找到 URL 的静态文件,如果没有,则将其重定向到 Django 应用程序中。
这种复杂的设置最好在官方 mod_wsgi 邮件列表中询问。此示例过去已多次提出,并且已在邮件列表存档中,其基础也在文档中进行了解释。
答案2
我想避免该Directory
指令,而且我WSGIScriptAlias
更喜欢AddHandler wsgi-script .wsgi
:
<VirtualHost *:80>
...
DocumentRoot /home/username/www/domain.tld/htdocs
...
# %{DOCUMENT_ROOT} is needed because outside of directories,
# REQUEST_FILENAME is the same as REQUEST_URI,
# i.e '/foo', not '/physical/path/to/foo'
#
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
RewriteRule ^/(.*)$ /site.wsgi/$1 [QSA,L,PT]
WSGIScriptAlias /site.wsgi /home/username/www/domain.tld/deploy/site.wsgi
</VirtualHost>
这会将请求传递给静态文件,并让 WSGI 处理其余部分。