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

moved some RFC-tweaking logic in Response to a public method to make it reusable

Fabien Potencier 14 лет назад
Родитель
Сommit
0e4d057984

+ 31 - 33
src/Symfony/Component/HttpFoundation/Response.php

@@ -98,7 +98,7 @@ class Response
      */
     public function __toString()
     {
-        $this->fixContent();
+        $this->prepare();
 
         return
             sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText)."\r\n".
@@ -114,6 +114,35 @@ class Response
         $this->headers = clone $this->headers;
     }
 
+    /**
+     * Prepares the Response before it is sent to the client.
+     *
+     * This method tweaks the Response to ensure that it is
+     * compliant with RFC 2616.
+     */
+    public function prepare()
+    {
+        if ($this->isInformational() || in_array($this->statusCode, array(204, 304))) {
+            $this->setContent('');
+        }
+
+        // Fix Content-Type
+        $charset = $this->charset ?: 'UTF-8';
+        if (!$this->headers->has('Content-Type')) {
+            $this->headers->set('Content-Type', 'text/html; charset='.$charset);
+        } elseif ('text/' === substr($this->headers->get('Content-Type'), 0, 5) && false === strpos($this->headers->get('Content-Type'), 'charset')) {
+            // add the charset
+            $this->headers->set('Content-Type', $this->headers->get('Content-Type').'; charset='.$charset);
+        }
+
+        // Fix Content-Length
+        if ($this->headers->has('Transfer-Encoding')) {
+            $this->headers->remove('Content-Length');
+        } elseif (!$this->headers->has('Content-Length')) {
+            $this->headers->set('Content-Length', strlen($this->content));
+        }
+    }
+
     /**
      * Sends HTTP headers.
      */
@@ -124,7 +153,7 @@ class Response
             return;
         }
 
-        $this->fixContent();
+        $this->prepare();
 
         // status
         header(sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText));
@@ -752,35 +781,4 @@ class Response
     {
         return in_array($this->statusCode, array(201, 204, 304));
     }
-
-    protected function fixContent()
-    {
-        if ($this->isInformational() || in_array($this->statusCode, array(204, 304))) {
-            $this->setContent('');
-        }
-        $this->fixContentType();
-        $this->fixContentLength();
-    }
-
-    protected function fixContentType()
-    {
-        $charset = $this->charset ?: 'UTF-8';
-        if (!$this->headers->has('Content-Type')) {
-            $this->headers->set('Content-Type', 'text/html; charset='.$charset);
-        } elseif ('text/' === substr($this->headers->get('Content-Type'), 0, 5) && false === strpos($this->headers->get('Content-Type'), 'charset')) {
-            // add the charset
-            $this->headers->set('Content-Type', $this->headers->get('Content-Type').'; charset='.$charset);
-        }
-    }
-
-    protected function fixContentLength()
-    {
-        if (!$this->headers->has('Content-Length')) {
-            $this->headers->set('Content-Length', strlen($this->content));
-        }
-
-        if ($this->headers->has('Transfer-Encoding')) {
-            $this->headers->remove('Content-Length');
-        }
-    }
 }

+ 1 - 1
src/Symfony/Component/HttpKernel/EventListener/ResponseListener.php

@@ -16,7 +16,7 @@ use Symfony\Component\HttpFoundation\Response;
 use Symfony\Component\HttpKernel\HttpKernelInterface;
 
 /**
- * ResponseListener fixes the Response Content-Type.
+ * ResponseListener fixes the Response headers based on the Request.
  *
  * @author Fabien Potencier <fabien@symfony.com>
  */

+ 2 - 4
src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php

@@ -196,6 +196,8 @@ class HttpCache implements HttpKernelInterface
             }
         }
 
+        $response->prepare();
+
         return $response;
     }
 
@@ -576,10 +578,6 @@ class HttpCache implements HttpKernelInterface
         }
 
         $response->headers->remove('X-Body-File');
-
-        if (!$response->headers->has('Transfer-Encoding')) {
-            $response->headers->set('Content-Length', strlen($response->getContent()));
-        }
     }
 
     protected function processResponseBody(Request $request, Response $response)

+ 4 - 4
tests/Symfony/Tests/Component/HttpKernel/HttpCache/HttpCacheTest.php

@@ -100,8 +100,8 @@ class HttpCacheTest extends HttpCacheTestCase
 
         $this->assertHttpKernelIsCalled();
         $this->assertEquals(304, $this->response->getStatusCode());
-        $this->assertFalse($this->response->headers->has('Content-Length'));
-        $this->assertFalse($this->response->headers->has('Content-Type'));
+        $this->assertSame(0, $this->response->headers->get('Content-Length'));
+        $this->assertEquals('text/html; charset=UTF-8', $this->response->headers->get('Content-Type'));
         $this->assertEmpty($this->response->getContent());
         $this->assertTraceContains('miss');
         $this->assertTraceContains('store');
@@ -114,8 +114,8 @@ class HttpCacheTest extends HttpCacheTestCase
 
         $this->assertHttpKernelIsCalled();
         $this->assertEquals(304, $this->response->getStatusCode());
-        $this->assertFalse($this->response->headers->has('Content-Length'));
-        $this->assertFalse($this->response->headers->has('Content-Type'));
+        $this->assertSame(0, $this->response->headers->get('Content-Length'));
+        $this->assertEquals('text/html; charset=UTF-8', $this->response->headers->get('Content-Type'));
         $this->assertTrue($this->response->headers->has('ETag'));
         $this->assertEmpty($this->response->getContent());
         $this->assertTraceContains('miss');