2012-04-03 34 views
7

Sau khi thực hiện một yêu cầu gzip deflate trong PHP, tôi nhận được chuỗi xì hơi trong khối bù đắp, trông giống như sauLàm thế nào để giải mã/thổi phồng chuỗi gzip đã được chunked?

Ví dụ rút ngắn rất nhiều để hiển thị định dạng:

00001B4E 
¾”kŒj…Øæ’ìÑ«F1ìÊ`+ƒQì¹UÜjùJƒZ\µy¡ÓUžGr‡J&=KLËÙÍ~=ÍkR 
0000102F 
ñÞœÞôΑüo[¾”+’Ñ8#à»0±R-4VÕ’n›êˆÍ.MCŽ…ÏÖr¿3M—èßñ°r¡\+ 
00000000 

Tôi không thể thổi phồng rằng có lẽ vì định dạng chunked. Tôi có thể xác nhận dữ liệu không bị hỏng sau khi gỡ bỏ thủ công các offset với trình chỉnh sửa Hex và đọc lưu trữ gzip. Tôi tự hỏi nếu có một phương pháp thích hợp để phân tích cú pháp này gzip xáo trộn phản ứng vào một chuỗi có thể đọc được?

Tôi có thể chia các khoảng trống này và kết hợp dữ liệu với nhau trong một chuỗi để gọi gzinflate, nhưng có vẻ như phải có cách dễ dàng hơn.

Trả lời

9

Phương pháp thích hợp của bạn để deflate một chunked đáp ứng được khoảng như sau:

initialise string to hold result 
for each chunk { 
    check that the stated chunk length equals the string length of the chunk 
    append the chunk data to the result variable 
} 

Dưới đây là một chức năng PHP tiện dụng để làm điều đó cho bạn (FIXED):

function unchunk_string ($str) { 

    // A string to hold the result 
    $result = ''; 

    // Split input by CRLF 
    $parts = explode("\r\n", $str); 

    // These vars track the current chunk 
    $chunkLen = 0; 
    $thisChunk = ''; 

    // Loop the data 
    while (($part = array_shift($parts)) !== NULL) { 
    if ($chunkLen) { 
     // Add the data to the string 
     // Don't forget, the data might contain a literal CRLF 
     $thisChunk .= $part."\r\n"; 
     if (strlen($thisChunk) == $chunkLen) { 
     // Chunk is complete 
     $result .= $thisChunk; 
     $chunkLen = 0; 
     $thisChunk = ''; 
     } else if (strlen($thisChunk) == $chunkLen + 2) { 
     // Chunk is complete, remove trailing CRLF 
     $result .= substr($thisChunk, 0, -2); 
     $chunkLen = 0; 
     $thisChunk = ''; 
     } else if (strlen($thisChunk) > $chunkLen) { 
     // Data is malformed 
     return FALSE; 
     } 
    } else { 
     // If we are not in a chunk, get length of the new one 
     if ($part === '') continue; 
     if (!$chunkLen = hexdec($part)) break; 
    } 
    } 

    // Return the decoded data of FALSE if it is incomplete 
    return ($chunkLen) ? FALSE : $result; 

} 
+0

Tuyệt vời, hoạt động như mong đợi. Đó là một chức năng PHP tiện dụng thực sự, tôi đã tìm kiếm điều này trong một thời gian. Cảm ơn rất nhiều! – user1309276

+0

@ user1309276 Tôi đã cập nhật chức năng trên, nó có lỗi xung quanh hành vi khi chuỗi chứa CRLF theo nghĩa đen. Điều này đã được khắc phục, và điều này cũng đã cung cấp phát hiện tốt hơn các chuỗi không đúng định dạng. – DaveRandom

+0

Cảm ơn bạn lần nữa! Đối với bất cứ ai vẫn gặp vấn đề, sau khi gọi unchunk_string tất cả những gì tôi cần làm là loại bỏ 10 byte đầu tiên bằng cách sử dụng: $ data = gzinflate (substr ($ data, 10)); – user1309276

0

Để giải mã một String sử dụng gzinflate, Zend_Http_Client lib sẽ giúp làm điều này loại tác vụ thông thường, WASY của nó để sử dụng, Tham khảo Zend_Http_Response code nếu bạn cần phải làm điều đó một mình

+0

Thật không may tôi đã thử phương pháp sử dụng lib, nhưng nó có chứa một số mã tôi có thể cần trong tương lai, cảm ơn! – user1309276

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