Просмотр исходного кода

Fixing ZF-6040: auto-detect zlib header in deflate body for buggy servers

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@17055 44c647ce-9c0f-0410-b52a-842ac1e357ba
shahar 16 лет назад
Родитель
Сommit
415c276e16

+ 23 - 5
library/Zend/Http/Response.php

@@ -601,8 +601,9 @@ class Zend_Http_Response
     {
         if (! function_exists('gzinflate')) {
             require_once 'Zend/Http/Exception.php';
-            throw new Zend_Http_Exception('Unable to decode gzipped response ' .
-                'body: perhaps the zlib extension is not loaded?');
+            throw new Zend_Http_Exception(
+                'zlib extension is required in order to decode "gzip" encoding'
+            );
         }
 
         return gzinflate(substr($body, 10));
@@ -620,11 +621,28 @@ class Zend_Http_Response
     {
         if (! function_exists('gzuncompress')) {
             require_once 'Zend/Http/Exception.php';
-            throw new Zend_Http_Exception('Unable to decode deflated response ' .
-                'body: perhaps the zlib extension is not loaded?');
+            throw new Zend_Http_Exception(
+                'zlib extension is required in order to decode "deflate" encoding'
+            );
         }
 
-        return gzuncompress($body);
+        /**
+         * Some servers (IIS ?) send a broken deflate response, without the 
+         * RFC-required zlib header. 
+         * 
+         * We try to detect the zlib header, and if it does not exsit we 
+         * teat the body is plain DEFLATE content.
+         * 
+         * This method was adapted from PEAR HTTP_Request2 by (c) Alexey Borzov
+         * 
+         * @link http://framework.zend.com/issues/browse/ZF-6040
+         */
+        $zlibHeader = unpack('n', substr($body, 0, 2));
+        if ($zlibHeader[1] % 31 == 0) {
+            return gzuncompress($body);
+        } else {
+            return gzinflate($body); 
+        }
     }
 
     /**

+ 20 - 0
tests/Zend/Http/ResponseTest.php

@@ -59,6 +59,26 @@ class Zend_Http_ResponseTest extends PHPUnit_Framework_TestCase
         $this->assertEquals('0b13cb193de9450aa70a6403e2c9902f', md5($res->getBody()));
         $this->assertEquals('ad62c21c3aa77b6a6f39600f6dd553b8', md5($res->getRawBody()));
     }
+    
+    /**
+     * Make sure wer can handle non-RFC complient "deflate" responses. 
+     * 
+     * Unlike stanrdard 'deflate' response, those do not contain the zlib header
+     * and trailer. Unfortunately some buggy servers (read: IIS) send those and 
+     * we need to support them.
+     * 
+     * @link http://framework.zend.com/issues/browse/ZF-6040
+     */
+    public function testNonStandardDeflateResponseZF6040()
+    {
+        $response_text = file_get_contents(dirname(__FILE__) . '/_files/response_deflate_iis');
+
+        $res = Zend_Http_Response::fromString($response_text);
+
+        $this->assertEquals('deflate', $res->getHeader('Content-encoding'));
+        $this->assertEquals('d82c87e3d5888db0193a3fb12396e616', md5($res->getBody()));
+        $this->assertEquals('c830dd74bb502443cf12514c185ff174', md5($res->getRawBody()));
+    }
 
     public function testChunkedResponse ()
     {

BIN
tests/Zend/Http/_files/response_deflate_iis