Как заставить http.client отправлять HTTP-тело chunked-кодировки в python? - PullRequest
3 голосов
/ 11 февраля 2012

Я хочу отправить фрагментированное тело 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-запроса не передается по частям.

Как передать chunked body с помощью http.client lib в python?

Ответы [ 2 ]

7 голосов
/ 11 февраля 2012

ОК, я понял.

Во-первых, напишите мою собственную функцию кодирования по частям.

Затем используйте 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()
1 голос
/ 31 октября 2014

Я бы предположил, что если вы уже знаете размер ваших данных, как в ответе , вы можете просто установить 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()
...