2012-03-18 47 views
11

Tôi đã tạo kiến ​​trúc máy khách/máy chủ trong python, tôi nhận yêu cầu HTTP từ máy khách được phục vụ bằng cách yêu cầu một máy chủ HTTP khác thông qua mã của tôi.Làm thế nào để giải mã dữ liệu nén gzip được trả về trong Phản hồi HTTP trong python?

Khi tôi nhận được phản hồi từ máy chủ thứ ba, tôi không thể giải mã dữ liệu nén gzip, trước tiên tôi chia dữ liệu phản hồi bằng cách sử dụng \r\n làm ký tự tách cho tôi dữ liệu làm mục cuối cùng trong danh sách giải nén nó bằng

zlib.decompress(data[-1]) 

nhưng nó cho tôi lỗi của tiêu đề không chính xác. Làm thế nào tôi nên đi với vấn đề này?

client_reply = '' 
       while 1: 
        chunk = server2.recv(512) 
        if len(chunk) : 
         client.send(chunk) 
         client_reply += chunk 
        else: 
         break 
       client_split = client_reply.split("\r\n") 
       print client_split[-1].decode('zlib') 

Tôi muốn đọc dữ liệu được được chuyển giao giữa máy khách và máy chủ thứ 2.

+1

Hiển thị mã cho chúng tôi! Bạn có chắc chắn dữ liệu chưa được mã hóa/giải mã không đúng cách (tức là dữ liệu đó phải được coi là dữ liệu nhị phân) không? – Cameron

+0

Có thể dữ liệu của bạn được chia thành nhiều phần và bạn cần phân tích cú pháp tiêu đề để có độ dài phù hợp. Tiêu đề gzipped có thông tin chiều dài –

+0

nếu dữ liệu nén tự nhận được "\ r \ n" trong đó, và bạn phá vỡ nó và giải mã chỉ một phần của nó thay vì tất cả dữ liệu nén? Tôi sẽ cố gắng tìm "\ r \ n" trong máy chủ trước khi bạn gửi nó để xác nhận nếu nó là vấn đề. –

Trả lời

1

Theo https://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html các tiêu đề và phần thân được phân tách bằng một dòng trống chỉ chứa các ký tự CRLF. Bạn có thể thử

client_split = client_reply.split("\r\n\r\n",1) 
print client_split[1].decode('zlib') 

Chia tách tìm thấy dòng trống và tham số bổ sung giới hạn số lần chia tách - kết quả là mảng với hai mục, tiêu đề và nội dung. Nhưng thật khó để đề xuất bất cứ điều gì mà không cần biết thêm về mã của bạn và chuỗi thực tế bị tách ra.

4

Chỉ định wbits khi sử dụng zlib.decompress(string, wbits, bufsize) xem kết thúc "khắc phục sự cố" chẳng hạn.

đáp thắc mắc

Hãy bắt đầu với aa lệnh curl rằng tải một phản ứng byte tầm với một "nội dung mã hóa" không rõ (lưu ý: chúng tôi biết trước khi tay nó là một số loại điều nén, mabye deflate lẽ gzip):

export URL="https://commoncrawl.s3.amazonaws.com/crawl-data/CC-MAIN-2016-18/segments/1461860106452.21/warc/CC-MAIN-20160428161506-00007-ip-10-239-7-51.ec2.internal.warc.gz" 
curl -r 266472196-266527075 $URL | gzip -dc | tee hello.txt 

với các tiêu đề phản ứng sau đây:

HTTP/1.1 206 Partial Content 
x-amz-id-2: IzdPq3DAPfitkgdXhEwzBSwkxwJRx9ICtfxnnruPCLSMvueRA8j7a05hKr++Na6s 
x-amz-request-id: 14B89CED698E0954 
Date: Sat, 06 Aug 2016 01:26:03 GMT 
Last-Modified: Sat, 07 May 2016 08:39:18 GMT 
ETag: "144a93586a13abf27cb9b82b10a87787" 
Accept-Ranges: bytes 
Content-Range: bytes 266472196-266527075/711047506 
Content-Type: application/octet-stream 
Content-Length: 54880 
Server: AmazonS3 

Vì vậy, để cho điểm.

Cho phép hiển thị đầu ra hex của 10 byte đầu tiên: curl -r 266472196-266472208 $URL | xxd

hex đầu ra:

0000000: 1f8b 0800 0000 0000 0000 ecbd eb 

Chúng ta có thể thấy một số vấn đề cơ bản về những gì chúng tôi đang làm việc với với các giá trị hex.

Khoảng nghĩa lẽ nó một gzip (1f8b) sử dụng deflate (0800) mà không có một thời gian sửa đổi (0000 0000), hoặc bất kỳ cờ thêm set (00), sử dụng một hệ thống fat32 (00).

Vui lòng tham khảo mục 2.3/2.3.1: https://tools.ietf.org/html/rfc1952#section-2.3.1

Vì vậy, vào python:

>>> import requests 
>>> url = 'https://commoncrawl.s3.amazonaws.com/crawl-data/CC-MAIN-2016-18/segments/1461860106452.21/warc/CC-MAIN-20160428161506-00006-ip-10-239-7-51.ec2.internal.warc.gz' 
>>> response = requests.get(url, params={"range":"bytes=257173173-257248267"}) 
>>> unknown_compressed_data = response.content 

thông báo bất cứ điều gì tương tự ?:

>>> unknown_compressed_data[:10] 
'\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x00' 

Và trên để giải nén chúng ta hãy chỉ cố gắng một cách ngẫu nhiên dựa trên (documentation):

>>> import zlib 

"zlib.error: Lỗi -2 trong khi prepa nhẫn để giải nén dữ liệu: không ổn định dòng ":

>>> zlib.decompress(unknown_compressed_data, -31) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
zlib.error: Error -2 while preparing to decompress data: inconsistent stream state 

"Lỗi -3 khi giải nén dữ liệu: kiểm tra tiêu đề không chính xác":

>>> zlib.decompress(unknown_compressed_data) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
zlib.error: Error -3 while decompressing data: incorrect header check 

" zlib.error: Lỗi -3 trong khi giải nén dữ liệu: khoảng cách không hợp lệ quá xa trở lại ":

>>> zlib.decompress(unknown_compressed_data, 30) 
Traceback (most recent call last): 
File "<stdin>", line 1, in <module> 
zlib.error: Error -3 while decompressing data: invalid distance too far back 

Có thể s olution:

>>> zlib.decompress(unknown_compressed_data, 31) 
'WARC/1.0\r\nWARC-Type: response\r\nWARC-Date: 2016-04-28T20:14:16Z\r\nWARC-Record-ID: <urn:uu 
+0

Tuyệt vời. Điều này làm việc cho tôi. – bibbsey

Các vấn đề liên quan