簡體   English   中英

如何使用 python 的 http.client 准確讀取一個響應塊?

[英]How can I read exactly one response chunk with python's http.client?

在 Python 3.3+(或任何其他內置的 Python HTTP 客戶端庫)中使用http.client ,我如何才能一次讀取一個分塊的 HTTP 響應,而該響應恰好是一個 HTTP 塊?

我正在為使用 HTTP 的分塊傳輸編碼寫入其響應的服務器擴展現有的測試夾具(使用http.client用 python 編寫)。 為了簡單起見,假設我希望能夠在客戶端接收到 HTTP 塊時打印一條消息。

我的代碼遵循一個相當標准的模式來讀取大量響應:

conn = http.client.HTTPConnection(...)
conn.request(...)
response = conn.getresponse()

resbody = []

while True:
    chunk = response.read(1024)
    if len(chunk):
        resbody.append(chunk)
    else:
        break

conn.close();

但是無論服務器是發送 10 字節塊還是 10MiB 塊,這都會讀取 1024 字節塊。

我正在尋找的是以下內容:

while True:
    chunk = response.readchunk()
    if len(chunk):
        resbody.append(chunk)
    else
        break

如果http.client無法做到這一點,是否可以使用另一個內置的 http 客戶端庫? 如果無法使用內置客戶端庫,是否可以使用pip可安裝模塊?

我發現像這樣使用請求庫更容易

r = requests.post(url, data=foo, headers=bar, stream=True)

for chunk in (r.raw.read_chunked()):
    print(chunk)

更新:

分塊傳輸編碼的好處是允許傳輸動態生成的內容。 HTTP 庫是否允許您讀取單個塊是一個單獨的問題(請參閱RFC 2616 - 第 3.6.1 節)。

我可以看到您嘗試做的事情會有用,但是標准的 python http 客戶端庫在沒有一些駭客的情況下不會做您想做的事情(請參閱http.clienthttplib )。

您嘗試做的事情可能適用於您的測試夾具,但在野外並不能保證。 客戶端讀取的數據的分塊可能與服務器發送的數據的分塊不同。 例如,數據可能在到達之前已經被代理服務器“重新分塊”(參見RFC 2616 - 第 3.2 節 - 成幀技術)。


訣竅是告訴響應對象它沒有被分塊( resp.chunked = False ),以便它返回原始字節。 這允許您在每個塊返回時解析它的大小和數據。

import http.client

conn = http.client.HTTPConnection("localhost")
conn.request('GET', "/")
resp = conn.getresponse()
resp.chunked = False

def get_chunk_size():
    size_str = resp.read(2)
    while size_str[-2:] != b"\r\n":
        size_str += resp.read(1)
    return int(size_str[:-2], 16)

def get_chunk_data(chunk_size):
    data = resp.read(chunk_size)
    resp.read(2)
    return data

respbody = ""
while True:
    chunk_size = get_chunk_size()
    if (chunk_size == 0):
        break
    else:
        chunk_data = get_chunk_data(chunk_size)
        print("Chunk Received: " + chunk_data.decode())
        respbody += chunk_data.decode()

conn.close()
print(respbody)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM