From eeafb55d314f3a03508d7067b8d3c46bd3a7ea40 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Fri, 10 Dec 2010 12:08:49 -0200 Subject: [PATCH] Support to download requests. --- cake/libs/http_socket.php | 46 +++++++++++++++++++++- cake/tests/cases/libs/http_socket.test.php | 28 +++++++++++++ 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/cake/libs/http_socket.php b/cake/libs/http_socket.php index 53e010874..0ecc1a60b 100644 --- a/cake/libs/http_socket.php +++ b/cake/libs/http_socket.php @@ -132,6 +132,13 @@ class HttpSocket extends CakeSocket { */ protected $_proxy = array(); +/** + * Resource to receive the content of request + * + * @var mixed + */ + protected $_contentResource = null; + /** * Build an HTTP Socket using the specified configuration. * @@ -208,6 +215,24 @@ class HttpSocket extends CakeSocket { $this->_proxy = compact('host', 'port', 'method', 'user', 'pass'); } +/** + * Set the resource to receive the request content. This resource must support fwrite. + * + * @param mixed $resource Resource or false to disable the resource use + * @return void + * @throw Exception + */ + public function setContentResource($resource) { + if ($resource === false) { + $this->_contentResource = null; + return; + } + if (!is_resource($resource)) { + throw new Exception(__('Invalid resource.')); + } + $this->_contentResource = $resource; + } + /** * Issue the specified request. HttpSocket::get() and HttpSocket::post() wrap this * method and provide a more granular interface. @@ -320,8 +345,27 @@ class HttpSocket extends CakeSocket { $this->write($this->request['raw']); $response = null; + $inHeader = true; while ($data = $this->read()) { - $response .= $data; + if ($this->_contentResource) { + if ($inHeader) { + $response .= $data; + $pos = strpos($response, "\r\n\r\n"); + if ($pos !== false) { + $pos += 4; + $data = substr($response, $pos); + fwrite($this->_contentResource, $data); + + $response = substr($response, 0, $pos); + $inHeader = false; + } + } else { + fwrite($this->_contentResource, $data); + fflush($this->_contentResource); + } + } else { + $response .= $data; + } } if ($connectionType === 'close') { diff --git a/cake/tests/cases/libs/http_socket.test.php b/cake/tests/cases/libs/http_socket.test.php index aac957c0d..32be35f7b 100644 --- a/cake/tests/cases/libs/http_socket.test.php +++ b/cake/tests/cases/libs/http_socket.test.php @@ -638,6 +638,34 @@ class HttpSocketTest extends CakeTestCase { $this->assertEqual($data, $this->Socket->response['body']); } +/** + * testRequestWithResource + * + * @return void + */ + public function testRequestWithResource() { + $serverResponse = "HTTP/1.x 200 OK\r\nDate: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\nContent-Type: text/html\r\n\r\n

This is a test!

"; + $this->Socket->expects($this->at(1))->method('read')->will($this->returnValue($serverResponse)); + $this->Socket->expects($this->at(2))->method('read')->will($this->returnValue(false)); + $this->Socket->expects($this->at(4))->method('read')->will($this->returnValue($serverResponse)); + $this->Socket->connected = true; + + $f = fopen(TMP . 'download.txt', 'w'); + $this->skipUnless($f, 'Can not write in TMP directory.'); + + $this->Socket->setContentResource($f); + $result = $this->Socket->request('http://www.cakephp.org/'); + $this->assertEqual($result, ''); + $this->assertEqual($this->Socket->response['header']['Server'], 'CakeHttp Server'); + fclose($f); + $this->assertEqual(file_get_contents(TMP . 'download.txt'), '

This is a test!

'); + unlink(TMP . 'download.txt'); + + $this->Socket->setContentResource(false); + $result = $this->Socket->request('http://www.cakephp.org/'); + $this->assertEqual($result, '

This is a test!

'); + } + /** * testProxy method *