Permalink
Browse files

Fixing Content-Length calculation when there is buffered output that …

…will be sent before the response body. fixes #2208
  • Loading branch information...
1 parent 606c30b commit 2711178b4b55eec7fa390cf98fd478bb28645cf7 @lorenzo lorenzo committed Nov 4, 2011
Showing with 35 additions and 7 deletions.
  1. +18 −7 lib/Cake/Network/CakeResponse.php
  2. +17 −0 lib/Cake/Test/Case/Network/CakeResponseTest.php
@@ -349,19 +349,30 @@ public function send() {
$codeMessage = $this->_statusCodes[$this->_status];
$this->_sendHeader("{$this->_protocol} {$this->_status} {$codeMessage}");
$this->_sendHeader('Content-Type', "{$this->_contentType}; charset={$this->_charset}");
+ $this->_setContentLength();
+ foreach ($this->_headers as $header => $value) {
+ $this->_sendHeader($header, $value);
+ }
+ $this->_sendContent($this->_body);
+ }
+
+/**
+ * Calculates the correct Content-Length and sets it as a header in the response
+ * Will not set the value if already set or if the output is compressed.
+ *
+ * @return void
+ */
+ protected function _setContentLength() {
$shouldSetLength = empty($this->_headers['Content-Length']) && !in_array($this->_status, range(301, 307));
if ($shouldSetLength && !$this->outputCompressed()) {
+ $offset = ob_get_level() ? ob_get_length() : 0;
if (ini_get('mbstring.func_overload') & 2 && function_exists('mb_strlen')) {
- $this->_headers['Content-Length'] = mb_strlen($this->_body, '8bit');
+ $this->_headers['Content-Length'] = $offset + mb_strlen($this->_body, '8bit');
} else {
- $this->_headers['Content-Length'] = strlen($this->_body);
+ $this->_headers['Content-Length'] = $offset + strlen($this->_body);
}
}
- foreach ($this->_headers as $header => $value) {
- $this->_sendHeader($header, $value);
- }
- $this->_sendContent($this->_body);
- }
+ }
/**
* Sends a header to the client.
@@ -424,5 +424,22 @@ public function testSendContentLength() {
$response->expects($this->once())->method('_sendContent')->with($body);
$response->expects($this->exactly(2))->method('_sendHeader');
$response->send();
+
+ ob_start();
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
+ $goofyOutput = 'I am goofily sending output in the controller';
+ echo $goofyOutput;
+ $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', strlen($goofyOutput) + 116);
+ $response->send();
+ ob_end_clean();
}
}

0 comments on commit 2711178

Please sign in to comment.