Обработка http-фрагментированной кодировки с помощью django
у меня проблема с обработкой http-кодировки передачи.
Я использую:
- apache.
- модуль mod_wsgi.
- Джанго.
django, способен обрабатывать только reqular http-запрос с полем заголовка content-length, но когда дело доходит до обработки TE (Transfer-Encoding), chunked или gzip, он возвращает пустой результат.
Я думаю о 2 подходах:
- делая некоторые модификация django.тут WSGI файл в Python
- добавить некоторые промежуточного файла 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 ...'