aboutsummaryrefslogtreecommitdiffstats
path: root/apps/files_external/3rdparty/aws-sdk-php/Guzzle/Http/Curl
diff options
context:
space:
mode:
Diffstat (limited to 'apps/files_external/3rdparty/aws-sdk-php/Guzzle/Http/Curl')
-rw-r--r--apps/files_external/3rdparty/aws-sdk-php/Guzzle/Http/Curl/CurlHandle.php15
-rw-r--r--apps/files_external/3rdparty/aws-sdk-php/Guzzle/Http/Curl/CurlMulti.php193
-rw-r--r--apps/files_external/3rdparty/aws-sdk-php/Guzzle/Http/Curl/CurlMultiProxy.php9
-rw-r--r--apps/files_external/3rdparty/aws-sdk-php/Guzzle/Http/Curl/RequestMediator.php26
4 files changed, 147 insertions, 96 deletions
diff --git a/apps/files_external/3rdparty/aws-sdk-php/Guzzle/Http/Curl/CurlHandle.php b/apps/files_external/3rdparty/aws-sdk-php/Guzzle/Http/Curl/CurlHandle.php
index 78f9bde87f6..63c6d4206ba 100644
--- a/apps/files_external/3rdparty/aws-sdk-php/Guzzle/Http/Curl/CurlHandle.php
+++ b/apps/files_external/3rdparty/aws-sdk-php/Guzzle/Http/Curl/CurlHandle.php
@@ -48,9 +48,16 @@ class CurlHandle
$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 => $request->getUrl(),
+ CURLOPT_URL => $url,
CURLOPT_CONNECTTIMEOUT => 150,
CURLOPT_RETURNTRANSFER => false,
CURLOPT_HEADER => false,
@@ -200,6 +207,12 @@ class CurlHandle
$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;
diff --git a/apps/files_external/3rdparty/aws-sdk-php/Guzzle/Http/Curl/CurlMulti.php b/apps/files_external/3rdparty/aws-sdk-php/Guzzle/Http/Curl/CurlMulti.php
index a8c569984d2..9e4e637222d 100644
--- a/apps/files_external/3rdparty/aws-sdk-php/Guzzle/Http/Curl/CurlMulti.php
+++ b/apps/files_external/3rdparty/aws-sdk-php/Guzzle/Http/Curl/CurlMulti.php
@@ -7,6 +7,8 @@ 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
@@ -39,8 +41,12 @@ class CurlMulti extends AbstractHasDispatcher implements CurlMultiInterface
CURLM_INTERNAL_ERROR => array('CURLM_INTERNAL_ERROR', 'This can only be returned if libcurl bugs. Please report it to us!')
);
- public function __construct()
+ /** @var float */
+ protected $selectTimeout;
+
+ public function __construct($selectTimeout = 1.0)
{
+ $this->selectTimeout = $selectTimeout;
$this->multiHandle = curl_multi_init();
// @codeCoverageIgnoreStart
if ($this->multiHandle === false) {
@@ -76,13 +82,12 @@ class CurlMulti extends AbstractHasDispatcher implements CurlMultiInterface
public function remove(RequestInterface $request)
{
$this->removeHandle($request);
- foreach ($this->requests as $i => $r) {
- if ($request === $r) {
- unset($this->requests[$i]);
- $this->requests = array_values($this->requests);
- $this->dispatch(self::REMOVE_REQUEST, array('request' => $request));
- return true;
- }
+ 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;
@@ -130,8 +135,7 @@ class CurlMulti extends AbstractHasDispatcher implements CurlMultiInterface
$multiException = new MultiTransferException('Errors during multi transfer');
while ($e = array_shift($exceptions)) {
- $multiException->add($e['exception']);
- $multiException->addFailedRequest($e['request']);
+ $multiException->addFailedRequestWithException($e['request'], $e['exception']);
}
// Add successful requests
@@ -155,10 +159,10 @@ class CurlMulti extends AbstractHasDispatcher implements CurlMultiInterface
try {
$state = $request->setState(RequestInterface::STATE_TRANSFER);
if ($state == RequestInterface::STATE_TRANSFER) {
- // Add the request curl handle to the multi handle
- $this->checkCurlResult(curl_multi_add_handle($this->multiHandle, $this->createCurlHandle($request)->getHandle()));
+ $this->addHandle($request);
} else {
- // Requests might decide they don't need to be sent just before transfer (e.g. CachePlugin)
+ // 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;
@@ -170,6 +174,14 @@ class CurlMulti extends AbstractHasDispatcher implements CurlMultiInterface
}
}
+ 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
*
@@ -191,18 +203,9 @@ class CurlMulti extends AbstractHasDispatcher implements CurlMultiInterface
*/
protected function perform()
{
- if (!$this->requests) {
- return;
- }
-
- // Initialize the handles with a very quick select timeout
- $active = $mrc = null;
- $this->executeHandles($active, $mrc, 0.001);
$event = new Event(array('curl_multi' => $this));
- $this->processMessages();
while ($this->requests) {
-
// Notify each request as polling
$blocking = $total = 0;
foreach ($this->requests as $request) {
@@ -214,33 +217,45 @@ class CurlMulti extends AbstractHasDispatcher implements CurlMultiInterface
++$blocking;
}
}
-
if ($blocking == $total) {
// Sleep to prevent eating CPU because no requests are actually pending a select call
usleep(500);
} else {
- do {
- $this->executeHandles($active, $mrc, 1);
- } while ($active);
+ $this->executeHandles();
}
- $this->processMessages();
}
}
/**
+ * 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()
{
- // Get messages from curl handles
while ($done = curl_multi_info_read($this->multiHandle)) {
+ $request = $this->resourceHash[(int) $done['handle']];
try {
- $request = $this->resourceHash[(int) $done['handle']];
$this->processResponse($request, $this->handles[$request], $done);
$this->successful[] = $request;
- } catch (MultiTransferException $e) {
- $this->removeErroredRequest($request, $e, false);
- throw $e;
} catch (\Exception $e) {
$this->removeErroredRequest($request, $e);
}
@@ -248,43 +263,14 @@ class CurlMulti extends AbstractHasDispatcher implements CurlMultiInterface
}
/**
- * Execute and select curl handles until there is activity
- *
- * @param int $active Active value to update
- * @param int $mrc Multi result value to update
- * @param int $timeout Select timeout in seconds
- */
- private function executeHandles(&$active, &$mrc, $timeout = 1)
- {
- do {
- $mrc = curl_multi_exec($this->multiHandle, $active);
- } while ($mrc == CURLM_CALL_MULTI_PERFORM && $active);
- $this->checkCurlResult($mrc);
-
- // @codeCoverageIgnoreStart
- // Select the curl handles until there is any activity on any of the open file descriptors
- // See https://github.com/php/php-src/blob/master/ext/curl/multi.c#L170
- if ($active && $mrc == CURLM_OK && curl_multi_select($this->multiHandle, $timeout) == -1) {
- // Perform a usleep if a previously executed select returned -1
- // @see https://bugs.php.net/bug.php?id=61141
- usleep(100);
- }
- // @codeCoverageIgnoreEnd
- }
-
- /**
* Remove a request that encountered an exception
*
* @param RequestInterface $request Request to remove
* @param \Exception $e Exception encountered
- * @param bool $buffer Set to false to not buffer the exception
*/
- protected function removeErroredRequest(RequestInterface $request, \Exception $e = null, $buffer = true)
+ protected function removeErroredRequest(RequestInterface $request, \Exception $e = null)
{
- if ($buffer) {
- $this->exceptions[] = array('request' => $request, 'exception' => $e);
- }
-
+ $this->exceptions[] = array('request' => $request, 'exception' => $e);
$this->remove($request);
$this->dispatch(self::MULTI_EXCEPTION, array('exception' => $e, 'all_exceptions' => $this->exceptions));
}
@@ -310,23 +296,31 @@ class CurlMulti extends AbstractHasDispatcher implements CurlMultiInterface
$this->removeHandle($request);
if (!$curlException) {
- $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);
- }
- } else {
- // 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;
+ 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;
}
}
@@ -339,9 +333,9 @@ class CurlMulti extends AbstractHasDispatcher implements CurlMultiInterface
{
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()]);
- curl_multi_remove_handle($this->multiHandle, $handle->getHandle());
$handle->close();
}
}
@@ -387,4 +381,43 @@ class CurlMulti extends AbstractHasDispatcher implements CurlMultiInterface
);
}
}
+
+ /**
+ * @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;
+ }
}
diff --git a/apps/files_external/3rdparty/aws-sdk-php/Guzzle/Http/Curl/CurlMultiProxy.php b/apps/files_external/3rdparty/aws-sdk-php/Guzzle/Http/Curl/CurlMultiProxy.php
index 665f029a79d..c5b80a7f57f 100644
--- a/apps/files_external/3rdparty/aws-sdk-php/Guzzle/Http/Curl/CurlMultiProxy.php
+++ b/apps/files_external/3rdparty/aws-sdk-php/Guzzle/Http/Curl/CurlMultiProxy.php
@@ -15,13 +15,16 @@ class CurlMultiProxy extends AbstractHasDispatcher implements CurlMultiInterface
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 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)
+ 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.
@@ -122,7 +125,7 @@ class CurlMultiProxy extends AbstractHasDispatcher implements CurlMultiInterface
}
// All are claimed, so create one
- $handle = new CurlMulti();
+ $handle = new CurlMulti($this->selectTimeout);
$handle->setEventDispatcher($this->getEventDispatcher());
$this->handles[] = $handle;
diff --git a/apps/files_external/3rdparty/aws-sdk-php/Guzzle/Http/Curl/RequestMediator.php b/apps/files_external/3rdparty/aws-sdk-php/Guzzle/Http/Curl/RequestMediator.php
index 0a70c626bf0..5d1a0cd8724 100644
--- a/apps/files_external/3rdparty/aws-sdk-php/Guzzle/Http/Curl/RequestMediator.php
+++ b/apps/files_external/3rdparty/aws-sdk-php/Guzzle/Http/Curl/RequestMediator.php
@@ -114,7 +114,12 @@ class RequestMediator
));
}
- return $this->request->getResponse()->getBody()->write($write);
+ if ($response = $this->request->getResponse()) {
+ return $response->getBody()->write($write);
+ } else {
+ // Unexpected data received before response headers - abort transfer
+ return 0;
+ }
}
/**
@@ -128,18 +133,15 @@ class RequestMediator
*/
public function readRequestBody($ch, $fd, $length)
{
- $read = '';
-
- if ($this->request->getBody()) {
- $read = $this->request->getBody()->read($length);
- if ($this->emitIo) {
- $this->request->dispatch('curl.callback.read', array(
- 'request' => $this->request,
- 'read' => $read
- ));
- }
+ 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 ? '' : $read;
+ return $read;
}
}