Отладка ошибки неверного запроса Apache / Django / WSGI (400)

Мое простое приложение Django отлично работало в режиме отладки (manage.py runserver) и работает под WSGI + Apache на моем устройстве для разработчиков, но когда я перешел на EC2, я начал получать периодические (10-80% времени) ошибки Bad Request (400) для любых URL-адресов, которые я попробуйте просмотреть (будь то в моем приложении или в админке Django.

Где я могу найти отладочную информацию по этому поводу? Ничего не появляется в /var/log/apache2/error.log, даже с LogLevel=info. Я проверил версии, зарегистрировал среду запроса (см. Советы по отладке ModWSGI) и не вижу серьезных различия.

Единственная оставшаяся у меня мысль: я использую mod_wsgi из Ubuntu 12.04 (libapache2-mod-wsgi 3.3-4build1), который был построен против Python 2.7.1; У меня Python 2.7.3. А Django - это 1.6, что новее, чем версия Ubuntu Precise. Я не решаюсь начинать сборку пакетов из исходного кода, так как это так сложно очистить, и это похоже на незначительные изменения версии ...

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

(Для справки, вот конфигурация Apache и приложения WSGI)

Конфигурация Apache (000-по умолчанию)

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www
    WSGIScriptAlias /rz /usr/local/share/rz/rz.wsgi
    ...

Приложение rz.WSGI

import os
import sys
import django.core.handlers.wsgi
import pprint

path = '/usr/local/share/rz'
if path not in sys.path:
    sys.path.insert(0, path)

os.environ['DJANGO_SETTINGS_MODULE'] = 'rz.settings'

class LoggingMiddleware:
    def __init__(self, application):
        self.__application = application

    def __call__(self, environ, start_response):
        errors = environ['wsgi.errors']
        pprint.pprint(('REQUEST', environ), stream=errors)

        def _start_response(status, headers, *args):
            pprint.pprint(('RESPONSE', status, headers), stream=errors)
            return start_response(status, headers, *args)

        return self.__application(environ, _start_response)

application = LoggingMiddleware(django.core.handlers.wsgi.WSGIHandler())

person mrisher    schedule 02.12.2013    source источник
comment
установите DEBUG = FALSE в файле настроек django. и попробуйте перезапустить сервер Apache.   -  person Nilesh    schedule 02.12.2013
comment
Почему DEBUG = FALSE делает его более надежным? Я попытался перезапустить и не вижу никаких улучшений.   -  person mrisher    schedule 03.12.2013
comment
Правильно ли установлен ALLOW_HOSTS? Django ответит неверным запросом только в режиме prod, если он установлен неправильно. Если часть времени он работает правильно - возможно, клиенты подключаются через разные имена хостов, некоторые из этих имен хостов могут отсутствовать в ALLOW_HOSTS.   -  person Greg Lowe    schedule 11.12.2013
comment
Да, вы поняли! Спасибо, это произошло потому, что эта настройка требуется для производственного режима. Интересно, почему это было прерывисто ...   -  person mrisher    schedule 18.12.2013
comment
Я выполнил sudo apt-get update и sudo apt-get upgrade на рабочем виртуальном сервере, а затем получил 400 ПЛОХОЙ ЗАПРОС. Это привело меня к этому сообщению, и решением было добавить ALLOWED_HOSTS. Я предполагаю, что это связано с тем, что обновление было изменено на Django 1.5 или выше. Обратите внимание на Важно < / b> комментарий здесь: по умолчанию Django 1.3.6 и 1.4.4 установили ALLOWED_HOSTS, чтобы разрешить все хосты. Это означает, что для фактического устранения уязвимости системы безопасности вам следует определить этот параметр самостоятельно сразу после обновления.   -  person HostileFork says dont trust SE    schedule 24.11.2016


Ответы (3)


Добавьте параметр ALLOWED_HOSTS в свой settings.py вот так ...

ALLOWED_HOSTS = [
    '.example.com', # Allow domain and subdomains
    '.example.com.', # Also allow FQDN and subdomains
]

У меня была такая же проблема, и я нашел ответ здесь, в документации

обновление: документы django 1.6 больше не доступны, я обновил ссылку, чтобы перейти к документам django 1.7 для настройки ALLOWED_HOSTS.

person teewuane    schedule 16.12.2013
comment
Странная вещь. У меня это решение работает только для localhost. Когда я пытаюсь добавить my_site.com в ALLOWED_HOSTS (127.0.0.1 my_site.com в / etc / hosts) снова появляется неверный запрос (400). Что случилось? - person Anton; 17.08.2014
comment
@Anton На что настроен ваш DEBUG? Когда вы заходите на свой веб-сайт через my_site.com, есть ли параметр, изменяющий значение DEBUG? Может быть, это опечатка в ваших ALLOWED_HOSTS настройках? Мне нужна дополнительная информация :) Я предполагаю, что у вас есть опечатка в настройках ALLOWED_HOSTS, и она игнорируется при попытке доступа к вашему веб-сайту через '127.0.0.1', потому что для DEBUG устанавливается значение False. Когда вы пытаетесь получить доступ к сайту через my_site.com, ваша DEBUG получает значение True и использует ALLOWED_HOSTS, который имеет тип. У вас есть ".my_site.com" или "mysite.com"? - person teewuane; 18.08.2014
comment
DEBUG имеет значение False. Я создал новый чистый проект для тестирования, поэтому ничто не может изменить значение DEBUG (по крайней мере, я на это надеюсь). Вариантов ALLOWED_HOSTS: ALLOWED_HOSTS = ['localhost', 'my_site.com', 'ubuntu-virtualbox'] перепробовал много. localhost и ubuntu-virtualbox - ›работает, my_site.com -› Bad Request. Затем я попытался предоставить доступ для всех хостов: ALLOWED_HOSTS = ['*'] с тем же результатом. И даже когда я изменил DEBUG на True, были доступны только localhost и ubuntu-virtualbox. my_site.com все еще возвращает неверный запрос. Может быть, это из-за virtualenv или каких-то системных настроек? - person Anton; 19.08.2014
comment
вот мой вопрос stackoverflow.com/questions/25357744/django -and-bad-request-400. Я могу дать там больше информации. Публиковать код в комментариях слишком сложно. - person Anton; 19.08.2014
comment
Отсутствие сайта, указанного в ALLOWED_HOSTS, также было моей проблемой. Однако мне нужно было перезапустить Apache после его изменения. Без перезапуска Apache он продолжал отображать случайные неверные запросы http 400. - person Joel B; 19.08.2014
comment
Ссылка на документы не работает - person Agey; 12.09.2016
comment
@Agey О да, похоже, что документация по django 1.6 больше не доступна. Исправлю ссылку на django 1.7. - person teewuane; 12.09.2016

