Apache отстает при ответе на gzip-запросы

Для приложения, которое я разрабатываю, пользователь отправляет сжатый HTTP-запрос POST (кодирование контента: GZIP) с составными данными формы (тип контента: multipart/form-data). Я использую mod_deflate в качестве входного фильтра для распаковки, а веб-запрос обрабатывается в Django через mod_wsgi.

Как правило, все в порядке. Но для определенных запросов (детерминированных) задержка между запросом и ответом составляет почти минуту. Расследование показывает, что обработка в django происходит сразу, но ответ от сервера зависает. Если запрос не сжат GZIP, все работает.

Обратите внимание, что для устранения сбоя в mod_wsgi я установил длину содержимого равным размеру несжатого сообщения.

Кто-нибудь сталкивался с этой проблемой? Есть ли способ легко отлаживать apache при обработке ответов?


person UsAaR33    schedule 13.10.2009    source источник


Ответы (1)


Как вы думаете, какой сбой существует в mod_wsgi?

Дело в том, что WSGI 1.0 не поддерживает мутирующие входные фильтры, которые изменяют длину содержимого запроса. Таким образом, технически вы не можете использовать mod_deflate в Apache для запроса содержимого при использовании WSGI 1.0. Если вы установите для длины содержимого значение, отличное от фактического размера, скорее всего, это затормозит работу mod_deflate.

Если вы хотите иметь возможность обрабатывать сжатый контент запроса, вам нужно выйти за пределы спецификации WSGI 1.0 и использовать нестандартный код.

Предлагаю прочитать:

http://blog.dscpl.com.au/2009/10/details-on-wsgi-10-amendmentsclarificat.html

Это объясняет эту проблему и предложения по этому поводу.

Я настоятельно рекомендую вам обратиться с этой проблемой в официальный список рассылки mod_wsgi для обсуждения как вам нужно написать свой код. Однако, если вы используете одну из платформ Python, вы, вероятно, будете ограничены в том, что вы можете делать, поскольку они будут реализовывать WSGI 1.0, где вы не можете этого сделать.


ОБНОВЛЕНИЕ 1

Из обсуждения списка mod_wsgi исходное приложение WSGI должно быть заключено в следующее промежуточное ПО WSGI. Это будет работать только с адаптерами WSGI, которые фактически предоставляют пустую строку в качестве конечного индикатора для ввода, чего не требует WSGI 1.0. Возможно, это следует использовать только для небольших загрузок, поскольку все считывается в память. Если нужны большие сжатые загрузки, то накопленные данные следует вместо этого записывать в файл.

class Wrapper(object):

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

    def __call__(self, environ, start_response):
        if environ.get('HTTP_CONTENT_ENCODING', '') == 'gzip':
            buffer = cStringIO.StringIO()
            input = environ['wsgi.input']
            blksize = 8192
            length = 0

            data = input.read(blksize)
            buffer.write(data)
            length += len(data)

            while data:
                data = input.read(blksize)
                buffer.write(data)
                length += len(data)

            buffer = cStringIO.StringIO(buffer.getvalue())

            environ['wsgi.input'] = buffer
            environ['CONTENT_LENGTH'] = length

        return self.__application(environ, start_response)


application = Wrapper(original_wsgi_application_callable)
person Graham Dumpleton    schedule 13.10.2009
comment
Что касается сбоя, мы обсуждали это ранее здесь: code.djangoproject.com/ticket/ 10819#comment:1 Я понял, что ваш комментарий означает, что я должен просто установить длину содержимого равным размеру несжатого сообщения. До сих пор это работало нормально... В любом случае, я спросил в списке mod_wsgi. Спасибо за вашу помощь. - person UsAaR33; 14.10.2009
comment
Обсуждение этого вопроса в списке mod_wsgi находится по адресу 'groups.google.com/group/. modwsgi/browse_frm/thread/'. - person Graham Dumpleton; 14.10.2009