From 356a367eb5d05bea3dfa2edaeabc52a2496b93b2 Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Sat, 29 Sep 2012 17:23:05 +0200 Subject: [PATCH] BUG Setting response length directly before output (fixes #7574) Complying to HTTP1.1/RFC2616 in terms of when to set 'Content-Length' in the first place --- control/Director.php | 11 +++++++++++ control/HTTPResponse.php | 11 ++++++++--- tests/control/HTTPResponseTest.php | 2 ++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/control/Director.php b/control/Director.php index 4148db723..2a4d60236 100644 --- a/control/Director.php +++ b/control/Director.php @@ -141,6 +141,17 @@ class Director implements TemplateGlobalProvider { number_format(memory_get_peak_usage(),0) )); } else { + // Set content length (according to RFC2616) + if( + !headers_sent() + && $response->getBody() + && $req->httpMethod() != 'HEAD' + && $response->getStatusCode() >= 200 + && !in_array($response->getStatusCode(), array(204, 304)) + ) { + $response->fixContentLength(); + } + $response->output(); } } else { diff --git a/control/HTTPResponse.php b/control/HTTPResponse.php index df7eb60ca..ff8289ac6 100644 --- a/control/HTTPResponse.php +++ b/control/HTTPResponse.php @@ -150,9 +150,6 @@ class SS_HTTPResponse { public function setBody($body) { $this->body = $body; - - // Set content-length in bytes. Use mbstring to avoid problems with mb_internal_encoding() and mbstring.func_overload - $this->headers['Content-Length'] = mb_strlen($this->body,'8bit'); } public function getBody() { @@ -248,6 +245,14 @@ class SS_HTTPResponse { public function isFinished() { return in_array($this->statusCode, array(301, 302, 401, 403)); } + + /** + * Set content-length in bytes. Should be called right before {@link output()}. + */ + public function fixContentLength() { + // Use mbstring to avoid problems with mb_internal_encoding() and mbstring.func_overload + $this->headers['Content-Length'] = mb_strlen($this->body,'8bit'); + } } diff --git a/tests/control/HTTPResponseTest.php b/tests/control/HTTPResponseTest.php index f2f37c693..69675c19d 100644 --- a/tests/control/HTTPResponseTest.php +++ b/tests/control/HTTPResponseTest.php @@ -15,6 +15,7 @@ class HTTPResponseTest extends SapphireTest { public function testContentLengthHeader() { $r = new SS_HTTPResponse('123ü'); + $r->fixContentLength(); $this->assertNotNull($r->getHeader('Content-Length'), 'Content-length header is added'); $this->assertEquals( 5, @@ -23,6 +24,7 @@ class HTTPResponseTest extends SapphireTest { ); $r->setBody('1234ü'); + $r->fixContentLength(); $this->assertEquals( 6, $r->getHeader('Content-Length'),