Если вы определенно установили ALOWED_HOSTS - убедитесь, что ваше имя хоста не содержит символов подчеркивания. Технически это незаконно.

Мне пришлось распечатать различные функции, и все свелось к тому, что это регулярное выражение не смогло обнаружить домен в django.http

host_validation_re = re.compile(r"^([a-z0-9.-]+|\[[a-f0-9]*:[a-f0-9:]+\])(:\d+)?$")

И действительно, в моем домене был знак подчеркивания.

person Yuji 'Tomita' Tomita    schedule 04.11.2014
comment
Бинго - после 45 минут охоты на это ваш ответ застрял, и, конечно же, у меня было подчеркивание в производственном домене (файл hosts), но не в домене dev. Очень сложно отладить это с помощью DEBUG = False. - person staggart; 27.10.2015

Это не решение, но для целей отладки вы можете установить параметр ALLOWED_HOSTS в своем settings.py следующим образом

ALLOWED_HOSTS = ['*']

Это обязательно должно сработать. Если нет, по крайней мере, вы будете знать, что проблема не в том, что Django запрещает доступ к заданному URL-адресу.

person user3770635    schedule 16.12.2014
comment
Этим вы отключаете безопасность, которую намереваются установить эти переменные. - person Mibou; 28.01.2015
comment
@Mibou, даже с этой настройкой, у меня плохой запрос при перенаправлении с одного сервера на другой .. - person holms; 15.04.2015
comment
Это хорошо по причинам DEBUG, чтобы определить, связана ли проблема с ALOWED_HOSTS. - person kecske; 30.06.2015