【问题标题】:How to POST chunked encoded data in Python如何在 Python 中发布分块编码数据
【发布时间】:2013-07-13 18:33:34
【问题描述】:

我正在尝试将分块编码数据发布到 httpbin.org/post。我尝试了两个选项:Requests 和 httplib

使用请求

#!/usr/bin/env python

import requests

def gen():
        l = range(130)
        for i in l:
                yield '%d' % i

if __name__ == "__main__":
        url = 'http://httpbin.org/post'
        headers = {
                        'Transfer-encoding':'chunked',
                        'Cache-Control': 'no-cache',
                        'Connection': 'Keep-Alive',
                        #'User-Agent': 'ExpressionEncoder'
                }
        r = requests.post(url, headers = headers, data = gen())
        print r

使用 httplib

#!/usr/bin/env python

import httplib
import os.path

if __name__ == "__main__":
        conn = httplib.HTTPConnection('httpbin.org')
        conn.connect()
        conn.putrequest('POST', '/post')
        conn.putheader('Transfer-Encoding', 'chunked')
        conn.putheader('Connection', 'Keep-Alive')
        conn.putheader('Cache-Control', 'no-cache')
        conn.endheaders()
        for i in range(130):
                conn.send(str(i))

        r = conn.getresponse()
        print r.status, r.reason

在这两种情况下,每当我分析 Wireshark 跟踪时,我都没有看到发送多个块。相反,我看到的是所有数据都在一个块中发送?我在这里遗漏了什么吗?

【问题讨论】:

  • 你确定吗?在 Wireshark 中选择单个 HTTP 消息,您应该能够展开超文本传输​​协议部分。该扩展部分应该有另一个名为“HTTP 分块响应”的子标题,其中包含您的数据。
  • @Lukasa:是的,你是对的。出于某种原因,我对分块数据如何出现在 Wireshark 上的理解存在缺陷。我认为它总是显示为一个单独的数据包。感谢您的宝贵时间。
  • 用httplib是否也需要逐行打印块的长度?
  • 它工作正常。我期待在 pcap 上看到每组块的单独跟踪,这不会发生。

标签: python http python-requests httplib chunked-encoding


【解决方案1】:

您发布的代码不应该正常工作。您仍然收到成功响应的原因是 httpbin.org 目前不支持分块传输编码。请参阅错误https://github.com/kennethreitz/httpbin/issues/102

就像在上面链接到的帖子Piotr 中一样,您应该以十六进制写出每个块的长度,然后是块本身。

我把你的代码作为一个例子。 http://httpbin.org/post 端点有 a form that you can use for testing。这就是我生成chunk1chunk2 表单数据的地方。

import httplib
import time

chunk1 = "custname=bob&custtel=11111&custemail=bob%40email.com&si"
chunk2 = "ze=medium&topping=bacon&delivery=11%3A00&comments=if+you%27re+late+we+get+it+free"

if __name__ == "__main__":
    conn = httplib.HTTPConnection('httpbin.org')
    conn.connect()
    conn.putrequest('POST', '/post')
    conn.putheader('Transfer-Encoding', 'chunked')
    conn.putheader('Content-Type', 'application/x-www-form-urlencoded')
    conn.endheaders()

    conn.send("%s\r\n" % hex(len(chunk1))[2:])
    conn.send("%s\r\n" % chunk1)

    time.sleep(1)

    conn.send("%s\r\n" % hex(len(chunk2))[2:])
    conn.send("%s\r\n" % chunk2)

    time.sleep(1)
    /* last chunk */
    conn.send("0\r\n\r\n")

    r = conn.getresponse()
    print r.status, r.reason, r.read()

wireshark 中的流看起来类似于以下内容,这是不正确的,因为它没有等待(注意尾随的 0)或解释我们发送的请求正文(注意 json: null):

POST /post HTTP/1.1
Host: httpbin.org
Accept-Encoding: identity
Transfer-Encoding: chunked
Content-Type: application/x-www-form-urlencoded

37
custname=bob&custtel=11111&custemail=bob%40email.com&si
51
ze=medium&topping=bacon&delivery=11%3A00&comments=if+you%27re+late+we+get+it+free
HTTP/1.1 200 OK
Connection: close
Server: gunicorn/18.0
Date: Fri, 31 Oct 2014 10:37:24 GMT
Content-Type: application/json
Content-Length: 494
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Via: 1.1 vegur

{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Accept-Encoding": "identity", 
    "Connect-Time": "2", 
    "Connection": "close", 
    "Content-Type": "application/x-www-form-urlencoded", 
    "Host": "httpbin.org", 
    "Total-Route-Time": "0", 
    "Transfer-Encoding": "chunked", 
    "Via": "1.1 vegur", 
    "X-Request-Id": "5053a365-ca6a-4c29-b97a-f7a6ded7f2d9"
  }, 
  "json": null, 
  "origin": "110.174.97.16", 
  "url": "http://httpbin.org/post"
}0

【讨论】:

    猜你喜欢
    • 2020-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-03
    • 1970-01-01
    • 1970-01-01
    • 2010-11-19
    • 1970-01-01
    相关资源
    最近更新 更多