处理HTTP分块编码和Django [英] Handling HTTP chunked encoding with django

查看:558
本文介绍了处理HTTP分块编码和Django的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a problem handeling http chunked transfer encoding.

我使用的是:


  • 阿帕奇。

  • mod_wsgi的插件。

  • Django的。

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

django, is only capable of handling reqular http request with content-length header field, but when it comes to handling TE (Transfer-Encoding), chunked or gzip, it returns an empty result.

我在想方法2:


  1. 制作了一些修改django.wsgi Python文件

  2. 添加一些中间件蟒蛇文件的Django,拦截任何分块的HTTP请求,将其转换为requelar与内容长度的头字段的HTTP请求,然后,把它传递给Django的,它可以很好地处理它。

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

Anybody can help with any of the above 2 options (more options are most welcome of course)

谢谢!

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

This is an extention to my question after Graham's first anwer:

首先,感谢您的快速反应。所使用的客户机是轴,这是其他公司的系统与我们进行通信的一部分。我有 WSGIChunkedRequest在集,我也做了一些修改,我的WSGI的包装是这样的:

First of all, thanks for your quick response. The client being used is Axis, which is a part of another company's system communicating with ours. I had WSGIChunkedRequest On set, I also made some modifications to my wsgi wrapper like this:

高清应用(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中文件中提取):

but it gives me those errors (extracted from apache's error.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

我究竟做错了什么?!

What Am I doing wrong?!

推荐答案

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

This is a not a Django issue. It is a limitation of the WSGI specification itself in as much as the WSGI specification prohibits use of chunked request content by requiring a CONTENT_LENGTH value for request.

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

When using mod_wsgi there is a switch for enabling non standard support for chunked request content, but that means your application isn't WSGI compliant, plus it would require a custom web application or WSGI wrapper as it still isn't going to work with Django.

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

The option in mod_wsgi to allow chunked request content is:

WSGIChunkedRequest On

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

Your WSGI wrapper should call wsgi.input.read() to get whole content, created a StringIO instance with it and use that to replace wsgi.input and then also add a new CONTENT_LENGTH value to environ with actual length before calling wrapped application.

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

Do note this is dangerous because you will not know how much data is being sent.

什么客户,你无论如何使用,只有支持分块请求的内容?

What client are you using anyway that only supports chunked request content?

更新1

您code被破坏的原因很多。您应该使用类似:

Your code is broken for numerous reasons. You should be using something like:

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压缩的请求内容的帮助。您将需要额外的检查针对的时候看到的内容编码是COM pressed数据,然后做同上。这是因为当数据是Apache的内容长度的变化pssed uncom $ P $,你需要重新计算。

Note that this will not help with gzip'd request content. You would need an additional check for that to see when content encoding was compressed data and then do same as above. This is because when data is uncompressed by Apache the content length changes and you need to recalculate it.

这篇关于处理HTTP分块编码和Django的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