Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixes #2175

Adding automatic Content-Length header to hint browser of the end of the response when using persistent connections
  • Loading branch information...
commit 4a453cc384414b5f55cc30609621b4eb2360cc89 1 parent 95acaba
@lorenzo lorenzo authored
View
18 lib/Cake/Network/CakeResponse.php
@@ -16,6 +16,9 @@
* @since CakePHP(tm) v 2.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
+
+App::uses('Multibyte', 'I18n');
+
/**
* CakeResponse is responsible for managing the response text, status and headers of a HTTP response.
*
@@ -347,7 +350,11 @@ public function send() {
$codeMessage = $this->_statusCodes[$this->_status];
$this->_sendHeader("{$this->_protocol} {$this->_status} {$codeMessage}");
$this->_sendHeader('Content-Type', "{$this->_contentType}; charset={$this->_charset}");
-
+ $shouldSetLength = empty($this->_headers['Content-Length']) && class_exists('Multibyte');
+ $shouldSetLength = $shouldSetLength && !$this->outputCompressed();
+ if ($shouldSetLength) {
+ $this->_headers['Content-Length'] = mb_strlen($this->_body);
+ }
foreach ($this->_headers as $header => $value) {
$this->_sendHeader($header, $value);
}
@@ -644,6 +651,15 @@ public function compress() {
}
/**
+ * Returns whether the resulting output will be compressed by PHP
+ *
+ * @return boolean
+ */
+ public function outputCompressed() {
+ return ini_get("zlib.output_compression") === '1' || in_array('ob_gzhandler', ob_list_handlers());
+ }
+
+/**
* Sets the correct headers to instruct the browser to dowload the response as a file.
*
* @param string $filename the name of the file as the browser will download the response
View
47 lib/Cake/Test/Case/Network/CakeResponseTest.php
@@ -370,4 +370,51 @@ public function testMapType() {
$result = $response->mapType(array('application/json', 'application/xhtml+xml', 'text/css'));
$this->assertEquals($expected, $result);
}
+
+/**
+* Tests the send and setting of Content-Length
+*
+*/
+ public function testSendContentLength() {
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
+ $response->body('the response body');
+ $response->expects($this->once())->method('_sendContent')->with('the response body');
+ $response->expects($this->at(0))
+ ->method('_sendHeader')->with('HTTP/1.1 200 OK');
+ $response->expects($this->at(1))
+ ->method('_sendHeader')->with('Content-Type', 'text/html; charset=UTF-8');
+ $response->expects($this->at(2))
+ ->method('_sendHeader')->with('Content-Length', strlen('the response body'));
+ $response->send();
+
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
+ $body = '長い長い長いSubjectの場合はfoldingするのが正しいんだけどいったいどうなるんだろう?';
+ $response->body($body);
+ $response->expects($this->once())->method('_sendContent')->with($body);
+ $response->expects($this->at(0))
+ ->method('_sendHeader')->with('HTTP/1.1 200 OK');
+ $response->expects($this->at(1))
+ ->method('_sendHeader')->with('Content-Type', 'text/html; charset=UTF-8');
+ $response->expects($this->at(2))
+ ->method('_sendHeader')->with('Content-Length', mb_strlen($body));
+ $response->send();
+
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent', 'outputCompressed'));
+ $body = '長い長い長いSubjectの場合はfoldingするのが正しいんだけどいったいどうなるんだろう?';
+ $response->body($body);
+ $response->expects($this->once())->method('outputCompressed')->will($this->returnValue(true));
+ $response->expects($this->once())->method('_sendContent')->with($body);
+ $response->expects($this->exactly(2))->method('_sendHeader');
+ $response->send();
+
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent', 'outputCompressed'));
+ $body = 'hwy';
+ $response->body($body);
+ $response->header('Content-Length', 1);
+ $response->expects($this->never())->method('outputCompressed');
+ $response->expects($this->once())->method('_sendContent')->with($body);
+ $response->expects($this->at(2))
+ ->method('_sendHeader')->with('Content-Length', 1);
+ $response->send();
+ }
}
Please sign in to comment.
Something went wrong with that request. Please try again.