2014-07-01 9 views
3

Python 3.3+ (또는 다른 내장 파이썬 HTTP 클라이언트 라이브러리)에서 http.client을 사용하면 한 번에 하나의 HTTP 청크로 정확히 청크 HTTP 응답을 읽을 수 있습니까?어떻게 파이썬의 http.client와 정확히 하나의 응답 청크를 읽을 수 있습니까?

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(); 

을하지만 1024 개 바이트 덩어리 여부에 관계없이 서버가 10 바이트 덩어리 또는 10MiB 청크를 보내는의 읽

내 코드는 많은 응답을 읽기 위해 상당히 표준 패턴을 따른다. 이, http.client 불가능 또 다른 내장 HTTP 클라이언트 라이브러리 가능한 경우

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

:

내가 무엇을 찾고은 다음과 같은 것입니까? 기본 클라이언트 lib로는 불가능한 경우 pip 모듈을 설치할 수 있습니까?

+0

이 모든 항목은 http://docs.python-requests.org/ko/latest/user/advanced/#body-content-workflow? –

+0

나는 그것이 확실하지 않습니다. 또는, 만약 그렇다면, 나는 너무 멍청해서 응답을 –

답변

3

는 업데이트 :

청크 분할 전송 인코딩의 장점은 동적으로 생성 된 컨텐츠의 전송을 허용하는 것입니다. HTTP 라이브러리에서 개별 청크를 읽을 수 있는지 여부는 별도의 문제입니다 (RFC 2616 - Section 3.6.1 참조).

어떻게하면 좋을지 알 수 있지만 표준 파이썬 http 클라이언트 라이브러리는 어떤 해커없이 원하는 것을하지 않습니다 (http.clienthttplib 참조).

당신이하려는 것은 테스트 픽스처에서 사용하기에는 좋지만 야생에서는 보장 할 수 없습니다. 클라이언트가 읽은 데이터의 청크가 서버에서 전송 한 데이터의 청크와 다를 수 있습니다. 예 : 데이터는 도착하기 전에 프록시 서버에 의해 "다시 청크 (chunked)"되었을 수 있습니다 (RFC 2616 - Section 3.2 - Framing Techniques 참조).


트릭은 원시 바이트를 반환하도록이 (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) 
+0

Upvoted에서 한 번에 정확히 하나의 HTTP 청크를 읽을 수있는 방법을 보았습니다. 실제로 질문에 대답했기 때문입니다. 그러나 약간의 해킹이기 때문에 받아들이지 않았습니다. 청크 분할 인코딩의 이점은 청크별로 읽을 수 있어야합니다. http.client가 청크 인코딩을 지원하지만 분명히 노출되지 않는다는 사실은 조금 슬프다. –

+1

작은 버그 : 청크 크기는 16 진수로 표현되므로 int (size_str [: - 2], 16)를 읽어야합니다. HTTP/1.1 https://tools.ietf.org/html/rfc7230#section-4.1 (편집)을 참조하십시오. 그렇지 않으면 : Ben이 말한 것처럼 해커라면 충분히 잘 작동합니다. –