2012-02-11 1 views
3

Я хочу отправить chunked тело HTTP для проверки моего собственного HTTP-сервера. Так что я написал этот питон код:Как заставить http.client отправить chunked-encoding HTTP body в 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 является transferrd фрагментированным, но захватить сетевой пакет с Wireshark, тело запроса на HTTP-не передается фрагментированным.

Как передать куски тела http.client lib в python?

ответ

7

ОК, я понимаю.

Прежде всего, напишите мою собственную функцию закодированного кодирования.

Затем используйте putrequest(), putheader(), endheaders() и отправить() вместо запроса()

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() 
+2

работает лучше для меня ти только один сепаратор второй линии внутри для части chunk_data (то есть: RET + = «% S \ г \ п»% (данные [ i * chunk_size: (i + 1) * chunk_size])) –

1

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