forked from lino/radar-wp
Initial import.
This commit is contained in:
commit
86383280c9
428 changed files with 68738 additions and 0 deletions
464
vendor/guzzle/http/Guzzle/Http/Curl/CurlHandle.php
vendored
Normal file
464
vendor/guzzle/http/Guzzle/Http/Curl/CurlHandle.php
vendored
Normal file
|
@ -0,0 +1,464 @@
|
|||
<?php
|
||||
|
||||
namespace Guzzle\Http\Curl;
|
||||
|
||||
use Guzzle\Common\Exception\InvalidArgumentException;
|
||||
use Guzzle\Common\Exception\RuntimeException;
|
||||
use Guzzle\Common\Collection;
|
||||
use Guzzle\Http\Message\EntityEnclosingRequest;
|
||||
use Guzzle\Http\Message\RequestInterface;
|
||||
use Guzzle\Parser\ParserRegistry;
|
||||
use Guzzle\Http\Url;
|
||||
|
||||
/**
|
||||
* Immutable wrapper for a cURL handle
|
||||
*/
|
||||
class CurlHandle
|
||||
{
|
||||
const BODY_AS_STRING = 'body_as_string';
|
||||
const PROGRESS = 'progress';
|
||||
const DEBUG = 'debug';
|
||||
|
||||
/** @var Collection Curl options */
|
||||
protected $options;
|
||||
|
||||
/** @var resource Curl resource handle */
|
||||
protected $handle;
|
||||
|
||||
/** @var int CURLE_* error */
|
||||
protected $errorNo = CURLE_OK;
|
||||
|
||||
/**
|
||||
* Factory method to create a new curl handle based on an HTTP request.
|
||||
*
|
||||
* There are some helpful options you can set to enable specific behavior:
|
||||
* - debug: Set to true to enable cURL debug functionality to track the actual headers sent over the wire.
|
||||
* - progress: Set to true to enable progress function callbacks.
|
||||
*
|
||||
* @param RequestInterface $request Request
|
||||
*
|
||||
* @return CurlHandle
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public static function factory(RequestInterface $request)
|
||||
{
|
||||
$requestCurlOptions = $request->getCurlOptions();
|
||||
$mediator = new RequestMediator($request, $requestCurlOptions->get('emit_io'));
|
||||
$tempContentLength = null;
|
||||
$method = $request->getMethod();
|
||||
$bodyAsString = $requestCurlOptions->get(self::BODY_AS_STRING);
|
||||
|
||||
// Prepare url
|
||||
$url = (string)$request->getUrl();
|
||||
if(($pos = strpos($url, '#')) !== false ){
|
||||
// strip fragment from url
|
||||
$url = substr($url, 0, $pos);
|
||||
}
|
||||
|
||||
// Array of default cURL options.
|
||||
$curlOptions = array(
|
||||
CURLOPT_URL => $url,
|
||||
CURLOPT_CONNECTTIMEOUT => 150,
|
||||
CURLOPT_RETURNTRANSFER => false,
|
||||
CURLOPT_HEADER => false,
|
||||
CURLOPT_PORT => $request->getPort(),
|
||||
CURLOPT_HTTPHEADER => array(),
|
||||
CURLOPT_WRITEFUNCTION => array($mediator, 'writeResponseBody'),
|
||||
CURLOPT_HEADERFUNCTION => array($mediator, 'receiveResponseHeader'),
|
||||
CURLOPT_HTTP_VERSION => $request->getProtocolVersion() === '1.0'
|
||||
? CURL_HTTP_VERSION_1_0 : CURL_HTTP_VERSION_1_1,
|
||||
// Verifies the authenticity of the peer's certificate
|
||||
CURLOPT_SSL_VERIFYPEER => 1,
|
||||
// Certificate must indicate that the server is the server to which you meant to connect
|
||||
CURLOPT_SSL_VERIFYHOST => 2
|
||||
);
|
||||
|
||||
if (defined('CURLOPT_PROTOCOLS')) {
|
||||
// Allow only HTTP and HTTPS protocols
|
||||
$curlOptions[CURLOPT_PROTOCOLS] = CURLPROTO_HTTP | CURLPROTO_HTTPS;
|
||||
}
|
||||
|
||||
// Add CURLOPT_ENCODING if Accept-Encoding header is provided
|
||||
if ($acceptEncodingHeader = $request->getHeader('Accept-Encoding')) {
|
||||
$curlOptions[CURLOPT_ENCODING] = (string) $acceptEncodingHeader;
|
||||
// Let cURL set the Accept-Encoding header, prevents duplicate values
|
||||
$request->removeHeader('Accept-Encoding');
|
||||
}
|
||||
|
||||
// Enable curl debug information if the 'debug' param was set
|
||||
if ($requestCurlOptions->get('debug')) {
|
||||
$curlOptions[CURLOPT_STDERR] = fopen('php://temp', 'r+');
|
||||
// @codeCoverageIgnoreStart
|
||||
if (false === $curlOptions[CURLOPT_STDERR]) {
|
||||
throw new RuntimeException('Unable to create a stream for CURLOPT_STDERR');
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
$curlOptions[CURLOPT_VERBOSE] = true;
|
||||
}
|
||||
|
||||
// Specify settings according to the HTTP method
|
||||
if ($method == 'GET') {
|
||||
$curlOptions[CURLOPT_HTTPGET] = true;
|
||||
} elseif ($method == 'HEAD') {
|
||||
$curlOptions[CURLOPT_NOBODY] = true;
|
||||
// HEAD requests do not use a write function
|
||||
unset($curlOptions[CURLOPT_WRITEFUNCTION]);
|
||||
} elseif (!($request instanceof EntityEnclosingRequest)) {
|
||||
$curlOptions[CURLOPT_CUSTOMREQUEST] = $method;
|
||||
} else {
|
||||
|
||||
$curlOptions[CURLOPT_CUSTOMREQUEST] = $method;
|
||||
|
||||
// Handle sending raw bodies in a request
|
||||
if ($request->getBody()) {
|
||||
// You can send the body as a string using curl's CURLOPT_POSTFIELDS
|
||||
if ($bodyAsString) {
|
||||
$curlOptions[CURLOPT_POSTFIELDS] = (string) $request->getBody();
|
||||
// Allow curl to add the Content-Length for us to account for the times when
|
||||
// POST redirects are followed by GET requests
|
||||
if ($tempContentLength = $request->getHeader('Content-Length')) {
|
||||
$tempContentLength = (int) (string) $tempContentLength;
|
||||
}
|
||||
// Remove the curl generated Content-Type header if none was set manually
|
||||
if (!$request->hasHeader('Content-Type')) {
|
||||
$curlOptions[CURLOPT_HTTPHEADER][] = 'Content-Type:';
|
||||
}
|
||||
} else {
|
||||
$curlOptions[CURLOPT_UPLOAD] = true;
|
||||
// Let cURL handle setting the Content-Length header
|
||||
if ($tempContentLength = $request->getHeader('Content-Length')) {
|
||||
$tempContentLength = (int) (string) $tempContentLength;
|
||||
$curlOptions[CURLOPT_INFILESIZE] = $tempContentLength;
|
||||
}
|
||||
// Add a callback for curl to read data to send with the request only if a body was specified
|
||||
$curlOptions[CURLOPT_READFUNCTION] = array($mediator, 'readRequestBody');
|
||||
// Attempt to seek to the start of the stream
|
||||
$request->getBody()->seek(0);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// Special handling for POST specific fields and files
|
||||
$postFields = false;
|
||||
if (count($request->getPostFiles())) {
|
||||
$postFields = $request->getPostFields()->useUrlEncoding(false)->urlEncode();
|
||||
foreach ($request->getPostFiles() as $key => $data) {
|
||||
$prefixKeys = count($data) > 1;
|
||||
foreach ($data as $index => $file) {
|
||||
// Allow multiple files in the same key
|
||||
$fieldKey = $prefixKeys ? "{$key}[{$index}]" : $key;
|
||||
$postFields[$fieldKey] = $file->getCurlValue();
|
||||
}
|
||||
}
|
||||
} elseif (count($request->getPostFields())) {
|
||||
$postFields = (string) $request->getPostFields()->useUrlEncoding(true);
|
||||
}
|
||||
|
||||
if ($postFields !== false) {
|
||||
if ($method == 'POST') {
|
||||
unset($curlOptions[CURLOPT_CUSTOMREQUEST]);
|
||||
$curlOptions[CURLOPT_POST] = true;
|
||||
}
|
||||
$curlOptions[CURLOPT_POSTFIELDS] = $postFields;
|
||||
$request->removeHeader('Content-Length');
|
||||
}
|
||||
}
|
||||
|
||||
// If the Expect header is not present, prevent curl from adding it
|
||||
if (!$request->hasHeader('Expect')) {
|
||||
$curlOptions[CURLOPT_HTTPHEADER][] = 'Expect:';
|
||||
}
|
||||
}
|
||||
|
||||
// If a Content-Length header was specified but we want to allow curl to set one for us
|
||||
if (null !== $tempContentLength) {
|
||||
$request->removeHeader('Content-Length');
|
||||
}
|
||||
|
||||
// Set custom cURL options
|
||||
foreach ($requestCurlOptions->toArray() as $key => $value) {
|
||||
if (is_numeric($key)) {
|
||||
$curlOptions[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
// Do not set an Accept header by default
|
||||
if (!isset($curlOptions[CURLOPT_ENCODING])) {
|
||||
$curlOptions[CURLOPT_HTTPHEADER][] = 'Accept:';
|
||||
}
|
||||
|
||||
// Add any custom headers to the request. Empty headers will cause curl to not send the header at all.
|
||||
foreach ($request->getHeaderLines() as $line) {
|
||||
$curlOptions[CURLOPT_HTTPHEADER][] = $line;
|
||||
}
|
||||
|
||||
// Add the content-length header back if it was temporarily removed
|
||||
if ($tempContentLength) {
|
||||
$request->setHeader('Content-Length', $tempContentLength);
|
||||
}
|
||||
|
||||
// Apply the options to a new cURL handle.
|
||||
$handle = curl_init();
|
||||
|
||||
// Enable the progress function if the 'progress' param was set
|
||||
if ($requestCurlOptions->get('progress')) {
|
||||
// Wrap the function in a function that provides the curl handle to the mediator's progress function
|
||||
// Using this rather than injecting the handle into the mediator prevents a circular reference
|
||||
$curlOptions[CURLOPT_PROGRESSFUNCTION] = function () use ($mediator, $handle) {
|
||||
$args = func_get_args();
|
||||
$args[] = $handle;
|
||||
|
||||
// PHP 5.5 pushed the handle onto the start of the args
|
||||
if (is_resource($args[0])) {
|
||||
array_shift($args);
|
||||
}
|
||||
|
||||
call_user_func_array(array($mediator, 'progress'), $args);
|
||||
};
|
||||
$curlOptions[CURLOPT_NOPROGRESS] = false;
|
||||
}
|
||||
|
||||
curl_setopt_array($handle, $curlOptions);
|
||||
|
||||
return new static($handle, $curlOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new CurlHandle object that wraps a cURL handle
|
||||
*
|
||||
* @param resource $handle Configured cURL handle resource
|
||||
* @param Collection|array $options Curl options to use with the handle
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function __construct($handle, $options)
|
||||
{
|
||||
if (!is_resource($handle)) {
|
||||
throw new InvalidArgumentException('Invalid handle provided');
|
||||
}
|
||||
if (is_array($options)) {
|
||||
$this->options = new Collection($options);
|
||||
} elseif ($options instanceof Collection) {
|
||||
$this->options = $options;
|
||||
} else {
|
||||
throw new InvalidArgumentException('Expected array or Collection');
|
||||
}
|
||||
$this->handle = $handle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the curl handle
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
if (is_resource($this->handle)) {
|
||||
curl_close($this->handle);
|
||||
}
|
||||
$this->handle = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the handle is available and still OK
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isAvailable()
|
||||
{
|
||||
return is_resource($this->handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the last error that occurred on the cURL handle
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getError()
|
||||
{
|
||||
return $this->isAvailable() ? curl_error($this->handle) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the last error number that occurred on the cURL handle
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getErrorNo()
|
||||
{
|
||||
if ($this->errorNo) {
|
||||
return $this->errorNo;
|
||||
}
|
||||
|
||||
return $this->isAvailable() ? curl_errno($this->handle) : CURLE_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the curl error number
|
||||
*
|
||||
* @param int $error Error number to set
|
||||
*
|
||||
* @return CurlHandle
|
||||
*/
|
||||
public function setErrorNo($error)
|
||||
{
|
||||
$this->errorNo = $error;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cURL curl_getinfo data
|
||||
*
|
||||
* @param int $option Option to retrieve. Pass null to retrieve all data as an array.
|
||||
*
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function getInfo($option = null)
|
||||
{
|
||||
if (!is_resource($this->handle)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (null !== $option) {
|
||||
return curl_getinfo($this->handle, $option) ?: null;
|
||||
}
|
||||
|
||||
return curl_getinfo($this->handle) ?: array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the stderr output
|
||||
*
|
||||
* @param bool $asResource Set to TRUE to get an fopen resource
|
||||
*
|
||||
* @return string|resource|null
|
||||
*/
|
||||
public function getStderr($asResource = false)
|
||||
{
|
||||
$stderr = $this->getOptions()->get(CURLOPT_STDERR);
|
||||
if (!$stderr) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($asResource) {
|
||||
return $stderr;
|
||||
}
|
||||
|
||||
fseek($stderr, 0);
|
||||
$e = stream_get_contents($stderr);
|
||||
fseek($stderr, 0, SEEK_END);
|
||||
|
||||
return $e;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the URL that this handle is connecting to
|
||||
*
|
||||
* @return Url
|
||||
*/
|
||||
public function getUrl()
|
||||
{
|
||||
return Url::factory($this->options->get(CURLOPT_URL));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the wrapped curl handle
|
||||
*
|
||||
* @return resource|null Returns the cURL handle or null if it was closed
|
||||
*/
|
||||
public function getHandle()
|
||||
{
|
||||
return $this->isAvailable() ? $this->handle : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cURL setopt options of the handle. Changing values in the return object will have no effect on the curl
|
||||
* handle after it is created.
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getOptions()
|
||||
{
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a request based on the log messages of the CurlHandle
|
||||
*
|
||||
* @param RequestInterface $request Request to update
|
||||
*/
|
||||
public function updateRequestFromTransfer(RequestInterface $request)
|
||||
{
|
||||
if (!$request->getResponse()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the transfer stats of the response
|
||||
$request->getResponse()->setInfo($this->getInfo());
|
||||
|
||||
if (!$log = $this->getStderr(true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse the cURL stderr output for outgoing requests
|
||||
$headers = '';
|
||||
fseek($log, 0);
|
||||
while (($line = fgets($log)) !== false) {
|
||||
if ($line && $line[0] == '>') {
|
||||
$headers = substr(trim($line), 2) . "\r\n";
|
||||
while (($line = fgets($log)) !== false) {
|
||||
if ($line[0] == '*' || $line[0] == '<') {
|
||||
break;
|
||||
} else {
|
||||
$headers .= trim($line) . "\r\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add request headers to the request exactly as they were sent
|
||||
if ($headers) {
|
||||
$parsed = ParserRegistry::getInstance()->getParser('message')->parseRequest($headers);
|
||||
if (!empty($parsed['headers'])) {
|
||||
$request->setHeaders(array());
|
||||
foreach ($parsed['headers'] as $name => $value) {
|
||||
$request->setHeader($name, $value);
|
||||
}
|
||||
}
|
||||
if (!empty($parsed['version'])) {
|
||||
$request->setProtocolVersion($parsed['version']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the config and replace curl.* configurators into the constant based values so it can be used elsewhere
|
||||
*
|
||||
* @param array|Collection $config The configuration we want to parse
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function parseCurlConfig($config)
|
||||
{
|
||||
$curlOptions = array();
|
||||
foreach ($config as $key => $value) {
|
||||
if (is_string($key) && defined($key)) {
|
||||
// Convert constants represented as string to constant int values
|
||||
$key = constant($key);
|
||||
}
|
||||
if (is_string($value) && defined($value)) {
|
||||
$value = constant($value);
|
||||
}
|
||||
$curlOptions[$key] = $value;
|
||||
}
|
||||
|
||||
return $curlOptions;
|
||||
}
|
||||
}
|
423
vendor/guzzle/http/Guzzle/Http/Curl/CurlMulti.php
vendored
Normal file
423
vendor/guzzle/http/Guzzle/Http/Curl/CurlMulti.php
vendored
Normal file
|
@ -0,0 +1,423 @@
|
|||
<?php
|
||||
|
||||
namespace Guzzle\Http\Curl;
|
||||
|
||||
use Guzzle\Common\AbstractHasDispatcher;
|
||||
use Guzzle\Common\Event;
|
||||
use Guzzle\Http\Exception\MultiTransferException;
|
||||
use Guzzle\Http\Exception\CurlException;
|
||||
use Guzzle\Http\Message\RequestInterface;
|
||||
use Guzzle\Http\Message\EntityEnclosingRequestInterface;
|
||||
use Guzzle\Http\Exception\RequestException;
|
||||
|
||||
/**
|
||||
* Send {@see RequestInterface} objects in parallel using curl_multi
|
||||
*/
|
||||
class CurlMulti extends AbstractHasDispatcher implements CurlMultiInterface
|
||||
{
|
||||
/** @var resource cURL multi handle. */
|
||||
protected $multiHandle;
|
||||
|
||||
/** @var array Attached {@see RequestInterface} objects. */
|
||||
protected $requests;
|
||||
|
||||
/** @var \SplObjectStorage RequestInterface to CurlHandle hash */
|
||||
protected $handles;
|
||||
|
||||
/** @var array Hash mapping curl handle resource IDs to request objects */
|
||||
protected $resourceHash;
|
||||
|
||||
/** @var array Queued exceptions */
|
||||
protected $exceptions = array();
|
||||
|
||||
/** @var array Requests that succeeded */
|
||||
protected $successful = array();
|
||||
|
||||
/** @var array cURL multi error values and codes */
|
||||
protected $multiErrors = array(
|
||||
CURLM_BAD_HANDLE => array('CURLM_BAD_HANDLE', 'The passed-in handle is not a valid CURLM handle.'),
|
||||
CURLM_BAD_EASY_HANDLE => array('CURLM_BAD_EASY_HANDLE', "An easy handle was not good/valid. It could mean that it isn't an easy handle at all, or possibly that the handle already is in used by this or another multi handle."),
|
||||
CURLM_OUT_OF_MEMORY => array('CURLM_OUT_OF_MEMORY', 'You are doomed.'),
|
||||
CURLM_INTERNAL_ERROR => array('CURLM_INTERNAL_ERROR', 'This can only be returned if libcurl bugs. Please report it to us!')
|
||||
);
|
||||
|
||||
/** @var float */
|
||||
protected $selectTimeout;
|
||||
|
||||
public function __construct($selectTimeout = 1.0)
|
||||
{
|
||||
$this->selectTimeout = $selectTimeout;
|
||||
$this->multiHandle = curl_multi_init();
|
||||
// @codeCoverageIgnoreStart
|
||||
if ($this->multiHandle === false) {
|
||||
throw new CurlException('Unable to create multi handle');
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
$this->reset();
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
if (is_resource($this->multiHandle)) {
|
||||
curl_multi_close($this->multiHandle);
|
||||
}
|
||||
}
|
||||
|
||||
public function add(RequestInterface $request)
|
||||
{
|
||||
$this->requests[] = $request;
|
||||
// If requests are currently transferring and this is async, then the
|
||||
// request must be prepared now as the send() method is not called.
|
||||
$this->beforeSend($request);
|
||||
$this->dispatch(self::ADD_REQUEST, array('request' => $request));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function all()
|
||||
{
|
||||
return $this->requests;
|
||||
}
|
||||
|
||||
public function remove(RequestInterface $request)
|
||||
{
|
||||
$this->removeHandle($request);
|
||||
if (($index = array_search($request, $this->requests, true)) !== false) {
|
||||
$request = $this->requests[$index];
|
||||
unset($this->requests[$index]);
|
||||
$this->requests = array_values($this->requests);
|
||||
$this->dispatch(self::REMOVE_REQUEST, array('request' => $request));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function reset($hard = false)
|
||||
{
|
||||
// Remove each request
|
||||
if ($this->requests) {
|
||||
foreach ($this->requests as $request) {
|
||||
$this->remove($request);
|
||||
}
|
||||
}
|
||||
|
||||
$this->handles = new \SplObjectStorage();
|
||||
$this->requests = $this->resourceHash = $this->exceptions = $this->successful = array();
|
||||
}
|
||||
|
||||
public function send()
|
||||
{
|
||||
$this->perform();
|
||||
$exceptions = $this->exceptions;
|
||||
$successful = $this->successful;
|
||||
$this->reset();
|
||||
|
||||
if ($exceptions) {
|
||||
$this->throwMultiException($exceptions, $successful);
|
||||
}
|
||||
}
|
||||
|
||||
public function count()
|
||||
{
|
||||
return count($this->requests);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build and throw a MultiTransferException
|
||||
*
|
||||
* @param array $exceptions Exceptions encountered
|
||||
* @param array $successful Successful requests
|
||||
* @throws MultiTransferException
|
||||
*/
|
||||
protected function throwMultiException(array $exceptions, array $successful)
|
||||
{
|
||||
$multiException = new MultiTransferException('Errors during multi transfer');
|
||||
|
||||
while ($e = array_shift($exceptions)) {
|
||||
$multiException->addFailedRequestWithException($e['request'], $e['exception']);
|
||||
}
|
||||
|
||||
// Add successful requests
|
||||
foreach ($successful as $request) {
|
||||
if (!$multiException->containsRequest($request)) {
|
||||
$multiException->addSuccessfulRequest($request);
|
||||
}
|
||||
}
|
||||
|
||||
throw $multiException;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare for sending
|
||||
*
|
||||
* @param RequestInterface $request Request to prepare
|
||||
* @throws \Exception on error preparing the request
|
||||
*/
|
||||
protected function beforeSend(RequestInterface $request)
|
||||
{
|
||||
try {
|
||||
$state = $request->setState(RequestInterface::STATE_TRANSFER);
|
||||
if ($state == RequestInterface::STATE_TRANSFER) {
|
||||
$this->addHandle($request);
|
||||
} else {
|
||||
// Requests might decide they don't need to be sent just before
|
||||
// transfer (e.g. CachePlugin)
|
||||
$this->remove($request);
|
||||
if ($state == RequestInterface::STATE_COMPLETE) {
|
||||
$this->successful[] = $request;
|
||||
}
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
// Queue the exception to be thrown when sent
|
||||
$this->removeErroredRequest($request, $e);
|
||||
}
|
||||
}
|
||||
|
||||
private function addHandle(RequestInterface $request)
|
||||
{
|
||||
$handle = $this->createCurlHandle($request)->getHandle();
|
||||
$this->checkCurlResult(
|
||||
curl_multi_add_handle($this->multiHandle, $handle)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a curl handle for a request
|
||||
*
|
||||
* @param RequestInterface $request Request
|
||||
*
|
||||
* @return CurlHandle
|
||||
*/
|
||||
protected function createCurlHandle(RequestInterface $request)
|
||||
{
|
||||
$wrapper = CurlHandle::factory($request);
|
||||
$this->handles[$request] = $wrapper;
|
||||
$this->resourceHash[(int) $wrapper->getHandle()] = $request;
|
||||
|
||||
return $wrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data from the multi handle
|
||||
*/
|
||||
protected function perform()
|
||||
{
|
||||
$event = new Event(array('curl_multi' => $this));
|
||||
|
||||
while ($this->requests) {
|
||||
// Notify each request as polling
|
||||
$blocking = $total = 0;
|
||||
foreach ($this->requests as $request) {
|
||||
++$total;
|
||||
$event['request'] = $request;
|
||||
$request->getEventDispatcher()->dispatch(self::POLLING_REQUEST, $event);
|
||||
// The blocking variable just has to be non-falsey to block the loop
|
||||
if ($request->getParams()->hasKey(self::BLOCKING)) {
|
||||
++$blocking;
|
||||
}
|
||||
}
|
||||
if ($blocking == $total) {
|
||||
// Sleep to prevent eating CPU because no requests are actually pending a select call
|
||||
usleep(500);
|
||||
} else {
|
||||
$this->executeHandles();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute and select curl handles
|
||||
*/
|
||||
private function executeHandles()
|
||||
{
|
||||
// The first curl_multi_select often times out no matter what, but is usually required for fast transfers
|
||||
$selectTimeout = 0.001;
|
||||
$active = false;
|
||||
do {
|
||||
while (($mrc = curl_multi_exec($this->multiHandle, $active)) == CURLM_CALL_MULTI_PERFORM);
|
||||
$this->checkCurlResult($mrc);
|
||||
$this->processMessages();
|
||||
if ($active && curl_multi_select($this->multiHandle, $selectTimeout) === -1) {
|
||||
// Perform a usleep if a select returns -1: https://bugs.php.net/bug.php?id=61141
|
||||
usleep(150);
|
||||
}
|
||||
$selectTimeout = $this->selectTimeout;
|
||||
} while ($active);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process any received curl multi messages
|
||||
*/
|
||||
private function processMessages()
|
||||
{
|
||||
while ($done = curl_multi_info_read($this->multiHandle)) {
|
||||
$request = $this->resourceHash[(int) $done['handle']];
|
||||
try {
|
||||
$this->processResponse($request, $this->handles[$request], $done);
|
||||
$this->successful[] = $request;
|
||||
} catch (\Exception $e) {
|
||||
$this->removeErroredRequest($request, $e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a request that encountered an exception
|
||||
*
|
||||
* @param RequestInterface $request Request to remove
|
||||
* @param \Exception $e Exception encountered
|
||||
*/
|
||||
protected function removeErroredRequest(RequestInterface $request, \Exception $e = null)
|
||||
{
|
||||
$this->exceptions[] = array('request' => $request, 'exception' => $e);
|
||||
$this->remove($request);
|
||||
$this->dispatch(self::MULTI_EXCEPTION, array('exception' => $e, 'all_exceptions' => $this->exceptions));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for errors and fix headers of a request based on a curl response
|
||||
*
|
||||
* @param RequestInterface $request Request to process
|
||||
* @param CurlHandle $handle Curl handle object
|
||||
* @param array $curl Array returned from curl_multi_info_read
|
||||
*
|
||||
* @throws CurlException on Curl error
|
||||
*/
|
||||
protected function processResponse(RequestInterface $request, CurlHandle $handle, array $curl)
|
||||
{
|
||||
// Set the transfer stats on the response
|
||||
$handle->updateRequestFromTransfer($request);
|
||||
// Check if a cURL exception occurred, and if so, notify things
|
||||
$curlException = $this->isCurlException($request, $handle, $curl);
|
||||
|
||||
// Always remove completed curl handles. They can be added back again
|
||||
// via events if needed (e.g. ExponentialBackoffPlugin)
|
||||
$this->removeHandle($request);
|
||||
|
||||
if (!$curlException) {
|
||||
if ($this->validateResponseWasSet($request)) {
|
||||
$state = $request->setState(
|
||||
RequestInterface::STATE_COMPLETE,
|
||||
array('handle' => $handle)
|
||||
);
|
||||
// Only remove the request if it wasn't resent as a result of
|
||||
// the state change
|
||||
if ($state != RequestInterface::STATE_TRANSFER) {
|
||||
$this->remove($request);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the state of the request to an error
|
||||
$state = $request->setState(RequestInterface::STATE_ERROR, array('exception' => $curlException));
|
||||
// Allow things to ignore the error if possible
|
||||
if ($state != RequestInterface::STATE_TRANSFER) {
|
||||
$this->remove($request);
|
||||
}
|
||||
|
||||
// The error was not handled, so fail
|
||||
if ($state == RequestInterface::STATE_ERROR) {
|
||||
/** @var CurlException $curlException */
|
||||
throw $curlException;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a curl handle from the curl multi object
|
||||
*
|
||||
* @param RequestInterface $request Request that owns the handle
|
||||
*/
|
||||
protected function removeHandle(RequestInterface $request)
|
||||
{
|
||||
if (isset($this->handles[$request])) {
|
||||
$handle = $this->handles[$request];
|
||||
curl_multi_remove_handle($this->multiHandle, $handle->getHandle());
|
||||
unset($this->handles[$request]);
|
||||
unset($this->resourceHash[(int) $handle->getHandle()]);
|
||||
$handle->close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a cURL transfer resulted in what should be an exception
|
||||
*
|
||||
* @param RequestInterface $request Request to check
|
||||
* @param CurlHandle $handle Curl handle object
|
||||
* @param array $curl Array returned from curl_multi_info_read
|
||||
*
|
||||
* @return CurlException|bool
|
||||
*/
|
||||
private function isCurlException(RequestInterface $request, CurlHandle $handle, array $curl)
|
||||
{
|
||||
if (CURLM_OK == $curl['result'] || CURLM_CALL_MULTI_PERFORM == $curl['result']) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$handle->setErrorNo($curl['result']);
|
||||
$e = new CurlException(sprintf('[curl] %s: %s [url] %s',
|
||||
$handle->getErrorNo(), $handle->getError(), $handle->getUrl()));
|
||||
$e->setCurlHandle($handle)
|
||||
->setRequest($request)
|
||||
->setCurlInfo($handle->getInfo())
|
||||
->setError($handle->getError(), $handle->getErrorNo());
|
||||
|
||||
return $e;
|
||||
}
|
||||
|
||||
/**
|
||||
* Throw an exception for a cURL multi response if needed
|
||||
*
|
||||
* @param int $code Curl response code
|
||||
* @throws CurlException
|
||||
*/
|
||||
private function checkCurlResult($code)
|
||||
{
|
||||
if ($code != CURLM_OK && $code != CURLM_CALL_MULTI_PERFORM) {
|
||||
throw new CurlException(isset($this->multiErrors[$code])
|
||||
? "cURL error: {$code} ({$this->multiErrors[$code][0]}): cURL message: {$this->multiErrors[$code][1]}"
|
||||
: 'Unexpected cURL error: ' . $code
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://github.com/guzzle/guzzle/issues/710
|
||||
*/
|
||||
private function validateResponseWasSet(RequestInterface $request)
|
||||
{
|
||||
if ($request->getResponse()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$body = $request instanceof EntityEnclosingRequestInterface
|
||||
? $request->getBody()
|
||||
: null;
|
||||
|
||||
if (!$body) {
|
||||
$rex = new RequestException(
|
||||
'No response was received for a request with no body. This'
|
||||
. ' could mean that you are saturating your network.'
|
||||
);
|
||||
$rex->setRequest($request);
|
||||
$this->removeErroredRequest($request, $rex);
|
||||
} elseif (!$body->isSeekable() || !$body->seek(0)) {
|
||||
// Nothing we can do with this. Sorry!
|
||||
$rex = new RequestException(
|
||||
'The connection was unexpectedly closed. The request would'
|
||||
. ' have been retried, but attempting to rewind the'
|
||||
. ' request body failed.'
|
||||
);
|
||||
$rex->setRequest($request);
|
||||
$this->removeErroredRequest($request, $rex);
|
||||
} else {
|
||||
$this->remove($request);
|
||||
// Add the request back to the batch to retry automatically.
|
||||
$this->requests[] = $request;
|
||||
$this->addHandle($request);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
58
vendor/guzzle/http/Guzzle/Http/Curl/CurlMultiInterface.php
vendored
Normal file
58
vendor/guzzle/http/Guzzle/Http/Curl/CurlMultiInterface.php
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
namespace Guzzle\Http\Curl;
|
||||
|
||||
use Guzzle\Common\HasDispatcherInterface;
|
||||
use Guzzle\Common\Exception\ExceptionCollection;
|
||||
use Guzzle\Http\Message\RequestInterface;
|
||||
|
||||
/**
|
||||
* Interface for sending a pool of {@see RequestInterface} objects in parallel
|
||||
*/
|
||||
interface CurlMultiInterface extends \Countable, HasDispatcherInterface
|
||||
{
|
||||
const POLLING_REQUEST = 'curl_multi.polling_request';
|
||||
const ADD_REQUEST = 'curl_multi.add_request';
|
||||
const REMOVE_REQUEST = 'curl_multi.remove_request';
|
||||
const MULTI_EXCEPTION = 'curl_multi.exception';
|
||||
const BLOCKING = 'curl_multi.blocking';
|
||||
|
||||
/**
|
||||
* Add a request to the pool.
|
||||
*
|
||||
* @param RequestInterface $request Request to add
|
||||
*
|
||||
* @return CurlMultiInterface
|
||||
*/
|
||||
public function add(RequestInterface $request);
|
||||
|
||||
/**
|
||||
* Get an array of attached {@see RequestInterface} objects
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function all();
|
||||
|
||||
/**
|
||||
* Remove a request from the pool.
|
||||
*
|
||||
* @param RequestInterface $request Request to remove
|
||||
*
|
||||
* @return bool Returns true on success or false on failure
|
||||
*/
|
||||
public function remove(RequestInterface $request);
|
||||
|
||||
/**
|
||||
* Reset the state and remove any attached RequestInterface objects
|
||||
*
|
||||
* @param bool $hard Set to true to close and reopen any open multi handles
|
||||
*/
|
||||
public function reset($hard = false);
|
||||
|
||||
/**
|
||||
* Send a pool of {@see RequestInterface} requests.
|
||||
*
|
||||
* @throws ExceptionCollection if any requests threw exceptions during the transfer.
|
||||
*/
|
||||
public function send();
|
||||
}
|
150
vendor/guzzle/http/Guzzle/Http/Curl/CurlMultiProxy.php
vendored
Normal file
150
vendor/guzzle/http/Guzzle/Http/Curl/CurlMultiProxy.php
vendored
Normal file
|
@ -0,0 +1,150 @@
|
|||
<?php
|
||||
|
||||
namespace Guzzle\Http\Curl;
|
||||
|
||||
use Guzzle\Common\AbstractHasDispatcher;
|
||||
use Guzzle\Http\Message\RequestInterface;
|
||||
|
||||
/**
|
||||
* Proxies requests and connections to a pool of internal curl_multi handles. Each recursive call will add requests
|
||||
* to the next available CurlMulti handle.
|
||||
*/
|
||||
class CurlMultiProxy extends AbstractHasDispatcher implements CurlMultiInterface
|
||||
{
|
||||
protected $handles = array();
|
||||
protected $groups = array();
|
||||
protected $queued = array();
|
||||
protected $maxHandles;
|
||||
protected $selectTimeout;
|
||||
|
||||
/**
|
||||
* @param int $maxHandles The maximum number of idle CurlMulti handles to allow to remain open
|
||||
* @param float $selectTimeout timeout for curl_multi_select
|
||||
*/
|
||||
public function __construct($maxHandles = 3, $selectTimeout = 1.0)
|
||||
{
|
||||
$this->maxHandles = $maxHandles;
|
||||
$this->selectTimeout = $selectTimeout;
|
||||
// You can get some weird "Too many open files" errors when sending a large amount of requests in parallel.
|
||||
// These two statements autoload classes before a system runs out of file descriptors so that you can get back
|
||||
// valuable error messages if you run out.
|
||||
class_exists('Guzzle\Http\Message\Response');
|
||||
class_exists('Guzzle\Http\Exception\CurlException');
|
||||
}
|
||||
|
||||
public function add(RequestInterface $request)
|
||||
{
|
||||
$this->queued[] = $request;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function all()
|
||||
{
|
||||
$requests = $this->queued;
|
||||
foreach ($this->handles as $handle) {
|
||||
$requests = array_merge($requests, $handle->all());
|
||||
}
|
||||
|
||||
return $requests;
|
||||
}
|
||||
|
||||
public function remove(RequestInterface $request)
|
||||
{
|
||||
foreach ($this->queued as $i => $r) {
|
||||
if ($request === $r) {
|
||||
unset($this->queued[$i]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->handles as $handle) {
|
||||
if ($handle->remove($request)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function reset($hard = false)
|
||||
{
|
||||
$this->queued = array();
|
||||
$this->groups = array();
|
||||
foreach ($this->handles as $handle) {
|
||||
$handle->reset();
|
||||
}
|
||||
if ($hard) {
|
||||
$this->handles = array();
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function send()
|
||||
{
|
||||
if ($this->queued) {
|
||||
$group = $this->getAvailableHandle();
|
||||
// Add this handle to a list of handles than is claimed
|
||||
$this->groups[] = $group;
|
||||
while ($request = array_shift($this->queued)) {
|
||||
$group->add($request);
|
||||
}
|
||||
try {
|
||||
$group->send();
|
||||
array_pop($this->groups);
|
||||
$this->cleanupHandles();
|
||||
} catch (\Exception $e) {
|
||||
// Remove the group and cleanup if an exception was encountered and no more requests in group
|
||||
if (!$group->count()) {
|
||||
array_pop($this->groups);
|
||||
$this->cleanupHandles();
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function count()
|
||||
{
|
||||
return count($this->all());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an existing available CurlMulti handle or create a new one
|
||||
*
|
||||
* @return CurlMulti
|
||||
*/
|
||||
protected function getAvailableHandle()
|
||||
{
|
||||
// Grab a handle that is not claimed
|
||||
foreach ($this->handles as $h) {
|
||||
if (!in_array($h, $this->groups, true)) {
|
||||
return $h;
|
||||
}
|
||||
}
|
||||
|
||||
// All are claimed, so create one
|
||||
$handle = new CurlMulti($this->selectTimeout);
|
||||
$handle->setEventDispatcher($this->getEventDispatcher());
|
||||
$this->handles[] = $handle;
|
||||
|
||||
return $handle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trims down unused CurlMulti handles to limit the number of open connections
|
||||
*/
|
||||
protected function cleanupHandles()
|
||||
{
|
||||
if ($diff = max(0, count($this->handles) - $this->maxHandles)) {
|
||||
for ($i = count($this->handles) - 1; $i > 0 && $diff > 0; $i--) {
|
||||
if (!count($this->handles[$i])) {
|
||||
unset($this->handles[$i]);
|
||||
$diff--;
|
||||
}
|
||||
}
|
||||
$this->handles = array_values($this->handles);
|
||||
}
|
||||
}
|
||||
}
|
66
vendor/guzzle/http/Guzzle/Http/Curl/CurlVersion.php
vendored
Normal file
66
vendor/guzzle/http/Guzzle/Http/Curl/CurlVersion.php
vendored
Normal file
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
namespace Guzzle\Http\Curl;
|
||||
|
||||
/**
|
||||
* Class used for querying curl_version data
|
||||
*/
|
||||
class CurlVersion
|
||||
{
|
||||
/** @var array curl_version() information */
|
||||
protected $version;
|
||||
|
||||
/** @var CurlVersion */
|
||||
protected static $instance;
|
||||
|
||||
/** @var string Default user agent */
|
||||
protected $userAgent;
|
||||
|
||||
/**
|
||||
* @return CurlVersion
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
if (!self::$instance) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the curl_version() data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAll()
|
||||
{
|
||||
if (!$this->version) {
|
||||
$this->version = curl_version();
|
||||
}
|
||||
|
||||
return $this->version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specific type of curl information
|
||||
*
|
||||
* @param string $type Version information to retrieve. This value is one of:
|
||||
* - version_number: cURL 24 bit version number
|
||||
* - version: cURL version number, as a string
|
||||
* - ssl_version_number: OpenSSL 24 bit version number
|
||||
* - ssl_version: OpenSSL version number, as a string
|
||||
* - libz_version: zlib version number, as a string
|
||||
* - host: Information about the host where cURL was built
|
||||
* - features: A bitmask of the CURL_VERSION_XXX constants
|
||||
* - protocols: An array of protocols names supported by cURL
|
||||
*
|
||||
* @return string|float|bool if the $type is found, and false if not found
|
||||
*/
|
||||
public function get($type)
|
||||
{
|
||||
$version = $this->getAll();
|
||||
|
||||
return isset($version[$type]) ? $version[$type] : false;
|
||||
}
|
||||
}
|
147
vendor/guzzle/http/Guzzle/Http/Curl/RequestMediator.php
vendored
Normal file
147
vendor/guzzle/http/Guzzle/Http/Curl/RequestMediator.php
vendored
Normal file
|
@ -0,0 +1,147 @@
|
|||
<?php
|
||||
|
||||
namespace Guzzle\Http\Curl;
|
||||
|
||||
use Guzzle\Http\Message\RequestInterface;
|
||||
use Guzzle\Http\EntityBody;
|
||||
use Guzzle\Http\Message\Response;
|
||||
|
||||
/**
|
||||
* Mediator between curl handles and request objects
|
||||
*/
|
||||
class RequestMediator
|
||||
{
|
||||
/** @var RequestInterface */
|
||||
protected $request;
|
||||
|
||||
/** @var bool Whether or not to emit read/write events */
|
||||
protected $emitIo;
|
||||
|
||||
/**
|
||||
* @param RequestInterface $request Request to mediate
|
||||
* @param bool $emitIo Set to true to dispatch events on input and output
|
||||
*/
|
||||
public function __construct(RequestInterface $request, $emitIo = false)
|
||||
{
|
||||
$this->request = $request;
|
||||
$this->emitIo = $emitIo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive a response header from curl
|
||||
*
|
||||
* @param resource $curl Curl handle
|
||||
* @param string $header Received header
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function receiveResponseHeader($curl, $header)
|
||||
{
|
||||
static $normalize = array("\r", "\n");
|
||||
$length = strlen($header);
|
||||
$header = str_replace($normalize, '', $header);
|
||||
|
||||
if (strpos($header, 'HTTP/') === 0) {
|
||||
|
||||
$startLine = explode(' ', $header, 3);
|
||||
$code = $startLine[1];
|
||||
$status = isset($startLine[2]) ? $startLine[2] : '';
|
||||
|
||||
// Only download the body of the response to the specified response
|
||||
// body when a successful response is received.
|
||||
if ($code >= 200 && $code < 300) {
|
||||
$body = $this->request->getResponseBody();
|
||||
} else {
|
||||
$body = EntityBody::factory();
|
||||
}
|
||||
|
||||
$response = new Response($code, null, $body);
|
||||
$response->setStatus($code, $status);
|
||||
$this->request->startResponse($response);
|
||||
|
||||
$this->request->dispatch('request.receive.status_line', array(
|
||||
'request' => $this,
|
||||
'line' => $header,
|
||||
'status_code' => $code,
|
||||
'reason_phrase' => $status
|
||||
));
|
||||
|
||||
} elseif ($pos = strpos($header, ':')) {
|
||||
$this->request->getResponse()->addHeader(
|
||||
trim(substr($header, 0, $pos)),
|
||||
trim(substr($header, $pos + 1))
|
||||
);
|
||||
}
|
||||
|
||||
return $length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Received a progress notification
|
||||
*
|
||||
* @param int $downloadSize Total download size
|
||||
* @param int $downloaded Amount of bytes downloaded
|
||||
* @param int $uploadSize Total upload size
|
||||
* @param int $uploaded Amount of bytes uploaded
|
||||
* @param resource $handle CurlHandle object
|
||||
*/
|
||||
public function progress($downloadSize, $downloaded, $uploadSize, $uploaded, $handle = null)
|
||||
{
|
||||
$this->request->dispatch('curl.callback.progress', array(
|
||||
'request' => $this->request,
|
||||
'handle' => $handle,
|
||||
'download_size' => $downloadSize,
|
||||
'downloaded' => $downloaded,
|
||||
'upload_size' => $uploadSize,
|
||||
'uploaded' => $uploaded
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Write data to the response body of a request
|
||||
*
|
||||
* @param resource $curl Curl handle
|
||||
* @param string $write Data that was received
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function writeResponseBody($curl, $write)
|
||||
{
|
||||
if ($this->emitIo) {
|
||||
$this->request->dispatch('curl.callback.write', array(
|
||||
'request' => $this->request,
|
||||
'write' => $write
|
||||
));
|
||||
}
|
||||
|
||||
if ($response = $this->request->getResponse()) {
|
||||
return $response->getBody()->write($write);
|
||||
} else {
|
||||
// Unexpected data received before response headers - abort transfer
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read data from the request body and send it to curl
|
||||
*
|
||||
* @param resource $ch Curl handle
|
||||
* @param resource $fd File descriptor
|
||||
* @param int $length Amount of data to read
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function readRequestBody($ch, $fd, $length)
|
||||
{
|
||||
if (!($body = $this->request->getBody())) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$read = (string) $body->read($length);
|
||||
if ($this->emitIo) {
|
||||
$this->request->dispatch('curl.callback.read', array('request' => $this->request, 'read' => $read));
|
||||
}
|
||||
|
||||
return $read;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue