Обработка http-фрагментированной кодировки с помощью django

у меня проблема с обработкой http-кодировки передачи.

Я использую:

  • apache.
  • модуль mod_wsgi.
  • Джанго.

django, способен обрабатывать только reqular http-запрос с полем заголовка content-length, но когда дело доходит до обработки TE (Transfer-Encoding), chunked или gzip, он возвращает пустой результат.

Я думаю о 2 подходах:

  1. делая некоторые модификация django.тут WSGI файл в Python
  2. добавить некоторые промежуточного файла Python для Django, чтобы перехватить любой запрос HTTP частями,преобразовать его в requelar HTTP-запрос с контент-длина заголовка, а затем, передать его в Джанго, где он может справиться с этим хорошо.

любой может помочь с любым из вышеперечисленных 2 вариантов (больше вариантов приветствуются, конечно)

спасибо!


это расширение моего вопроса после первого Грэхема Анвер:

прежде всего, спасибо за Ваш быстрый ответ. Используемый клиент-Axis,который является частью системы связи другой компании с нашей. У меня было WSGIChunkedRequest On set, я также внес некоторые изменения в мою оболочку wsgi следующим образом:

def application(environ, start_response):

    if environ.get("mod_wsgi.input_chunked") == "1":
        stream = environ["wsgi.input"]
        print stream
        print 'type: ', type(stream)
        length = 0
        for byte in stream:
            length+=1
        #print length    
        environ["CONTENT_LENGTH"] = len(stream.read(length))

    django_application = get_wsgi_application()
    return django_application(environ, start_response)

но это дает мне те ошибки (извлеченные из ошибки apache.log file):

[Sat Aug 25 17:26:07 2012] [error] <mod_wsgi.Input object at 0xb6c35390>
[Sat Aug 25 17:26:07 2012] [error] type:  <type 'mod_wsgi.Input'>
[Sat Aug 25 17:26:08 2012] [error] [client xxxxxxxxxxxxx] mod_wsgi (pid=27210): Exception occurred processing WSGI script '/..../wsgi.py'.
[Sat Aug 25 17:26:08 2012] [error] [client xxxxxxxxxxxxx] Traceback (most recent call last):
[Sat Aug 25 17:26:08 2012] [error] [client xxxxxxxxxxxxx]   File "/..../wsgi.py", line 57, in application
[Sat Aug 25 17:26:08 2012] [error] [client xxxxxxxxxxxxx]     for byte in stream:
[Sat Aug 25 17:26:08 2012] [error] [client xxxxxxxxxxxxx] IOError: request data read error

что я делаю неправильно?!

2 ответов


это не проблема Django. Это ограничение самой спецификации WSGI настолько, насколько спецификация WSGI запрещает использование содержимого фрагментированного запроса, требуя значения CONTENT_LENGTH для запроса.

при использовании mod_wsgi есть переключатель для включения нестандартной поддержки содержимого фрагментированного запроса, но это означает, что ваше приложение не совместимо с WSGI, плюс для этого потребуется пользовательское веб-приложение или оболочка WSGI, поскольку оно все еще не будет работать с Джанго.

опция в mod_wsgi, чтобы разрешить содержимое запроса chunked:

WSGIChunkedRequest On

ваш фантик тут WSGI следует называть тут WSGI.вход.read () чтобы получить весь контент, создал экземпляр StringIO с ним и использовал его для замены wsgi.введите, а затем добавьте новое значение CONTENT_LENGTH в environ с фактической длиной перед вызовом обернутого приложения.

заметьте, это опасно, потому что вы не будете знать, сколько данных передается.

какой клиент вы использование в любом случае, что поддерживает только содержимое запроса chunked?


обновление 1

ваш код нарушен по многим причинам. Вы должны использовать что-то вроде:

import StringIO

django_application = get_wsgi_application()

def application(environ, start_response):

    if environ.get("mod_wsgi.input_chunked") == "1":
        stream = environ["wsgi.input"]
        data = stream.read()   
        environ["CONTENT_LENGTH"] = str(len(data))
        environ["wsgi.input"] = StringIO.StringIO(data)

    return django_application(environ, start_response)

обратите внимание, что это не поможет с помощью gzip бы содержимого запроса. Вам понадобится дополнительная проверка, чтобы увидеть, когда кодировка содержимого была сжата, а затем сделать то же самое, что и выше. Это связано с тем, что когда данные не сжимаются Apache, длина содержимого изменяется, и вы нужно пересчитать.


теперь все работает гладко, проблема была в режиме демона, так как он не работает с фрагментированным http-трафиком, может быть в mod_wsgi 4 -- согласно Graham Dumpleton. Итак, если у вас есть эта проблема, переключите mod_wsgi в встроенный режим.

в качестве модификации кода Грэма в оболочке wsgi есть 2 варианта, где вы можете прочитать поток, буферизованный в переменной среды:

первый:

try:
    while True:
        data+= stream.next()
except:
    print 'Done with reading the stream ...'