gunicorn через mod_proxy перенаправляет за пределы проекта, несмотря на ProxyPassReverse - PullRequest
7 голосов
/ 21 июня 2011

У меня есть WSGI-приложение (проект Django), работающее под gunicorn на 127.0.0.1:18731, и я использую Apache с mod_proxy для перенаправления запросов с http://example.com/my-project/* на http://127.0.0.1:18731/*.Статические файлы хранятся за пределами /my-project/.Если приложению Django не нужно ничего перенаправлять, это работает просто отлично, но если оно пытается перенаправить запрос (например, добавить косую черту в http://example.com/my-project/foo), оно заканчивает тем, что удаляет /my-project/ из URL, оставляя меняс недействительным URL-адресом http://example.com/foo/.

Моя конфигурация mod_proxy выглядит следующим образом:

<Proxy *>
    Order deny,allow
    Allow from all
</Proxy>
ProxyRequests On
ProxyPass /my-project/ http://127.0.0.1:18731/ retry=0
ProxyPassReverse /my-project/ http://127.0.0.1:18731/ retry=0
ProxyPreserveHost On
ProxyErrorOverride Off

Я не хочу заставлять Django добавлять префикс /my-project/ ко всем своим URL-адресам вИнтерес переносимости.Apache, очевидно, должен обрабатывать префикс самостоятельно с помощью строки ProxyPassReverse.Что я делаю не так?

Ответы [ 3 ]

6 голосов
/ 20 октября 2011

У меня была эта проблема.

ProxyPreserveHost On

<Location "/my-project/">
    ProxyPass http://127.0.0.1:18173/my-project/
    ProxyPassReverse http://127.0.0.1:18173/my-project/
    RequestHeader set SCRIPT_NAME /my-project
    RequestHeader set X-FORWARDED-PROTOCOL ssl
    RequestHeader set X-FORWARDED-SSL on
</Location>

Чтобы приложение WSGI могло создать абсолютный URL, нам нужно:

  • ProxyPreserveHost On, поэтому заголовок Host: пропускается, и приложение знает имя хоста, на котором видит нас клиент.
  • Добавьте заголовок SCRIPT_NAME, чтобы приложение знало, где находится его корень.
  • Установите X-FORWARDED- заголовки по мере необходимости. Я тоже использую ssl, поэтому я должен сообщить приложению, что оно должно использовать схему https.

Я использую директивы <Location>, потому что я делаю гораздо больше вещей с этим vhost. Но вы можете легко переписать это, передав path аргументы директивам ProxyPass и ProxyPassReverse.

Примечание: ProxyRequests должно быть Выключено , если только вы не хотите использовать прямой прокси. Если вы читаете это, вам, вероятно, нужен только обратный прокси.

Специальное примечание для Django: settings.LOGIN_URL используется как , поэтому вам нужно добавить к нему SCRIPT_NAME.

2 голосов
/ 21 июня 2011

Вы пробовали это?Я добавил my-project в URL, который вы тоже используете.

<Proxy *>
    Order deny,allow
    Allow from all
</Proxy>
ProxyRequests On
ProxyPass /my-project/ http://127.0.0.1:18731/my-project/ retry=0
ProxyPassReverse /my-project/ http://127.0.0.1:18731/my-project/ retry=0
ProxyPreserveHost On
ProxyErrorOverride Off

Обычно я использую nginx для такого рода вещей, поэтому я не уверен, сработает ли это или нет.

Обновление : вышеописанное не сработало, поэтому попробуйте что-то другое.

Попробуйте что-то подобное и посмотрите, поможет ли это.Это настроение немного отличается.Он проксирует все, кроме медиа, которое подается через псевдоним.Это избавит от необходимости иметь / my-project / вообще.

<VirtualHost *:80>
ServerName example.com
UseCanonicalName On
ServerAdmin webmaster@localhost

LogLevel warn
CustomLog /var/log/apache2/example.com/access.log combined
ErrorLog /var/log/apache2/example.com/error.log
ServerSignature On

Alias /media/ /home/example/example.com/pysrc/project/media/

ProxyPass /media/ !
ProxyPass / http://127.0.0.1:18731/
ProxyPassReverse / http://127.0.0.1:18731/
ProxyPreserveHost On
ProxyErrorOverride Off
</VirtualHost>
0 голосов
/ 21 марта 2013

Я решил исходную проблему, установив для конфигурации ProxyPassReverse фактическое имя домена:

ProxyPass /my-project/ http://127.0.0.1:18731/
ProxyPassReverse /my-project/ http://mydomain.com/

Подсказка: Значения Apache ProxyPassReverse

...