mod_wsgi、.htaccess 和 rewriterule

mod_wsgi、.htaccess 和 rewriterule

我正在使用通过 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 处理程序,但请求路径现在是原始路径。总结一下:

  1. 这里应使用的正确 RewriteCond 是什么?
  2. 如何将请求传输到 mod_wsgi 处理程序?这是正确的方法吗?
  3. 如果这不是解决办法,那么当静态文件存在时,如何从目录中提供静态文件,当它们不存在时,如何从 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 处理其余部分。

相关内容