Files
grzanieplus.pl/plugins/sfWebBrowserPlugin/lib/sfCurlAdapter.class.php
2025-03-12 17:06:23 +01:00

248 lines
7.0 KiB
PHP

<?php
/*
* This file is part of the sfWebBrowserPlugin package.
* (c) 2004-2006 Francois Zaninotto <francois.zaninotto@symfony-project.com>
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com> for the click-related functions
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* sfWebBrowser provides a basic HTTP client.
*
* @package sfWebBrowserPlugin
* @author Francois Zaninotto <francois.zaninotto@symfony-project.com>
* @author Ben Meynell <bmeynell@colorado.edu>
* @version 0.9
*/
class sfCurlAdapter
{
protected
$options = array(),
$curl = null,
$headers = array();
/**
* Build a curl adapter instance
* Accepts an option of parameters passed to the PHP curl adapter:
* ssl_verify => [true/false]
* verbose => [true/false]
* verbose_log => [true/false]
* Additional options are passed as curl options, under the form:
* userpwd => CURL_USERPWD
* timeout => CURL_TIMEOUT
* ...
*
* @param array $options Curl-specific options
*/
public function __construct($options = array())
{
if (!extension_loaded('curl'))
{
throw new Exception('Curl extension not loaded');
}
$this->options = $options;
$curl_options = $options;
$this->curl = curl_init();
// cookies
if (isset($curl_options['cookies']))
{
if (isset($curl_options['cookies_file']))
{
$cookie_file = $curl_options['cookies_file'];
unset($curl_options['cookies_file']);
}
else
{
$cookie_file = sfConfig::get('sf_data_dir').'/sfWebBrowserPlugin/sfCurlAdapter/cookies.txt';
}
if (isset($curl_options['cookies_dir']))
{
$cookie_dir = $curl_options['cookies_dir'];
unset($curl_options['cookies_dir']);
}
else
{
$cookie_dir = sfConfig::get('sf_data_dir').'/sfWebBrowserPlugin/sfCurlAdapter';
}
if (!is_dir($cookie_dir))
{
if (!mkdir($cookie_dir, 0777, true))
{
throw new Exception(sprintf('Could not create directory "%s"', $cookie_dir));
}
}
curl_setopt($this->curl, CURLOPT_COOKIESESSION, false);
curl_setopt($this->curl, CURLOPT_COOKIEJAR, $cookie_file);
curl_setopt($this->curl, CURLOPT_COOKIEFILE, $cookie_file);
unset($curl_options['cookies']);
}
// default settings
curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($this->curl, CURLOPT_AUTOREFERER, true);
curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($this->curl, CURLOPT_FRESH_CONNECT, true);
if(isset($curl_options['followlocation']))
{
curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, (bool) $this->options['followlocation']);
unset($curl_options['followlocation']);
}
// activate ssl certificate verification?
if (isset($curl_options['ssl_verify_host']))
{
curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, (bool) $this->options['ssl_verify_host']);
unset($curl_options['ssl_verify_host']);
}
if (isset($curl_options['ssl_verify']))
{
curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, (bool) $this->options['ssl_verify']);
unset($curl_options['ssl_verify']);
}
// verbose execution?
if (isset($curl_options['verbose']))
{
curl_setopt($this->curl, CURLOPT_NOPROGRESS, false);
curl_setopt($this->curl, CURLOPT_VERBOSE, true);
unset($curl_options['cookies']);
}
if (isset($curl_options['verbose_log']))
{
$log_file = sfConfig::get('sf_log_dir').'/sfCurlAdapter_verbose.log';
curl_setopt($this->curl, CURLOPT_VERBOSE, true);
$this->fh = fopen($log_file, 'a+b');
curl_setopt($this->curl, CURLOPT_STDERR, $this->fh);
unset($curl_options['verbose_log']);
}
// Additional options
foreach ($curl_options as $key => $value)
{
$const = constant('CURLOPT_' . strtoupper($key));
if(!is_null($const))
{
curl_setopt($this->curl, $const, $value);
}
}
// response header storage - uses callback function
curl_setopt($this->curl, CURLOPT_HEADERFUNCTION, array($this, 'read_header'));
}
/**
* Submits a request
*
* @param string The request uri
* @param string The request method
* @param array The request parameters (associative array)
* @param array The request headers (associative array)
*
* @return sfWebBrowser The current browser object
*/
public function call($browser, $uri, $method = 'GET', $parameters = array(), $headers = array())
{
// uri
curl_setopt($this->curl, CURLOPT_URL, $uri);
// request headers
$m_headers = array_merge($browser->getDefaultRequestHeaders(), $browser->initializeRequestHeaders($headers));
$request_headers = explode("\r\n", $browser->prepareHeaders($m_headers));
curl_setopt($this->curl, CURLOPT_HTTPHEADER, $request_headers);
// encoding support
if(isset($headers['Accept-Encoding']))
{
curl_setopt($this->curl, CURLOPT_ENCODING, $headers['Accept-Encoding']);
}
// timeout support
if(isset($this->options['Timeout']))
{
curl_setopt($this->curl, CURLOPT_TIMEOUT, $this->options['Timeout']);
}
if (!empty($parameters))
{
if (!is_array($parameters))
{
curl_setopt($this->curl, CURLOPT_POSTFIELDS, $parameters);
}
else
{
// multipart posts (file upload support)
$has_files = false;
foreach ($parameters as $name => $value)
{
if (is_array($value)) {
continue;
}
/** @link https://svn.php.net/viewvc/?view=revision&amp;revision=305507 */
if (false === strpos($value, "\0") && is_file($value))
{
$has_files = true;
$parameters[$name] = '@'.realpath($value);
}
}
if($has_files)
{
curl_setopt($this->curl, CURLOPT_POSTFIELDS, $parameters);
}
else
{
curl_setopt($this->curl, CURLOPT_POSTFIELDS, http_build_query($parameters, '', '&'));
}
}
}
else
{
curl_setopt($this->curl, CURLOPT_POSTFIELDS, "");
}
// handle any request method
curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, $method);
$response = curl_exec($this->curl);
if (curl_errno($this->curl))
{
throw new Exception(curl_error($this->curl), curl_errno($this->curl));
}
$requestInfo = curl_getinfo($this->curl);
$browser->setResponseCode($requestInfo['http_code']);
$browser->setResponseHeaders($this->headers);
$browser->setResponseText($response);
// clear response headers
$this->headers = array();
return $browser;
}
public function __destruct()
{
curl_close($this->curl);
}
protected function read_header($curl, $headers)
{
$this->headers[] = $headers;
return strlen($headers);
}
}