How to force http.client to send chunked-encoding HTTP body in python?

Celebi picture Celebi · Feb 11, 2012 · Viewed 7.6k times · Source

I want to send chunked HTTP body to test my own HTTP server. So I wrote this python code:

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)

I expect the HTTP request's body is transferrd chunked, but I capture the network package with Wireshark, the HTTP request's body is not transferred chunked.

How to transfer chunked body by http.client lib in python?

Answer

Celebi picture Celebi · Feb 11, 2012

OK, I get it.

First, write my own chunked encode function.

Then use putrequest(), putheader(), endheaders() and send() instead of 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()