【问题标题】:How to force http.client to send chunked-encoding HTTP body in python?如何强制 http.client 在 python 中发送分块编码的 HTTP 正文?
【发布时间】:2012-03-03 12:33:29
【问题描述】:

我想发送分块的 HTTP 正文来测试我自己的 HTTP 服务器。 所以我写了这个python代码:

import http.client

body = 'Hello World!' * 80

conn = http.client.HTTPConnection("some.domain.com")
url = "/some_path?arg=true_arg"

conn.request("POST", url, body, {"Transfer-Encoding":"chunked"})

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

我希望 HTTP 请求的正文被传输分块, 但是我用 Wireshark 捕获了网络包,HTTP 请求的正文没有被分块传输。

如何在python中通过http.client lib传输分块体?

【问题讨论】:

    标签: python http chunked


    【解决方案1】:

    好的,我明白了。

    首先,编写我自己的分块编码函数。

    然后使用 putrequest()、putheader()、endheaders() 和 send() 代替 request()

    import http.client
    
    def chunk_data(data, chunk_size):
        dl = len(data)
        ret = ""
        for i in range(dl // chunk_size):
            ret += "%s\r\n" % (hex(chunk_size)[2:])
            ret += "%s\r\n\r\n" % (data[i * chunk_size : (i + 1) * chunk_size])
    
        if len(data) % chunk_size != 0:
            ret += "%s\r\n" % (hex(len(data) % chunk_size)[2:])
            ret += "%s\r\n" % (data[-(len(data) % chunk_size):])
    
        ret += "0\r\n\r\n"
        return ret
    
    
    conn = http.client.HTTPConnection(host)
    url = "/some_path"
    conn.putrequest('POST', url)
    conn.putheader('Transfer-Encoding', 'chunked')
    conn.endheaders()
    conn.send(chunk_data(body, size_per_chunk).encode('utf-8'))
    
    resp = conn.getresponse()
    print(resp.status, resp.reason)
    conn.close()
    

    【讨论】:

    • 对我来说效果更好,因为 chunk_data 的第二行中只有一个分隔符(即: ret += "%s\r\n" % (data[i * chunk_size : (i + 1) * chunk_size]))
    【解决方案2】:

    我建议,如果您已经知道 answer 中的数据大小,因为您可以设置 Content-Length 并一次性将其全部发送回来,这就是您正在做的事情无论如何,只需致电conn.send

    当您不知道数据有多大时,分块传输编码最有用,例如动态生成的内容。我已经修改了你的代码来说明:

    import httplib
    
    def write_chunk(conn, data):
        conn.send("%s\r\n" % hex(len(data))[2:])
        conn.send("%s\r\n" % data)
    
    def dynamically_generate_data():
        for i in range(80):
            yield "hello world"
    
    conn = httplib.HTTPConnection("localhost")
    url = "/some_path"
    conn.putrequest('POST', url)
    conn.putheader('Transfer-Encoding', 'chunked')
    conn.endheaders()
    
    for new_chunk in dynamically_generate_data():
        write_chunk(conn, new_chunk)
    conn.send('0\r\n')
    
    resp = conn.getresponse()
    print(resp.status, resp.reason)
    conn.close()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-05
      • 2010-11-17
      • 2012-08-20
      • 2013-07-13
      • 2013-05-08
      • 2013-04-23
      • 1970-01-01
      • 2010-09-09
      相关资源
      最近更新 更多