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

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

В общем все нормально. Но для определенных запросов (детерминированных) от запроса к ответу наблюдается почти минутное отставание. Расследование показывает, что обработка в django выполняется немедленно, но ответ сервера останавливается. Если запрос не GZIPed, все работает хорошо.

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

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

13.10.2009 10:36:34
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)
5
3.11.2013 07:50:53
Что касается сбоя, мы фактически обсуждали это ранее здесь: code.djangoproject.com/ticket/10819#comment:1 Я принял ваш комментарий к значению, что я должен просто установить длину содержимого равной размеру несжатого сообщения. До сих пор это работало нормально ... В любом случае, я спросил в списке mod_wsgi. Спасибо за вашу помощь.
UsAaR33 14.10.2009 01:16:40
Обсуждение списка mod_wsgi по этому поводу можно найти по адресу groups.google.com/group/modwsgi/browse_frm/thread/… .
Graham Dumpleton 14.10.2009 04:46:16