Назад | Перейти на главную страницу

mod_wsgi, .htaccess и rewriterule

Я использую несколько проектов django, работающих на одном экземпляре apache через mod_wsgi, настроенных с помощью virtualhost для каждого сайта, см. Httpd.conf Вот. Для одного из сайтов я хочу использовать static-cache (статический генератор), поэтому я создал каталог с файлом .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?

Спасибо за вашу помощь.

Без тестирования используйте что-то вроде:

<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, поэтому в нем написано что-то вроде:

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. Этот пример был представлен несколько раз в прошлом и находится в архивах списков рассылки, а также является основанием для его объяснения в документации.

Я хотел избежать 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.