处理HTTP分块编码和Django(Handling HTTP chunked encoding w

2019-07-31 03:18发布

我有一个问题HANDELING HTTP分块传输编码。

我正在使用:

  • 阿帕奇。
  • mod_wsgi的插件。
  • Django的。

django的,只能够处理与内容长度报头字段reqular http请求,但是当涉及到处理TE(传输编码),分块或gzip的,它返回一个空的结果。

我想的方法2:

  1. 做一些修改django.wsgi Python文件
  2. 添加一些中间件Python文件在模块中使用,拦截任何分块http请求,将其转换为与内容长度报头字段requelar http请求,然后,把它传递给DJANGO,它可以很好地处理它。

任何人都可以与任何上述2个选项帮助(更多的选择当然是最欢迎)

谢谢!


这是一个推广到格雷厄姆的第一个前面回答后,我的问题:

首先,感谢您的快速反应。 正在使用的客户端是轴,这是另一家公司的系统与我们沟通的一部分。 我有WSGIChunkedRequest On一套,我也做了一些修改,我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的error.log中文件中提取)这些错误:

[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

我究竟做错了什么?!

Answer 1:

这是不是一个Django的问题。 它是WSGI规范本身在多达WSGI规范通过要求对请求的CONTENT_LENGTH值禁止使用的分块请求内容的限制。

当使用mod_wsgi的存在对于实现分块请求内容不标准支持一个开关,但是这意味着你的应用程序不兼容WSGI,再加上它需要一个定制的Web应用程序或WSGI包装,因为它仍然不会使用Django工作。

在mod_wsgi的选项,允许分块的请求内容是:

WSGIChunkedRequest On

你的WSGI包装应该调用wsgi.input.read()来获取全部内容,创建与它StringIO的实例,并用它来代替wsgi.input然后还添加了新的CONTENT_LENGTH值调用应用程序包之前,实际长度ENVIRON。

请注意,这是危险的,因为你不会知道被多少数据发送。

什么是您使用的客户端反正只支持分块请求的内容?


更新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的内容长度的变化未压缩的,你需要重新计算。



Answer 2:

现在一切正常顺利,问题是在守护进程模式,因为它不与分块的HTTP流量工作,可能是在mod_wsgi的4 - 按照格雷厄姆邓普尔顿。 所以,如果你有这个问题开关的mod_wsgi嵌入模式。

作为修改的格雷厄姆在WSGI包装代码,有2个选项,你可以阅读环境变量缓冲的流:

第一:

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

第二个:

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

第一码存根,能够读取守护进程模式的缓冲区,但停止的地方,并且程序没有继续运行(这弄得我一点,我希望看到它很好地工作),而其他的代码存根,坠毁有一个IOError,只有在嵌入模式工作。

还有一点要补充,升级从3.3到3.4没有解决的问题,所以你必须要等维护嵌入模式。

这些都是我的结果和意见。 如果您有任何意见,添加或更正,请不要犹豫。

谢谢!



文章来源: Handling HTTP chunked encoding with django