summaryrefslogtreecommitdiffstats
path: root/vendor/fguillot/picofeed/lib/PicoFeed/Client/Curl.php
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/fguillot/picofeed/lib/PicoFeed/Client/Curl.php')
-rw-r--r--vendor/fguillot/picofeed/lib/PicoFeed/Client/Curl.php138
1 files changed, 136 insertions, 2 deletions
diff --git a/vendor/fguillot/picofeed/lib/PicoFeed/Client/Curl.php b/vendor/fguillot/picofeed/lib/PicoFeed/Client/Curl.php
index d45773d2d..5e5514f52 100644
--- a/vendor/fguillot/picofeed/lib/PicoFeed/Client/Curl.php
+++ b/vendor/fguillot/picofeed/lib/PicoFeed/Client/Curl.php
@@ -13,6 +13,38 @@ use PicoFeed\Logging\Logger;
class Curl extends Client
{
/**
+ * HTTP response body
+ *
+ * @access private
+ * @var string
+ */
+ private $body = '';
+
+ /**
+ * Body size
+ *
+ * @access private
+ * @var integer
+ */
+ private $body_length = 0;
+
+ /**
+ * HTTP response headers
+ *
+ * @access private
+ * @var array
+ */
+ private $headers = array();
+
+ /**
+ * Counter on the number of header received
+ *
+ * @access private
+ * @var integer
+ */
+ private $headers_counter = 0;
+
+ /**
* cURL callback to read the HTTP body
*
* If the function return -1, curl stop to read the HTTP response
@@ -64,6 +96,44 @@ class Curl extends Client
}
/**
+ * cURL callback to passthrough the HTTP status header to the client
+ *
+ * @access public
+ * @param resource $ch cURL handler
+ * @param string $buffer Header line
+ * @return integer Length of the buffer
+ */
+ public function passthroughHeaders($ch, $buffer)
+ {
+ list($status, $headers) = HttpHeaders::parse(array($buffer));
+
+ if ($status !== 0) {
+ header(':', true, $status);
+ }
+ elseif (isset($headers['Content-Type'])) {
+ header($buffer);
+ }
+
+ return $this->readHeaders($ch, $buffer);
+ }
+
+ /**
+ * cURL callback to passthrough the HTTP body to the client
+ *
+ * If the function return -1, curl stop to read the HTTP response
+ *
+ * @access public
+ * @param resource $ch cURL handler
+ * @param string $buffer Chunk of data
+ * @return integer Length of the buffer
+ */
+ public function passthroughBody($ch, $buffer)
+ {
+ echo $buffer;
+ return strlen($buffer);
+ }
+
+ /**
* Prepare HTTP headers
*
* @access private
@@ -131,6 +201,29 @@ class Curl extends Client
}
/**
+ * Set write/header functions
+ *
+ * @access private
+ * @return resource $ch
+ */
+ private function prepareDownloadMode($ch)
+ {
+ $write_function = 'readBody';
+ $header_function = 'readHeaders';
+
+ if ($this->isPassthroughEnabled()) {
+ $write_function = 'passthroughBody';
+ $header_function = 'passthroughHeaders';
+
+ }
+
+ curl_setopt($ch, CURLOPT_WRITEFUNCTION, array($this, $write_function));
+ curl_setopt($ch, CURLOPT_HEADERFUNCTION, array($this, $header_function));
+
+ return $ch;
+ }
+
+ /**
* Prepare curl context
*
* @access private
@@ -147,12 +240,11 @@ class Curl extends Client
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, ini_get('open_basedir') === '');
curl_setopt($ch, CURLOPT_MAXREDIRS, $this->max_redirects);
curl_setopt($ch, CURLOPT_ENCODING, '');
- curl_setopt($ch, CURLOPT_WRITEFUNCTION, array($this, 'readBody'));
- curl_setopt($ch, CURLOPT_HEADERFUNCTION, array($this, 'readHeaders'));
curl_setopt($ch, CURLOPT_COOKIEJAR, 'php://memory');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'php://memory');
curl_setopt($ch, CURLOPT_SSLVERSION, 1); // Enforce TLS v1
+ $ch = $this->prepareDownloadMode($ch);
$ch = $this->prepareProxyContext($ch);
$ch = $this->prepareAuthContext($ch);
@@ -229,6 +321,48 @@ class Curl extends Client
}
/**
+ * Handle manually redirections when there is an open base dir restriction
+ *
+ * @access private
+ * @param string $location Redirected URL
+ * @return array
+ */
+ private function handleRedirection($location)
+ {
+ $nb_redirects = 0;
+ $result = array();
+ $this->url = Url::resolve($location, $this->url);
+ $this->body = '';
+ $this->body_length = 0;
+ $this->headers = array();
+ $this->headers_counter = 0;
+
+ while (true) {
+
+ $nb_redirects++;
+
+ if ($nb_redirects >= $this->max_redirects) {
+ throw new MaxRedirectException('Maximum number of redirections reached');
+ }
+
+ $result = $this->doRequest(false);
+
+ if ($result['status'] == 301 || $result['status'] == 302) {
+ $this->url = Url::resolve($result['headers']['Location'], $this->url);
+ $this->body = '';
+ $this->body_length = 0;
+ $this->headers = array();
+ $this->headers_counter = 0;
+ }
+ else {
+ break;
+ }
+ }
+
+ return $result;
+ }
+
+ /**
* Handle cURL errors (throw individual exceptions)
*
* We don't use constants because they are not necessary always available