summaryrefslogtreecommitdiffstats
path: root/vendor/fguillot/picofeed/lib/PicoFeed/Client
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/fguillot/picofeed/lib/PicoFeed/Client')
-rw-r--r--vendor/fguillot/picofeed/lib/PicoFeed/Client/Client.php668
-rw-r--r--vendor/fguillot/picofeed/lib/PicoFeed/Client/ClientException.php14
-rw-r--r--vendor/fguillot/picofeed/lib/PicoFeed/Client/Curl.php384
-rw-r--r--vendor/fguillot/picofeed/lib/PicoFeed/Client/HttpHeaders.php79
-rw-r--r--vendor/fguillot/picofeed/lib/PicoFeed/Client/InvalidCertificateException.php12
-rw-r--r--vendor/fguillot/picofeed/lib/PicoFeed/Client/InvalidUrlException.php12
-rw-r--r--vendor/fguillot/picofeed/lib/PicoFeed/Client/MaxRedirectException.php12
-rw-r--r--vendor/fguillot/picofeed/lib/PicoFeed/Client/MaxSizeException.php12
-rw-r--r--vendor/fguillot/picofeed/lib/PicoFeed/Client/Stream.php201
-rw-r--r--vendor/fguillot/picofeed/lib/PicoFeed/Client/TimeoutException.php12
-rw-r--r--vendor/fguillot/picofeed/lib/PicoFeed/Client/Url.php290
11 files changed, 0 insertions, 1696 deletions
diff --git a/vendor/fguillot/picofeed/lib/PicoFeed/Client/Client.php b/vendor/fguillot/picofeed/lib/PicoFeed/Client/Client.php
deleted file mode 100644
index 24c619cdf..000000000
--- a/vendor/fguillot/picofeed/lib/PicoFeed/Client/Client.php
+++ /dev/null
@@ -1,668 +0,0 @@
-<?php
-
-namespace PicoFeed\Client;
-
-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 = '';
-
- /**
- * 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/fguillot/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->handleNotFoundResponse($response);
- $this->handleNormalResponse($response);
-
- return $this;
- }
-
- /**
- * Handle not modified response.
- *
- * @param array $response Client response
- */
- public 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 not found response.
- *
- * @param array $response Client response
- */
- public function handleNotFoundResponse(array $response)
- {
- if ($response['status'] == 404) {
- throw new InvalidUrlException('Resource not found');
- }
- }
-
- /**
- * Handle normal response.
- *
- * @param array $response Client response
- */
- public 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.
- *
- * @return string
- * @return \PicoFeed\Client\Client
- */
- 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;
- }
-}
diff --git a/vendor/fguillot/picofeed/lib/PicoFeed/Client/ClientException.php b/vendor/fguillot/picofeed/lib/PicoFeed/Client/ClientException.php
deleted file mode 100644
index b3a95c9f7..000000000
--- a/vendor/fguillot/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/fguillot/picofeed/lib/PicoFeed/Client/Curl.php b/vendor/fguillot/picofeed/lib/PicoFeed/Client/Curl.php
deleted file mode 100644
index 82ea87a44..000000000
--- a/vendor/fguillot/picofeed/lib/PicoFeed/Client/Curl.php
+++ /dev/null
@@ -1,384 +0,0 @@
-<?php
-
-namespace PicoFeed\Client;
-
-use PicoFeed\Logging\Logger;
-
-/**
- * cURL HTTP client.
- *
- * @author Frederic Guillot
- */
-class Curl extends Client
-{
- /**
- * 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']);
- }
-
- header($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;
- }
-
- 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)
- {
- $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)) {
- return $this->handleRedirection($headers['Location']);
- }
-
- return array(
- 'status' => $status,
- 'body' => $this->body,
- 'headers' => $headers,
- );
- }
-
- /**
- * Handle HTTP redirects
- *
- * @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->response_headers = array();
- $this->response_headers_count = 0;
-
- while (true) {
- ++$nb_redirects;
-
- if ($nb_redirects >= $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