diff options
Diffstat (limited to 'libs/Zend/Http/Client/Adapter/Curl.php')
-rw-r--r-- | libs/Zend/Http/Client/Adapter/Curl.php | 180 |
1 files changed, 132 insertions, 48 deletions
diff --git a/libs/Zend/Http/Client/Adapter/Curl.php b/libs/Zend/Http/Client/Adapter/Curl.php index 3335745c1f..4747bd898c 100644 --- a/libs/Zend/Http/Client/Adapter/Curl.php +++ b/libs/Zend/Http/Client/Adapter/Curl.php @@ -16,16 +16,24 @@ * @category Zend * @package Zend_Http * @subpackage Client_Adapter - * @version $Id: Curl.php 17118 2009-07-26 09:41:41Z shahar $ - * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @version $Id: Curl.php 22221 2010-05-21 07:00:58Z dragonbe $ + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License */ -/** Zend_Uri_Http */ -require_once 'Zend/Uri/Http.php'; +/** + * @see Zend_Uri_Http + */ +// require_once 'Zend/Uri/Http.php'; -/** Zend_Http_Client_Adapter_Interface */ -require_once 'Zend/Http/Client/Adapter/Interface.php'; +/** + * @see Zend_Http_Client_Adapter_Interface + */ +// require_once 'Zend/Http/Client/Adapter/Interface.php'; +/** + * @see Zend_Http_Client_Adapter_Stream + */ +// require_once 'Zend/Http/Client/Adapter/Stream.php'; /** * An adapter class for Zend_Http_Client based on the curl extension. @@ -34,10 +42,10 @@ require_once 'Zend/Http/Client/Adapter/Interface.php'; * @category Zend * @package Zend_Http * @subpackage Client_Adapter - * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License */ -class Zend_Http_Client_Adapter_Curl implements Zend_Http_Client_Adapter_Interface +class Zend_Http_Client_Adapter_Curl implements Zend_Http_Client_Adapter_Interface, Zend_Http_Client_Adapter_Stream { /** * Parameters array @@ -65,23 +73,7 @@ class Zend_Http_Client_Adapter_Curl implements Zend_Http_Client_Adapter_Interfac * * @var array */ - protected $_invalidOverwritableCurlOptions = array( - CURLOPT_HTTPGET, - CURLOPT_POST, - CURLOPT_PUT, - CURLOPT_CUSTOMREQUEST, - CURLOPT_HEADER, - CURLOPT_RETURNTRANSFER, - CURLOPT_HTTPHEADER, - CURLOPT_POSTFIELDS, - CURLOPT_INFILE, - CURLOPT_INFILESIZE, - CURLOPT_PORT, - CURLOPT_MAXREDIRS, - CURLOPT_TIMEOUT, - CURL_HTTP_VERSION_1_1, - CURL_HTTP_VERSION_1_0, - ); + protected $_invalidOverwritableCurlOptions; /** * Response gotten from server @@ -91,6 +83,13 @@ class Zend_Http_Client_Adapter_Curl implements Zend_Http_Client_Adapter_Interfac protected $_response = null; /** + * Stream for storing output + * + * @var resource + */ + protected $out_stream; + + /** * Adapter constructor * * Config is set using setConfig() @@ -101,9 +100,26 @@ class Zend_Http_Client_Adapter_Curl implements Zend_Http_Client_Adapter_Interfac public function __construct() { if (!extension_loaded('curl')) { - require_once 'Zend/Http/Client/Adapter/Exception.php'; + // require_once 'Zend/Http/Client/Adapter/Exception.php'; throw new Zend_Http_Client_Adapter_Exception('cURL extension has to be loaded to use this Zend_Http_Client adapter.'); } + $this->_invalidOverwritableCurlOptions = array( + CURLOPT_HTTPGET, + CURLOPT_POST, + CURLOPT_PUT, + CURLOPT_CUSTOMREQUEST, + CURLOPT_HEADER, + CURLOPT_RETURNTRANSFER, + CURLOPT_HTTPHEADER, + CURLOPT_POSTFIELDS, + CURLOPT_INFILE, + CURLOPT_INFILESIZE, + CURLOPT_PORT, + CURLOPT_MAXREDIRS, + CURLOPT_CONNECTTIMEOUT, + CURL_HTTP_VERSION_1_1, + CURL_HTTP_VERSION_1_0, + ); } /** @@ -119,7 +135,7 @@ class Zend_Http_Client_Adapter_Curl implements Zend_Http_Client_Adapter_Interfac $config = $config->toArray(); } elseif (! is_array($config)) { - require_once 'Zend/Http/Client/Adapter/Exception.php'; + // require_once 'Zend/Http/Client/Adapter/Exception.php'; throw new Zend_Http_Client_Adapter_Exception( 'Array or Zend_Config object expected, got ' . gettype($config) ); @@ -149,6 +165,16 @@ class Zend_Http_Client_Adapter_Curl implements Zend_Http_Client_Adapter_Interfac } /** + * Retrieve the array of all configuration options + * + * @return array + */ + public function getConfig() + { + return $this->_config; + } + + /** * Direct setter for cURL adapter related options. * * @param string|int $option @@ -196,7 +222,7 @@ class Zend_Http_Client_Adapter_Curl implements Zend_Http_Client_Adapter_Interfac } // Set timeout - curl_setopt($this->_curl, CURLOPT_TIMEOUT, $this->_config['timeout']); + curl_setopt($this->_curl, CURLOPT_CONNECTTIMEOUT, $this->_config['timeout']); // Set Max redirects curl_setopt($this->_curl, CURLOPT_MAXREDIRS, $this->_config['maxredirects']); @@ -204,7 +230,7 @@ class Zend_Http_Client_Adapter_Curl implements Zend_Http_Client_Adapter_Interfac if (!$this->_curl) { $this->close(); - require_once 'Zend/Http/Client/Adapter/Exception.php'; + // require_once 'Zend/Http/Client/Adapter/Exception.php'; throw new Zend_Http_Client_Adapter_Exception('Unable to Connect to ' . $host . ':' . $port); } @@ -233,16 +259,16 @@ class Zend_Http_Client_Adapter_Curl implements Zend_Http_Client_Adapter_Interfac * @return string $request * @throws Zend_Http_Client_Adapter_Exception If connection fails, connected to wrong host, no PUT file defined, unsupported method, or unsupported cURL option */ - public function write($method, $uri, $http_ver = '1.1', $headers = array(), $body = '') + public function write($method, $uri, $httpVersion = 1.1, $headers = array(), $body = '') { // Make sure we're properly connected if (!$this->_curl) { - require_once 'Zend/Http/Client/Adapter/Exception.php'; + // require_once 'Zend/Http/Client/Adapter/Exception.php'; throw new Zend_Http_Client_Adapter_Exception("Trying to write but we are not connected"); } if ($this->_connected_to[0] != $uri->getHost() || $this->_connected_to[1] != $uri->getPort()) { - require_once 'Zend/Http/Client/Adapter/Exception.php'; + // require_once 'Zend/Http/Client/Adapter/Exception.php'; throw new Zend_Http_Client_Adapter_Exception("Trying to write but we are connected to the wrong host"); } @@ -263,20 +289,30 @@ class Zend_Http_Client_Adapter_Curl implements Zend_Http_Client_Adapter_Interfac case Zend_Http_Client::PUT: // There are two different types of PUT request, either a Raw Data string has been set // or CURLOPT_INFILE and CURLOPT_INFILESIZE are used. + if(is_resource($body)) { + $this->_config['curloptions'][CURLOPT_INFILE] = $body; + } if (isset($this->_config['curloptions'][CURLOPT_INFILE])) { - if (!isset($this->_config['curloptions'][CURLOPT_INFILESIZE])) { - require_once 'Zend/Http/Client/Adapter/Exception.php'; - throw new Zend_Http_Client_Adapter_Exception("Cannot set a file-handle for cURL option CURLOPT_INFILE without also setting its size in CURLOPT_INFILESIZE."); - } - // Now we will probably already have Content-Length set, so that we have to delete it // from $headers at this point: foreach ($headers AS $k => $header) { - if (stristr($header, "Content-Length:") !== false) { + if (preg_match('/Content-Length:\s*(\d+)/i', $header, $m)) { + if(is_resource($body)) { + $this->_config['curloptions'][CURLOPT_INFILESIZE] = (int)$m[1]; + } unset($headers[$k]); } } + if (!isset($this->_config['curloptions'][CURLOPT_INFILESIZE])) { + // require_once 'Zend/Http/Client/Adapter/Exception.php'; + throw new Zend_Http_Client_Adapter_Exception("Cannot set a file-handle for cURL option CURLOPT_INFILE without also setting its size in CURLOPT_INFILESIZE."); + } + + if(is_resource($body)) { + $body = ''; + } + $curlMethod = CURLOPT_PUT; } else { $curlMethod = CURLOPT_CUSTOMREQUEST; @@ -298,25 +334,43 @@ class Zend_Http_Client_Adapter_Curl implements Zend_Http_Client_Adapter_Interfac $curlMethod = CURLOPT_CUSTOMREQUEST; $curlValue = "TRACE"; break; + + case Zend_Http_Client::HEAD: + $curlMethod = CURLOPT_CUSTOMREQUEST; + $curlValue = "HEAD"; + break; default: // For now, through an exception for unsupported request methods - require_once 'Zend/Http/Client/Adapter/Exception.php'; + // require_once 'Zend/Http/Client/Adapter/Exception.php'; throw new Zend_Http_Client_Adapter_Exception("Method currently not supported"); } + if(is_resource($body) && $curlMethod != CURLOPT_PUT) { + // require_once 'Zend/Http/Client/Adapter/Exception.php'; + throw new Zend_Http_Client_Adapter_Exception("Streaming requests are allowed only with PUT"); + } + // get http version to use - $curlHttp = ($http_ver = 1.1) ? CURL_HTTP_VERSION_1_1 : CURL_HTTP_VERSION_1_0; + $curlHttp = ($httpVersion == 1.1) ? CURL_HTTP_VERSION_1_1 : CURL_HTTP_VERSION_1_0; // mark as HTTP request and set HTTP method curl_setopt($this->_curl, $curlHttp, true); curl_setopt($this->_curl, $curlMethod, $curlValue); - // ensure headers are also returned - curl_setopt($this->_curl, CURLOPT_HEADER, true); - - // ensure actual response is returned - curl_setopt($this->_curl, CURLOPT_RETURNTRANSFER, true); + if($this->out_stream) { + // headers will be read into the response + curl_setopt($this->_curl, CURLOPT_HEADER, false); + curl_setopt($this->_curl, CURLOPT_HEADERFUNCTION, array($this, "readHeader")); + // and data will be written into the file + curl_setopt($this->_curl, CURLOPT_FILE, $this->out_stream); + } else { + // ensure headers are also returned + curl_setopt($this->_curl, CURLOPT_HEADER, true); + + // ensure actual response is returned + curl_setopt($this->_curl, CURLOPT_RETURNTRANSFER, true); + } // set additional headers $headers['Accept'] = ''; @@ -346,7 +400,7 @@ class Zend_Http_Client_Adapter_Curl implements Zend_Http_Client_Adapter_Interfac foreach ((array)$this->_config['curloptions'] as $k => $v) { if (!in_array($k, $this->_invalidOverwritableCurlOptions)) { if (curl_setopt($this->_curl, $k, $v) == false) { - require_once 'Zend/Http/Client/Exception.php'; + // require_once 'Zend/Http/Client/Exception.php'; throw new Zend_Http_Client_Exception(sprintf("Unknown or erroreous cURL option '%s' set", $k)); } } @@ -354,13 +408,18 @@ class Zend_Http_Client_Adapter_Curl implements Zend_Http_Client_Adapter_Interfac } // send the request - $this->_response = curl_exec($this->_curl); + $response = curl_exec($this->_curl); + + // if we used streaming, headers are already there + if(!is_resource($this->out_stream)) { + $this->_response = $response; + } $request = curl_getinfo($this->_curl, CURLINFO_HEADER_OUT); $request .= $body; if (empty($this->_response)) { - require_once 'Zend/Http/Client/Exception.php'; + // require_once 'Zend/Http/Client/Exception.php'; throw new Zend_Http_Client_Exception("Error in cURL request: " . curl_error($this->_curl)); } @@ -420,4 +479,29 @@ class Zend_Http_Client_Adapter_Curl implements Zend_Http_Client_Adapter_Interfac { return $this->_curl; } + + /** + * Set output stream for the response + * + * @param resource $stream + * @return Zend_Http_Client_Adapter_Socket + */ + public function setOutputStream($stream) + { + $this->out_stream = $stream; + return $this; + } + + /** + * Header reader function for CURL + * + * @param resource $curl + * @param string $header + * @return int + */ + public function readHeader($curl, $header) + { + $this->_response .= $header; + return strlen($header); + } } |