mirror of
https://github.com/codeigniter4/CodeIgniter4.git
synced 2025-02-20 11:44:28 +08:00
Adding some options and standard abilities to CURLRequest. More to come...
This commit is contained in:
parent
efda966e14
commit
ba2ab15f02
@ -14,23 +14,21 @@ use App\Config\AppConfig;
|
||||
*/
|
||||
class CURLRequest extends Request
|
||||
{
|
||||
protected $timeout = 2.0;
|
||||
|
||||
/**
|
||||
* @var ResponseInterface
|
||||
*/
|
||||
protected $response;
|
||||
|
||||
/**
|
||||
* The first poriton of URI that is prepended
|
||||
* to all relative requests.
|
||||
* @var string
|
||||
* @var URI
|
||||
*/
|
||||
protected $base_uri;
|
||||
|
||||
/**
|
||||
* If TRUE, turns on VERBOSE reporting through cURL
|
||||
* and output to STDOUT
|
||||
* @var bool
|
||||
*/
|
||||
protected $debug = false;
|
||||
protected $config = [
|
||||
'timeout' => 0.0,
|
||||
'connect_timeout' => 150,
|
||||
'debug' => false
|
||||
];
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
@ -76,7 +74,7 @@ class CURLRequest extends Request
|
||||
|
||||
$url = $this->prepareURL($url);
|
||||
|
||||
$this->send($url);
|
||||
$this->send($method, $url);
|
||||
|
||||
return $this->response;
|
||||
}
|
||||
@ -202,12 +200,19 @@ class CURLRequest extends Request
|
||||
unset($options['base_uri']);
|
||||
}
|
||||
|
||||
if (array_key_exists('headers', $options) && is_array($options['headers']))
|
||||
{
|
||||
foreach ($options['headers'] as $name => $value)
|
||||
{
|
||||
$this->setHeader($name, $value);
|
||||
}
|
||||
|
||||
unset($options['headers']);
|
||||
}
|
||||
|
||||
foreach ($options as $key => $value)
|
||||
{
|
||||
if (isset($this->$key))
|
||||
{
|
||||
$this->$key = $value;
|
||||
}
|
||||
$this->config[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
@ -241,7 +246,7 @@ class CURLRequest extends Request
|
||||
*
|
||||
* @param string $url
|
||||
*/
|
||||
public function send(string $url)
|
||||
public function send(string $method, string $url)
|
||||
{
|
||||
$ch = curl_init();
|
||||
|
||||
@ -251,15 +256,12 @@ class CURLRequest extends Request
|
||||
curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
|
||||
|
||||
$this->setCURLOptions($ch);
|
||||
$this->applyMethod($method, $ch);
|
||||
$this->applyRequestHeaders($ch);
|
||||
|
||||
// Send the request and wait for a response.
|
||||
$output = curl_exec($ch);
|
||||
|
||||
if ($this->debug)
|
||||
{
|
||||
echo $output;
|
||||
}
|
||||
|
||||
if($output === false)
|
||||
{
|
||||
throw new \RuntimeException(curl_errno($ch) .': '. curl_error($ch));
|
||||
@ -281,12 +283,84 @@ class CURLRequest extends Request
|
||||
$body = substr($output, $break+4);
|
||||
$this->response->setBody($body);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->response->setBody($output);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Takes all headers current part of this request and adds them
|
||||
* to the cURL request.
|
||||
*
|
||||
* @param $handle
|
||||
*/
|
||||
protected function applyRequestHeaders($handle)
|
||||
{
|
||||
$headers = $this->headers();
|
||||
|
||||
if (empty($head)) return;
|
||||
|
||||
$set = [];
|
||||
|
||||
foreach ($headers as $name => $value)
|
||||
{
|
||||
$set[] = $name.': '. $this->headerLine($name);
|
||||
}
|
||||
|
||||
curl_setopt($handle, CURLOPT_HTTPHEADER, $set);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
protected function applyMethod($method, $handle)
|
||||
{
|
||||
$method = strtoupper($method);
|
||||
|
||||
curl_setopt($handle, CURLOPT_CUSTOMREQUEST, $method);
|
||||
|
||||
$size = strlen($this->body);
|
||||
|
||||
// Have content?
|
||||
if ($size === null || $size > 0)
|
||||
{
|
||||
$this->applyBody($handle);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($method == 'PUT' || $method == 'POST')
|
||||
{
|
||||
// See http://tools.ietf.org/html/rfc7230#section-3.3.2
|
||||
if (is_null($this->header('content-length')))
|
||||
{
|
||||
$this->setHeader('Content-Length', 0);
|
||||
}
|
||||
}
|
||||
else if ($method == 'HEAD')
|
||||
{
|
||||
curl_setopt($handle, CURLOPT_NOBODY, 1);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
protected function applyBody($handle)
|
||||
{
|
||||
if (! empty($this->body))
|
||||
{
|
||||
curl_setopt($handle, CURLOPT_POSTFIELDS, (string)$this->body());
|
||||
}
|
||||
|
||||
// curl sometimes adds a content type by default, prevent this
|
||||
$this->setHeader('Content-Type', '');
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Parses the header retrieved from the cURL response into
|
||||
* our Response object.
|
||||
@ -325,8 +399,68 @@ class CURLRequest extends Request
|
||||
|
||||
protected function setCURLOptions($handle)
|
||||
{
|
||||
// Auth Headers
|
||||
if (! empty($this->config['auth']))
|
||||
{
|
||||
curl_setopt($handle, CURLOPT_USERPWD, $this->config['auth'][0].':'.$this->config['auth'][1]);
|
||||
|
||||
if (! empty($this->config['auth'][2]) && strtolower($this->config['auth'][2]) == 'digest')
|
||||
{
|
||||
curl_setopt($handle, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
|
||||
}
|
||||
else
|
||||
{
|
||||
curl_setopt($handle, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
|
||||
}
|
||||
}
|
||||
|
||||
// Certificate
|
||||
if (! empty($this->config['cert']))
|
||||
{
|
||||
$cert = $this->config['cert'];
|
||||
|
||||
if (is_array($cert))
|
||||
{
|
||||
curl_setopt($handle, CURLOPT_SSLCERTPASSWD, $cert[1]);
|
||||
$cert = $cert[0];
|
||||
}
|
||||
|
||||
if (! file_exists($cert))
|
||||
{
|
||||
throw new \InvalidArgumentException('SSL certificate not found at: '. $cert);
|
||||
}
|
||||
|
||||
curl_setopt($handle, CURLOPT_SSLCERT, $cert);
|
||||
}
|
||||
|
||||
// Debug
|
||||
curl_setopt($handle, CURLOPT_VERBOSE, (bool)$this->debug);
|
||||
if (isset($this->config['debug']))
|
||||
{
|
||||
curl_setopt($handle, CURLOPT_VERBOSE, 1);
|
||||
curl_setopt($handle, CURLOPT_STDERR, is_bool($this->config['debug']) ? fopen('php://output', 'w+') : $this->config['debug']);
|
||||
}
|
||||
|
||||
// Decode Content
|
||||
if (! empty($this->config['decode_content']))
|
||||
{
|
||||
$accept = $this->headerLine('Accept-Encoding');
|
||||
|
||||
if ($accept)
|
||||
{
|
||||
curl_setopt($handle, CURLOPT_ENCODING, $accept);
|
||||
}
|
||||
else
|
||||
{
|
||||
curl_setopt($handle, CURLOPT_ENCODING, '');
|
||||
curl_setopt($handle, CURLOPT_HTTPHEADER, 'Accept-Encoding:');
|
||||
}
|
||||
}
|
||||
|
||||
// Timeout
|
||||
curl_setopt($handle, CURLOPT_TIMEOUT_MS, (float)$this->config['timeout'] * 1000);
|
||||
|
||||
// Connection Timeout
|
||||
curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, (float)$this->config['connect_timeout'] * 1000);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
@ -90,7 +90,7 @@ Base URI
|
||||
|
||||
A ``base_uri`` can be set as one of the options during the instantiation of the class. This allows you to
|
||||
set a base URI, and then make all requests with that client using relative URLs. This is especially handy
|
||||
when working with APIs.
|
||||
when working with APIs.::
|
||||
|
||||
$client = Services::curlrequest([
|
||||
'base_uri' => 'https://example.com/api/v1/'
|
||||
@ -159,3 +159,88 @@ Request Options
|
||||
This section describes all of the available options you may pass into the constructor, the ``request()`` method,
|
||||
or any of the shortcut methods.
|
||||
|
||||
|
||||
Auth
|
||||
====
|
||||
|
||||
Allows you to provide Authentication details for `HTTP Basic <http://www.ietf.org/rfc/rfc2069.txt>`_ and
|
||||
`Digest <http://www.ietf.org/rfc/rfc2069.txt>`_ and authentication. Your script may have to do extra to support
|
||||
Digest authentication - this simply passes the username and password along for you. The value must be an
|
||||
array where the first element is the username, and the second is the password. The third parameter should be
|
||||
the type of authentication to use, either ``basic`` or ``digest``.::
|
||||
|
||||
$client->request('GET', 'http://example.com', ['auth' => ['username', 'password', 'digest']]);
|
||||
|
||||
Body
|
||||
====
|
||||
|
||||
There are two ways to set the body of the request for request types that support them, like PUT, OR POST.
|
||||
The first way is to use the ``setBody()`` method::
|
||||
|
||||
$client->setBody($body)
|
||||
->request('put', 'http://example.com');
|
||||
|
||||
The second method is by passing a ``body`` option in. This is provided to maintain Guzzle API compatibility,
|
||||
and functions the exact same way as the previous example. The value must be a string.::
|
||||
|
||||
$client->request('put', 'http://example.com', ['body' => $body]);
|
||||
|
||||
|
||||
|
||||
Certificates
|
||||
============
|
||||
|
||||
To specify the location of a PEM formatted client-side certificate, pass a string with the full path to the
|
||||
file as the ``cert`` option. If a password is required, set the value to an array with the first element
|
||||
as the path to the certificate, and the second as the password::
|
||||
|
||||
$client->request('get', '/', ['cert' => ['/path/server.pem', 'password']);
|
||||
|
||||
Connection Timeout
|
||||
==================
|
||||
|
||||
By default, CodeIgniter does not impose a limit for cURL to attempt to connect to a website. If you need to
|
||||
modify this value, you can do so by passing the amount of time in seconds with the ``connect_timeout`` option.
|
||||
You can pass 0 to wait indefinitely::
|
||||
|
||||
$response->request('GET', 'http://example.com', ['connect_timeout' => 0]);
|
||||
|
||||
Debug
|
||||
=====
|
||||
|
||||
When ``debug`` is passed and set to ``true``, this will enable additional debugging to echo to STDOUT during the
|
||||
script execution. This is done by passing CURLOPT_VERBOSE and echoing the output::
|
||||
|
||||
$response->request('GET', 'http://example.com', ['debug' => true]);
|
||||
|
||||
You can pass a filename as the value for debug to have the output written to a file::
|
||||
|
||||
$response->request('GET', 'http://example.com', ['debug' => '/usr/local/curl_log.txt']);
|
||||
|
||||
Headers
|
||||
=======
|
||||
|
||||
While you can set any headers this request needs by using the ``setHeader()`` method, you can also pass an associative
|
||||
array of headers in as an option. Each key is the name of a header, and each value is a string or array of strings
|
||||
representing the header field values.::
|
||||
|
||||
$client->request('get', '/', [
|
||||
'headers' => [
|
||||
'User-Agent' => 'testing/1.0',
|
||||
'Accept' => 'application/json',
|
||||
'X-Foo' => ['Bar', 'Baz']
|
||||
]
|
||||
]);
|
||||
|
||||
If headers are passed into the constructor they are treated as default values that will be overridden later by any
|
||||
further headers arrays or calls to ``setHeader()``.
|
||||
|
||||
Timeout
|
||||
=======
|
||||
|
||||
By default, cURL functions are allowed to run as long as they take, with no time limit. You can modify this with the ``timeout``
|
||||
option. The value should be the number of seconds you want the functions to execute for. Use 0 to wait indefinitely::
|
||||
|
||||
$response->request('GET', 'http://example.com', ['timeout' => 5]);
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user