diff options
Diffstat (limited to 'vendor/miniflux/picofeed/lib/PicoFeed/Client')
13 files changed, 0 insertions, 1789 deletions
diff --git a/vendor/miniflux/picofeed/lib/PicoFeed/Client/Client.php b/vendor/miniflux/picofeed/lib/PicoFeed/Client/Client.php deleted file mode 100644 index 0548d5c6..00000000 --- a/vendor/miniflux/picofeed/lib/PicoFeed/Client/Client.php +++ /dev/null @@ -1,719 +0,0 @@ -<?php - -namespace PicoFeed\Client; - -use DateTime; -use Exception; -use LogicException; -use PicoFeed\Logging\Logger; -use PicoFeed\Config\Config; - -/** - * Client class. - * - * @author Frederic Guillot - */ -abstract class Client -{ - /** - * Flag that say if the resource have been modified. - * - * @var bool - */ - private $is_modified = true; - - /** - * HTTP Content-Type. - * - * @var string - */ - private $content_type = ''; - - /** - * HTTP encoding. - * - * @var string - */ - private $encoding = ''; - - /** - * HTTP request headers. - * - * @var array - */ - protected $request_headers = array(); - - /** - * HTTP Etag header. - * - * @var string - */ - protected $etag = ''; - - /** - * HTTP Last-Modified header. - * - * @var string - */ - protected $last_modified = ''; - - /** - * Expiration DateTime - * - * @var DateTime - */ - protected $expiration = null; - - /** - * Proxy hostname. - * - * @var string - */ - protected $proxy_hostname = ''; - - /** - * Proxy port. - * - * @var int - */ - protected $proxy_port = 3128; - - /** - * Proxy username. - * - * @var string - */ - protected $proxy_username = ''; - - /** - * Proxy password. - * - * @var string - */ - protected $proxy_password = ''; - - /** - * Basic auth username. - * - * @var string - */ - protected $username = ''; - - /** - * Basic auth password. - * - * @var string - */ - protected $password = ''; - - /** - * Client connection timeout. - * - * @var int - */ - protected $timeout = 10; - - /** - * User-agent. - * - * @var string - */ - protected $user_agent = 'PicoFeed (https://github.com/miniflux/picoFeed)'; - - /** - * Real URL used (can be changed after a HTTP redirect). - * - * @var string - */ - protected $url = ''; - - /** - * Page/Feed content. - * - * @var string - */ - protected $content = ''; - - /** - * Number maximum of HTTP redirections to avoid infinite loops. - * - * @var int - */ - protected $max_redirects = 5; - - /** - * Maximum size of the HTTP body response. - * - * @var int - */ - protected $max_body_size = 2097152; // 2MB - - /** - * HTTP response status code. - * - * @var int - */ - protected $status_code = 0; - - /** - * Enables direct passthrough to requesting client. - * - * @var bool - */ - protected $passthrough = false; - - /** - * Do the HTTP request. - * - * @abstract - * - * @return array - */ - abstract public function doRequest(); - - /** - * Get client instance: curl or stream driver. - * - * @static - * - * @return \PicoFeed\Client\Client - */ - public static function getInstance() - { - if (function_exists('curl_init')) { - return new Curl(); - } elseif (ini_get('allow_url_fopen')) { - return new Stream(); - } - - throw new LogicException('You must have "allow_url_fopen=1" or curl extension installed'); - } - - /** - * Add HTTP Header to the request. - * - * @param array $headers - */ - public function setHeaders($headers) - { - $this->request_headers = $headers; - } - - /** - * Perform the HTTP request. - * - * @param string $url URL - * - * @return Client - */ - public function execute($url = '') - { - if ($url !== '') { - $this->url = $url; - } - - Logger::setMessage(get_called_class().' Fetch URL: '.$this->url); - Logger::setMessage(get_called_class().' Etag provided: '.$this->etag); - Logger::setMessage(get_called_class().' Last-Modified provided: '.$this->last_modified); - - $response = $this->doRequest(); - - $this->status_code = $response['status']; - $this->handleNotModifiedResponse($response); - $this->handleErrorResponse($response); - $this->handleNormalResponse($response); - - $this->expiration = $this->parseExpiration($response['headers']); - Logger::setMessage(get_called_class().' Expiration: '.$this->expiration->format(DATE_ISO8601)); - - return $this; - } - - /** - * Handle not modified response. - * - * @param array $response Client response - */ - protected function handleNotModifiedResponse(array $response) - { - if ($response['status'] == 304) { - $this->is_modified = false; - } elseif ($response['status'] == 200) { - $this->is_modified = $this->hasBeenModified($response, $this->etag, $this->last_modified); - $this->etag = $this->getHeader($response, 'ETag'); - $this->last_modified = $this->getHeader($response, 'Last-Modified'); - } - - if ($this->is_modified === false) { - Logger::setMessage(get_called_class().' Resource not modified'); - } - } - - /** - * Handle Http Error codes - * - * @param array $response Client response - * @throws ForbiddenException - * @throws InvalidUrlException - * @throws UnauthorizedException - */ - protected function handleErrorResponse(array $response) - { - $status = $response['status']; - if ($status == 401) { - throw new UnauthorizedException('Wrong or missing credentials'); - } else if ($status == 403) { - throw new ForbiddenException('Not allowed to access resource'); - } else if ($status == 404) { - throw new InvalidUrlException('Resource not found'); - } - } - - /** - * Handle normal response. - * - * @param array $response Client response - */ - protected function handleNormalResponse(array $response) - { - if ($response['status'] == 200) { - $this->content = $response['body']; - $this->content_type = $this->findContentType($response); - $this->encoding = $this->findCharset(); - } - } - - /** - * Check if a request has been modified according to the parameters. - * - * @param array $response - * @param string $etag - * @param string $lastModified - * - * @return bool - */ - private function hasBeenModified($response, $etag, $lastModified) - { - $headers = array( - 'Etag' => $etag, - 'Last-Modified' => $lastModified, - ); - - // Compare the values for each header that is present - $presentCacheHeaderCount = 0; - foreach ($headers as $key => $value) { - if (isset($response['headers'][$key])) { - if ($response['headers'][$key] !== $value) { - return true; - } - ++$presentCacheHeaderCount; - } - } - - // If at least one header is present and the values match, the response - // was not modified - if ($presentCacheHeaderCount > 0) { - return false; - } - - return true; - } - - /** - * Find content type from response headers. - * - * @param array $response Client response - * - * @return string - */ - public function findContentType(array $response) - { - return strtolower($this->getHeader($response, 'Content-Type')); - } - - /** - * Find charset from response headers. - * - * @return string - */ - public function findCharset() - { - $result = explode('charset=', $this->content_type); - - return isset($result[1]) ? $result[1] : ''; - } - - /** - * Get header value from a client response. - * - * @param array $response Client response - * @param string $header Header name - * - * @return string - */ - public function getHeader(array $response, $header) - { - return isset($response['headers'][$header]) ? $response['headers'][$header] : ''; - } - - /** - * Set the Last-Modified HTTP header. - * - * @param string $last_modified Header value - * - * @return \PicoFeed\Client\Client - */ - public function setLastModified($last_modified) - { - $this->last_modified = $last_modified; - - return $this; - } - - /** - * Get the value of the Last-Modified HTTP header. - * - * @return string - */ - public function getLastModified() - { - return $this->last_modified; - } - - /** - * Set the value of the Etag HTTP header. - * - * @param string $etag Etag HTTP header value - * - * @return \PicoFeed\Client\Client - */ - public function setEtag($etag) - { - $this->etag = $etag; - - return $this; - } - - /** - * Get the Etag HTTP header value. - * - * @return string - */ - public function getEtag() - { - return $this->etag; - } - - /** - * Get the final url value. - * - * @return string - */ - public function getUrl() - { - return $this->url; - } - - /** - * Set the url. - * - * @param $url - * @return string - */ - public function setUrl($url) - { - $this->url = $url; - return $this; - } - - /** - * Get the HTTP response status code. - * - * @return int - */ - public function getStatusCode() - { - return $this->status_code; - } - - /** - * Get the body of the HTTP response. - * - * @return string - */ - public function getContent() - { - return $this->content; - } - - /** - * Get the content type value from HTTP headers. - * - * @return string - */ - public function getContentType() - { - return $this->content_type; - } - - /** - * Get the encoding value from HTTP headers. - * - * @return string - */ - public function getEncoding() - { - return $this->encoding; - } - - /** - * Return true if the remote resource has changed. - * - * @return bool - */ - public function isModified() - { - return $this->is_modified; - } - - /** - * return true if passthrough mode is enabled. - * - * @return bool - */ - public function isPassthroughEnabled() - { - return $this->passthrough; - } - - /** - * Set connection timeout. - * - * @param int $timeout Connection timeout - * - * @return \PicoFeed\Client\Client - */ - public function setTimeout($timeout) - { - $this->timeout = $timeout ?: $this->timeout; - - return $this; - } - - /** - * Set a custom user agent. - * - * @param string $user_agent User Agent - * - * @return \PicoFeed\Client\Client - */ - public function setUserAgent($user_agent) - { - $this->user_agent = $user_agent ?: $this->user_agent; - - return $this; - } - - /** - * Set the maximum number of HTTP redirections. - * - * @param int $max Maximum - * - * @return \PicoFeed\Client\Client - */ - public function setMaxRedirections($max) - { - $this->max_redirects = $max ?: $this->max_redirects; - - return $this; - } - - /** - * Set the maximum size of the HTTP body. - * - * @param int $max Maximum - * - * @return \PicoFeed\Client\Client - */ - public function setMaxBodySize($max) - { - $this->max_body_size = $max ?: $this->max_body_size; - - return $this; - } - - /** - * Set the proxy hostname. - * - * @param string $hostname Proxy hostname - * - * @return \PicoFeed\Client\Client - */ - public function setProxyHostname($hostname) - { - $this->proxy_hostname = $hostname ?: $this->proxy_hostname; - - return $this; - } - - /** - * Set the proxy port. - * - * @param int $port Proxy port - * - * @return \PicoFeed\Client\Client - */ - public function setProxyPort($port) - { - $this->proxy_port = $port ?: $this->proxy_port; - - return $this; - } - - /** - * Set the proxy username. - * - * @param string $username Proxy username - * - * @return \PicoFeed\Client\Client - */ - public function setProxyUsername($username) - { - $this->proxy_username = $username ?: $this->proxy_username; - - return $this; - } - - /** - * Set the proxy password. - * - * @param string $password Password - * - * @return \PicoFeed\Client\Client - */ - public function setProxyPassword($password) - { - $this->proxy_password = $password ?: $this->proxy_password; - - return $this; - } - - /** - * Set the username. - * - * @param string $username Basic Auth username - * - * @return \PicoFeed\Client\Client - */ - public function setUsername($username) - { - $this->username = $username ?: $this->username; - - return $this; - } - - /** - * Set the password. - * - * @param string $password Basic Auth Password - * - * @return \PicoFeed\Client\Client - */ - public function setPassword($password) - { - $this->password = $password ?: $this->password; - - return $this; - } - - /** - * Enable the passthrough mode. - * - * @return \PicoFeed\Client\Client - */ - public function enablePassthroughMode() - { - $this->passthrough = true; - - return $this; - } - - /** - * Disable the passthrough mode. - * - * @return \PicoFeed\Client\Client - */ - public function disablePassthroughMode() - { - $this->passthrough = false; - - return $this; - } - - /** - * Set config object. - * - * @param \PicoFeed\Config\Config $config Config instance - * - * @return \PicoFeed\Client\Client - */ - public function setConfig(Config $config) - { - if ($config !== null) { - $this->setTimeout($config->getClientTimeout()); - $this->setUserAgent($config->getClientUserAgent()); - $this->setMaxRedirections($config->getMaxRedirections()); - $this->setMaxBodySize($config->getMaxBodySize()); - $this->setProxyHostname($config->getProxyHostname()); - $this->setProxyPort($config->getProxyPort()); - $this->setProxyUsername($config->getProxyUsername()); - $this->setProxyPassword($config->getProxyPassword()); - } - - return $this; - } - - /** - * Return true if the HTTP status code is a redirection - * - * @access protected - * @param integer $code - * @return boolean - */ - public function isRedirection($code) - { - return $code == 301 || $code == 302 || $code == 303 || $code == 307; - } - - public function parseExpiration(HttpHeaders $headers) - { - try { - - if (isset($headers['Cache-Control'])) { - if (preg_match('/s-maxage=(\d+)/', $headers['Cache-Control'], $matches)) { - return new DateTime('+' . $matches[1] . ' seconds'); - } else if (preg_match('/max-age=(\d+)/', $headers['Cache-Control'], $matches)) { - return new DateTime('+' . $matches[1] . ' seconds'); - } - } - - if (! empty($headers['Expires'])) { - return new DateTime($headers['Expires']); - } - } catch (Exception $e) { - Logger::setMessage('Unable to parse expiration date: '.$e->getMessage()); - } - - return new DateTime(); - } - - /** - * Get expiration date time from "Expires" or "Cache-Control" headers - * - * @return DateTime - */ - public function getExpiration() - { - return $this->expiration ?: new DateTime(); - } -} diff --git a/vendor/miniflux/picofeed/lib/PicoFeed/Client/ClientException.php b/vendor/miniflux/picofeed/lib/PicoFeed/Client/ClientException.php deleted file mode 100644 index b3a95c9f..00000000 --- a/vendor/miniflux/picofeed/lib/PicoFeed/Client/ClientException.php +++ /dev/null @@ -1,14 +0,0 @@ -<?php - -namespace PicoFeed\Client; - -use PicoFeed\PicoFeedException; - -/** - * ClientException Exception. - * - * @author Frederic Guillot - */ -abstract class ClientException extends PicoFeedException -{ -} diff --git a/vendor/miniflux/picofeed/lib/PicoFeed/Client/Curl.php b/vendor/miniflux/picofeed/lib/PicoFeed/Client/Curl.php deleted file mode 100644 index f4a65782..00000000 --- a/vendor/miniflux/picofeed/lib/PicoFeed/Client/Curl.php +++ /dev/null @@ -1,402 +0,0 @@ -<?php - -namespace PicoFeed\Client; - -use PicoFeed\Logging\Logger; - -/** - * cURL HTTP client. - * - * @author Frederic Guillot - */ -class Curl extends Client -{ - protected $nbRedirects = 0; - - /** - * HTTP response body. - * - * @var string - */ - private $body = ''; - - /** - * Body size. - * - * @var int - */ - private $body_length = 0; - - /** - * HTTP response headers. - * - * @var array - */ - private $response_headers = array(); - - /** - * Counter on the number of header received. - * - * @var int - */ - private $response_headers_count = 0; - - /** - * cURL callback to read the HTTP body. - * - * If the function return -1, curl stop to read the HTTP response - * - * @param resource $ch cURL handler - * @param string $buffer Chunk of data - * - * @return int Length of the buffer - */ - public function readBody($ch, $buffer) - { - $length = strlen($buffer); - $this->body_length += $length; - - if ($this->body_length > $this->max_body_size) { - return -1; - } - - $this->body .= $buffer; - - return $length; - } - - /** - * cURL callback to read HTTP headers. - * - * @param resource $ch cURL handler - * @param string $buffer Header line - * - * @return int Length of the buffer - */ - public function readHeaders($ch, $buffer) - { - $length = strlen($buffer); - - if ($buffer === "\r\n" || $buffer === "\n") { - ++$this->response_headers_count; - } else { - if (!isset($this->response_headers[$this->response_headers_count])) { - $this->response_headers[$this->response_headers_count] = ''; - } - - $this->response_headers[$this->response_headers_count] .= $buffer; - } - - return $length; - } - - /** - * cURL callback to passthrough the HTTP body to the client. - * - * If the function return -1, curl stop to read the HTTP response - * - * @param resource $ch cURL handler - * @param string $buffer Chunk of data - * - * @return int Length of the buffer - */ - public function passthroughBody($ch, $buffer) - { - // do it only at the beginning of a transmission - if ($this->body_length === 0) { - list($status, $headers) = HttpHeaders::parse(explode("\n", $this->response_headers[$this->response_headers_count - 1])); - - if ($this->isRedirection($status)) { - return $this->handleRedirection($headers['Location']); - } - - // Do not work with PHP-FPM - if (strpos(PHP_SAPI, 'cgi') !== false) { - header(':', true, $status); - } - - if (isset($headers['Content-Type'])) { - header('Content-Type:' .$headers['Content-Type']); - } - } - - $length = strlen($buffer); - $this->body_length += $length; - - echo $buffer; - - return $length; - } - - /** - * Prepare HTTP headers. - * - * @return string[] - */ - private function prepareHeaders() - { - $headers = array( - 'Connection: close', - ); - - if ($this->etag) { - $headers[] = 'If-None-Match: '.$this->etag; - $headers[] = 'A-IM: feed'; - } - - if ($this->last_modified) { - $headers[] = 'If-Modified-Since: '.$this->last_modified; - } - - $headers = array_merge($headers, $this->request_headers); - - return $headers; - } - - /** - * Prepare curl proxy context. - * - * @param resource $ch - * - * @return resource $ch - */ - private function prepareProxyContext($ch) - { - if ($this->proxy_hostname) { - Logger::setMessage(get_called_class().' Proxy: '.$this->proxy_hostname.':'.$this->proxy_port); - - curl_setopt($ch, CURLOPT_PROXYPORT, $this->proxy_port); - curl_setopt($ch, CURLOPT_PROXYTYPE, 'HTTP'); - curl_setopt($ch, CURLOPT_PROXY, $this->proxy_hostname); - - if ($this->proxy_username) { - Logger::setMessage(get_called_class().' Proxy credentials: Yes'); - curl_setopt($ch, CURLOPT_PROXYUSERPWD, $this->proxy_username.':'.$this->proxy_password); - } else { - Logger::setMessage(get_called_class().' Proxy credentials: No'); - } - } - - return $ch; - } - - /** - * Prepare curl auth context. - * - * @param resource $ch - * - * @return resource $ch - */ - private function prepareAuthContext($ch) - { - if ($this->username && $this->password) { - curl_setopt($ch, CURLOPT_USERPWD, $this->username.':'.$this->password); - } - - return $ch; - } - - /** - * Set write/header functions. - * - * @param resource $ch - * - * @return resource $ch - */ - private function prepareDownloadMode($ch) - { - $this->body = ''; - $this->response_headers = array(); - $this->response_headers_count = 0; - $write_function = 'readBody'; - $header_function = 'readHeaders'; - - if ($this->isPassthroughEnabled()) { - $write_function = 'passthroughBody'; - } - - curl_setopt($ch, CURLOPT_WRITEFUNCTION, array($this, $write_function)); - curl_setopt($ch, CURLOPT_HEADERFUNCTION, array($this, $header_function)); - - return $ch; - } - - /** - * Prepare curl context. - * - * @return resource - */ - private function prepareContext() - { - $ch = curl_init(); - - curl_setopt($ch, CURLOPT_URL, $this->url); - curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); - curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout); - curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->timeout); - curl_setopt($ch, CURLOPT_USERAGENT, $this->user_agent); - curl_setopt($ch, CURLOPT_HTTPHEADER, $this->prepareHeaders()); - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false); - curl_setopt($ch, CURLOPT_ENCODING, ''); - curl_setopt($ch, CURLOPT_COOKIEJAR, 'php://memory'); - curl_setopt($ch, CURLOPT_COOKIEFILE, 'php://memory'); - - // Disable SSLv3 by enforcing TLSv1.x for curl >= 7.34.0 and < 7.39.0. - // Versions prior to 7.34 and at least when compiled against openssl - // interpret this parameter as "limit to TLSv1.0" which fails for sites - // which enforce TLS 1.1+. - // Starting with curl 7.39.0 SSLv3 is disabled by default. - $version = curl_version(); - if ($version['version_number'] >= 467456 && $version['version_number'] < 468736) { - curl_setopt($ch, CURLOPT_SSLVERSION, 1); - } - - $ch = $this->prepareDownloadMode($ch); - $ch = $this->prepareProxyContext($ch); - $ch = $this->prepareAuthContext($ch); - - return $ch; - } - - /** - * Execute curl context. - */ - private function executeContext() - { - $ch = $this->prepareContext(); - curl_exec($ch); - - Logger::setMessage(get_called_class().' cURL total time: '.curl_getinfo($ch, CURLINFO_TOTAL_TIME)); - Logger::setMessage(get_called_class().' cURL dns lookup time: '.curl_getinfo($ch, CURLINFO_NAMELOOKUP_TIME)); - Logger::setMessage(get_called_class().' cURL connect time: '.curl_getinfo($ch, CURLINFO_CONNECT_TIME)); - Logger::setMessage(get_called_class().' cURL speed download: '.curl_getinfo($ch, CURLINFO_SPEED_DOWNLOAD)); - Logger::setMessage(get_called_class().' cURL effective url: '.curl_getinfo($ch, CURLINFO_EFFECTIVE_URL)); - - $curl_errno = curl_errno($ch); - - if ($curl_errno) { - Logger::setMessage(get_called_class().' cURL error: '.curl_error($ch)); - curl_close($ch); - - $this->handleError($curl_errno); - } - - // Update the url if there where redirects - $this->url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); - - curl_close($ch); - } - - /** - * Do the HTTP request. - * - * @return array HTTP response ['body' => ..., 'status' => ..., 'headers' => ...] - */ - public function doRequest() - { - $this->executeContext(); - - list($status, $headers) = HttpHeaders::parse(explode("\n", $this->response_headers[$this->response_headers_count - 1])); - - if ($this->isRedirection($status)) { - if (empty($headers['Location'])) { - $status = 200; - } else { - return $this->handleRedirection($headers['Location']); - } - } - - return array( - 'status' => $status, - 'body' => $this->body, - 'headers' => $headers, - ); - } - - /** - * Handle HTTP redirects - * - * @param string $location Redirected URL - * @return array - * @throws MaxRedirectException - */ - private function handleRedirection($location) - { - $result = array(); - $this->url = Url::resolve($location, $this->url); - $this->body = ''; - $this->body_length = 0; - $this->response_headers = array(); - $this->response_headers_count = 0; - - while (true) { - $this->nbRedirects++; - - if ($this->nbRedirects >= $this->max_redirects) { - throw new MaxRedirectException('Maximum number of redirections reached'); - } - - $result = $this->doRequest(); - - if ($this->isRedirection($result['status'])) { - $this->url = Url::resolve($result['headers']['Location'], $this->url); - $this->body = ''; - $this->body_length = 0; - $this->response_headers = array(); - $this->response_headers_count = 0; - } else { - break; - } - } - - return $result; - } - - /** - * Handle cURL errors (throw individual exceptions). - * - * We don't use constants because they are not necessary always available - * (depends of the version of libcurl linked to php) - * - * @see http://curl.haxx.se/libcurl/c/libcurl-errors.html - * - * @param int $errno cURL error code - * @throws InvalidCertificateException - * @throws InvalidUrlException - * @throws MaxRedirectException - * @throws MaxSizeException - * @throws TimeoutException - */ - private function handleError($errno) - { - switch ($errno) { - case 78: // CURLE_REMOTE_FILE_NOT_FOUND - throw new InvalidUrlException('Resource not found', $errno); - case 6: // CURLE_COULDNT_RESOLVE_HOST - throw new InvalidUrlException('Unable to resolve hostname', $errno); - case 7: // CURLE_COULDNT_CONNECT - throw new InvalidUrlException('Unable to connect to the remote host', $errno); - case 23: // CURLE_WRITE_ERROR - throw new MaxSizeException('Maximum response size exceeded', $errno); - case 28: // CURLE_OPERATION_TIMEDOUT - throw new TimeoutException('Operation timeout', $errno); - case 35: // CURLE_SSL_CONNECT_ERROR - case 51: // CURLE_PEER_FAILED_VERIFICATION - case 58: // CURLE_SSL_CERTPROBLEM - case 60: // CURLE_SSL_CACERT - case 59: // CURLE_SSL_CIPHER - case 64: // CURLE_USE_SSL_FAILED - case 66: // CURLE_SSL_ENGINE_INITFAILED - case 77: // CURLE_SSL_CACERT_BADFILE - case 83: // CURLE_SSL_ISSUER_ERROR - $msg = 'Invalid SSL certificate caused by CURL error number ' . $errno; - throw new InvalidCertificateException($msg, $errno); - case 47: // CURLE_TOO_MANY_REDIRECTS - throw new MaxRedirectException('Maximum number of redirections reached', $errno); - case 63: // CURLE_FILESIZE_EXCEEDED - throw new MaxSizeException('Maximum response size exceeded', $errno); - default: - throw new InvalidUrlException('Unable to fetch the URL', $errno); - } - } -} diff --git a/vendor/miniflux/picofeed/lib/PicoFeed/Client/ForbiddenException.php b/vendor/miniflux/picofeed/lib/PicoFeed/Client/ForbiddenException.php deleted file mode 100644 index c226e95a..00000000 --- a/vendor/miniflux/picofeed/lib/PicoFeed/Client/ForbiddenException.php +++ /dev/null @@ -1,10 +0,0 @@ -<?php - -namespace PicoFeed\Client; - -/** - * @author Bernhard Posselt - */ -class ForbiddenException extends ClientException -{ -} diff --git a/vendor/miniflux/picofeed/lib/PicoFeed/Client/HttpHeaders.php b/vendor/miniflux/picofeed/lib/PicoFeed/Client/HttpHeaders.php deleted file mode 100644 index 34b81399..00000000 --- a/vendor/miniflux/picofeed/lib/PicoFeed/Client/HttpHeaders.php +++ /dev/null @@ -1,79 +0,0 @@ -<?php - -namespace PicoFeed\Client; - -use ArrayAccess; -use PicoFeed\Logging\Logger; - -/** - * Class to handle HTTP headers case insensitivity. - * - * @author Bernhard Posselt - * @author Frederic Guillot - */ -class HttpHeaders implements ArrayAccess -{ - private $headers = array(); - - public function __construct(array $headers) - { - foreach ($headers as $key => $value) { - $this->headers[strtolower($key)] = $value; - } - } - - public function offsetGet($offset) - { - return $this->offsetExists($offset) ? $this->headers[strtolower($offset)] : ''; - } - - public function offsetSet($offset, $value) - { - $this->headers[strtolower($offset)] = $value; - } - - public function offsetExists($offset) - { - return isset($this->headers[strtolower($offset)]); - } - - public function offsetUnset($offset) - { - unset($this->headers[strtolower($offset)]); - } - - /** - * Parse HTTP headers. - * - * @static - * - * @param array $lines List of headers - * - * @return array - */ - public static function parse(array $lines) - { - $status = 0; - $headers = array(); - - foreach ($lines as $line) { - if (strpos($line, 'HTTP/1') === 0) { - $headers = array(); - $status = (int) substr($line, 9, 3); - } elseif (strpos($line, ': ') !== false) { - list($name, $value) = explode(': ', $line); - if ($value) { - $headers[trim($name)] = trim($value); - } - } - } - - Logger::setMessage(get_called_class().' HTTP status code: '.$status); - - foreach ($headers as $name => $value) { - Logger::setMessage(get_called_class().' HTTP header: '.$name.' => '.$value); - } - - return array($status, new self($headers)); - } -} diff --git a/vendor/miniflux/picofeed/lib/PicoFeed/Client/InvalidCertificateException.php b/vendor/miniflux/picofeed/lib/PicoFeed/Client/InvalidCertificateException.php deleted file mode 100644 index 8d25d7e4..00000000 --- a/vendor/miniflux/picofeed/lib/PicoFeed/Client/InvalidCertificateException.php +++ /dev/null @@ -1,12 +0,0 @@ -<?php - -namespace PicoFeed\Client; - -/** - * InvalidCertificateException Exception. - * - * @author Frederic Guillot - */ -class InvalidCertificateException extends ClientException -{ -} diff --git a/vendor/miniflux/picofeed/lib/PicoFeed/Client/InvalidUrlException.php b/vendor/miniflux/picofeed/lib/PicoFeed/Client/InvalidUrlException.php deleted file mode 100644 index 15534d98..00000000 --- a/vendor/miniflux/picofeed/lib/PicoFeed/Client/InvalidUrlException.php +++ /dev/null @@ -1,12 +0,0 @@ -<?php - -namespace PicoFeed\Client; - -/** - * InvalidUrlException Exception. - * - * @author Frederic Guillot - */ -class InvalidUrlException extends ClientException -{ -} diff --git a/vendor/miniflux/picofeed/lib/PicoFeed/Client/MaxRedirectException.php b/vendor/miniflux/picofeed/lib/PicoFeed/Client/MaxRedirectException.php deleted file mode 100644 index 0a221af6..00000000 --- a/vendor/miniflux/picofeed/lib/PicoFeed/Client/MaxRedirectException.php +++ /dev/null @@ -1,12 +0,0 @@ -<?php - -namespace PicoFeed\Client; - -/** - * MaxRedirectException Exception. - * - * @author Frederic Guillot - */ -class MaxRedirectException extends ClientException -{ -} diff --git a/vendor/miniflux/picofeed/lib/PicoFeed/Client/MaxSizeException.php b/vendor/miniflux/picofeed/lib/PicoFeed/Client/MaxSizeException.php deleted file mode 100644 index 201b22a6..00000000 --- a/vendor/miniflux/picofeed/lib/PicoFeed/Client/MaxSizeException.php +++ /dev/null @@ -1,12 +0,0 @@ -<?php - -namespace PicoFeed\Client; - -/** - * MaxSizeException Exception. - * - * @author Frederic Guillot - */ -class MaxSizeException extends ClientException -{ -} diff --git a/vendor/miniflux/picofeed/lib/PicoFeed/Client/Stream.php b/vendor/miniflux/picofeed/lib/PicoFeed/Client/Stream.php deleted file mode 100644 index 2e91d472..00000000 --- a/vendor/miniflux/picofeed/lib/PicoFeed/Client/Stream.php +++ /dev/null @@ -1,205 +0,0 @@ -<?php - -namespace PicoFeed\Client; - -use PicoFeed\Logging\Logger; - -/** - * Stream context HTTP client. - * - * @author Frederic Guillot - */ -class Stream extends Client -{ - /** - * Prepare HTTP headers. - * - * @return string[] - */ - private function prepareHeaders() - { - $headers = array( - 'Connection: close', - 'User-Agent: '.$this->user_agent, - ); - - // disable compression in passthrough mode. It could result in double - // compressed content which isn't decodeable by browsers - if (function_exists('gzdecode') && !$this->isPassthroughEnabled()) { - $headers[] = 'Accept-Encoding: gzip'; - } - - if ($this->etag) { - $headers[] = 'If-None-Match: '.$this->etag; - $headers[] = 'A-IM: feed'; - } - - if ($this->last_modified) { - $headers[] = 'If-Modified-Since: '.$this->last_modified; - } - - if ($this->proxy_username) { - $headers[] = 'Proxy-Authorization: Basic '.base64_encode($this->proxy_username.':'.$this->proxy_password); - } - - if ($this->username && $this->password) { - $headers[] = 'Authorization: Basic '.base64_encode($this->username.':'.$this->password); - } - - $headers = array_merge($headers, $this->request_headers); - - return $headers; - } - - /** - * Construct the final URL from location headers. - * - * @param array $headers List of HTTP response header - */ - private function setEffectiveUrl($headers) - { - foreach ($headers as $header) { - if (stripos($header, 'Location') === 0) { - list(, $value) = explode(': ', $header); - - $this->url = Url::resolve($value, $this->url); - } - } - } - - /** - * Prepare stream context. - * - * @return array - */ - private function prepareContext() - { - $context = array( - 'http' => array( - 'method' => 'GET', - 'protocol_version' => 1.1, - 'timeout' => $this->timeout, - 'max_redirects' => $this->max_redirects, - ), - ); - - if ($this->proxy_hostname) { - Logger::setMessage(get_called_class().' Proxy: '.$this->proxy_hostname.':'.$this->proxy_port); - - $context['http']['proxy'] = 'tcp://'.$this->proxy_hostname.':'.$this->proxy_port; - $context['http']['request_fulluri'] = true; - - if ($this->proxy_username) { - Logger::setMessage(get_called_class().' Proxy credentials: Yes'); - } else { - Logger::setMessage(get_called_class().' Proxy credentials: No'); - } - } - - $context['http']['header'] = implode("\r\n", $this->prepareHeaders()); - - return $context; - } - - /** - * Do the HTTP request. - * - * @return array HTTP response ['body' => ..., 'status' => ..., 'headers' => ...] - * @throws InvalidUrlException - * @throws MaxSizeException - * @throws TimeoutException - */ - public function doRequest() - { - $body = ''; - - // Create context - $context = stream_context_create($this->prepareContext()); - - // Make HTTP request - $stream = @fopen($this->url, 'r', false, $context); - if (!is_resource($stream)) { - throw new InvalidUrlException('Unable to establish a connection'); - } - - // Get HTTP headers response - $metadata = stream_get_meta_data($stream); - list($status, $headers) = HttpHeaders::parse($metadata['wrapper_data']); - - if ($this->isPassthroughEnabled()) { - header(':', true, $status); - - if (isset($headers['Content-Type'])) { - header('Content-Type: '.$headers['Content-Type']); - } - - fpassthru($stream); - } else { - // Get the entire body until the max size - $body = stream_get_contents($stream, $this->max_body_size + 1); - - // If the body size is too large abort everything - if (strlen($body) > $this->max_body_size) { - throw new MaxSizeException('Content size too large'); - } - - if ($metadata['timed_out']) { - throw new TimeoutException('Operation timeout'); - } - } - - fclose($stream); - - $this->setEffectiveUrl($metadata['wrapper_data']); - - return array( - 'status' => $status, - 'body' => $this->decodeBody($body, $headers), - 'headers' => $headers, - ); - } - - /** - * Decode body response according to the HTTP headers. - * - * @param string $body Raw body - * @param HttpHeaders $headers HTTP headers - * - * @return string - */ - public function decodeBody($body, HttpHeaders $headers) - { - if (isset($headers['Transfer-Encoding']) && $headers['Transfer-Encoding'] === 'chunked') { - $body = $this->decodeChunked($body); - } - - if (isset($headers['Content-Encoding']) && $headers['Content-Encoding'] === 'gzip') { - $body = gzdecode($body); - } - - return $body; - } - - /** - * Decode a chunked body. - * - * @param string $str Raw body - * - * @return string Decoded body - */ - public function decodeChunked($str) - { - for ($result = ''; !empty($str); $str = trim($str)) { - - // Get the chunk length - $pos = strpos($str, "\r\n"); - $len = hexdec(substr($str, 0, $pos)); - - // Append the chunk to the result - $result .= substr($str, $pos + 2, $len); - $str = substr($str, $pos + 2 + $len); - } - - return $result; - } -} diff --git a/vendor/miniflux/picofeed/lib/PicoFeed/Client/TimeoutException.php b/vendor/miniflux/picofeed/lib/PicoFeed/Client/TimeoutException.php deleted file mode 100644 index da98da12..00000000 --- a/vendor/miniflux/picofeed/lib/PicoFeed/Client/TimeoutException.php +++ /dev/null @@ -1,12 +0,0 @@ -<?php - -namespace PicoFeed\Client; - -/** - * TimeoutException Exception. - * - * @author Frederic Guillot - */ -class TimeoutException extends ClientException -{ -} diff --git a/vendor/miniflux/picofeed/lib/PicoFeed/Client/UnauthorizedException.php b/vendor/miniflux/picofeed/lib/PicoFeed/Client/UnauthorizedException.php deleted file mode 100644 index 81898b99..00000000 --- a/vendor/miniflux/picofeed/lib/PicoFeed/Client/UnauthorizedException.php +++ /dev/null @@ -1,10 +0,0 @@ -<?php - -namespace PicoFeed\Client; - -/** - * @author Bernhard Posselt - */ -class UnauthorizedException extends ClientException -{ -} diff --git a/vendor/miniflux/picofeed/lib/PicoFeed/Client/Url.php b/vendor/miniflux/picofeed/lib/PicoFeed/Client/Url.php deleted file mode 100644 index a9337988..00000000 --- a/vendor/miniflux/picofeed/lib/PicoFeed/Client/Url.php +++ /dev/null @@ -1,290 +0,0 @@ -<?php - -namespace PicoFeed\Client; - -/** - * URL class. - * - * @author Frederic Guillot - */ -class Url -{ - /** - * URL. - * - * @var string - */ - private $url = ''; - - /** - * URL components. - * - * @var array - */ - private $components = array(); - - /** - * Constructor. - * - * @param string $url URL - */ - public function __construct($url) - { - $this->url = $url; - $this->components = parse_url($url) ?: array(); - - // Issue with PHP < 5.4.7 and protocol relative url - if (version_compare(PHP_VERSION, '5.4.7', '<') && $this->isProtocolRelative()) { - $pos = strpos($this->components['path'], '/', 2); - - if ($pos === false) { - $pos = strlen($this->components['path']); - } - - $this->components['host'] = substr($this->components['path'], 2, $pos - 2); - $this->components['path'] = substr($this->components['path'], $pos); - } - } - - /** - * Shortcut method to get an absolute url from relative url. - * - * @static - * - * @param mixed $item_url Unknown url (can be relative or not) - * @param mixed $website_url Website url - * - * @return string - */ - public static function resolve($item_url, $website_url) - { - $link = is_string($item_url) ? new self($item_url) : $item_url; - $website = is_string($website_url) ? new self($website_url) : $website_url; - - if ($link->isRelativeUrl()) { - if ($link->isRelativePath()) { - return $link->getAbsoluteUrl($website->getBaseUrl($website->getBasePath())); - } - - return $link->getAbsoluteUrl($website->getBaseUrl()); - } elseif ($link->isProtocolRelative()) { - $link->setScheme($website->getScheme()); - } - - return $link->getAbsoluteUrl(); - } - - /** - * Shortcut method to get a base url. - * - * @static - * - * @param string $url - * - * @return string - */ - public static function base($url) - { - $link = new self($url); - - return $link->getBaseUrl(); - } - - /** - * Get the base URL. - * - * @param string $suffix Add a suffix to the url - * - * @return string - */ - public function getBaseUrl($suffix = '') - { - return $this->hasHost() ? $this->getScheme('://').$this->getHost().$this->getPort(':').$suffix : ''; - } - - /** - * Get the absolute URL. - * - * @param string $base_url Use this url as base url - * - * @return string - */ - public function getAbsoluteUrl($base_url = '') - { - if ($base_url) { - $base = new self($base_url); - $url = $base->getAbsoluteUrl().substr($this->getFullPath(), 1); - } else { - $url = $this->hasHost() ? $this->getBaseUrl().$this->getFullPath() : ''; - } - - return $url; - } - - /** - * Return true if the url is relative. - * - * @return bool - */ - public function isRelativeUrl() - { - return !$this->hasScheme() && !$this->isProtocolRelative(); - } - - /** - * Return true if the path is relative. - * - * @return bool - */ - public function isRelativePath() - { - $path = $this->getPath(); - - return empty($path) || $path{0} - !== '/'; - } - - /** - * Filters the path of a URI. - * - * Imported from Guzzle library: https://github.com/guzzle/psr7/blob/master/src/Uri.php#L568-L582 - * - * @param $path - * - * @return string - */ - public function filterPath($path, $charUnreserved = 'a-zA-Z0-9_\-\.~', $charSubDelims = '!\$&\'\(\)\*\+,;=') - { - return preg_replace_callback( - '/(?:[^'.$charUnreserved.$charSubDelims.':@\/%]+|%(?![A-Fa-f0-9]{2}))/', - function (array $matches) { return rawurlencode($matches[0]); }, - $path - ); - } - - /** - * Get the path. - * - * @return string - */ - public function getPath() - { - return $this->filterPath(empty($this->components['path']) ? '' : $this->components['path']); - } - - /** - * Get the base path. - * - * @return string - */ - public function getBasePath() - { - $current_path = $this->getPath(); - - $path = $this->isRelativePath() ? '/' : ''; - $path .= substr($current_path, -1) === '/' ? $current_path : dirname($current_path); - - return preg_replace('/\\\\\/|\/\//', '/', $path.'/'); - } - - /** - * Get the full path (path + querystring + fragment). - * - * @return string - */ - public function getFullPath() - { - $path = $this->isRelativePath() ? '/' : ''; - $path .= $this->getPath(); - $path .= empty($this->components['query']) ? '' : '?'.$this->components['query']; - $path .= empty($this->components['fragment']) ? '' : '#'.$this->components['fragment']; - - return $path; - } - - /** - * Get the hostname. - * - * @return string - */ - public function getHost() - { - return empty($this->components['host']) ? '' : $this->components['host']; - } - - /** - * Return true if the url has a hostname. - * - * @return bool - */ - public function hasHost() - { - return !empty($this->components['host']); - } - - /** - * Get the scheme. - * - * @param string $suffix Suffix to add when there is a scheme - * - * @return string - */ - public function getScheme($suffix = '') - { - return ($this->hasScheme() ? $this->components['scheme'] : 'http').$suffix; - } - - /** - * Set the scheme. - * - * @param string $scheme Set a scheme - * - * @return string - */ - public function setScheme($scheme) - { - $this->components['scheme'] = $scheme; - } - - /** - * Return true if the url has a scheme. - * - * @return bool - */ - public function hasScheme() - { - return !empty($this->components['scheme']); - } - - /** - * Get the port. - * - * @param string $prefix Prefix to add when there is a port - * - * @return string - */ - public function getPort($prefix = '') - { - return $this->hasPort() ? $prefix.$this->components['port'] : ''; - } - - /** - * Return true if the url has a port. - * - * @return bool - */ - public function hasPort() - { - return !empty($this->components['port']); - } - - /** - * Return true if the url is protocol relative (start with //). - * - * @return bool - */ - public function isProtocolRelative() - { - return strpos($this->url, '//') === 0; - } -} |