X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FNetwork%2FHTTPRequest.php;h=6442295273857e7af78df608b614f9e97e30fa22;hb=335cd76baf1cf4352e56f779c898118eb9f36ff1;hp=798b0cdea8ab4472f1f6359b71e088ad2fad451a;hpb=933ea7c9ceefc9b38080f56ee214099a2b1118a4;p=friendica.git diff --git a/src/Network/HTTPRequest.php b/src/Network/HTTPRequest.php index 798b0cdea8..6442295273 100644 --- a/src/Network/HTTPRequest.php +++ b/src/Network/HTTPRequest.php @@ -28,11 +28,6 @@ use Friendica\Core\Config\IConfig; use Friendica\Core\System; use Friendica\Util\Network; use Friendica\Util\Profiler; -use GuzzleHttp\Client; -use GuzzleHttp\Exception\RequestException; -use Psr\Http\Message\RequestInterface; -use Psr\Http\Message\ResponseInterface; -use Psr\Http\Message\UriInterface; use Psr\Log\LoggerInterface; /** @@ -59,8 +54,12 @@ class HTTPRequest implements IHTTPRequest /** * {@inheritDoc} + * + * @param int $redirects The recursion counter for internal use - default 0 + * + * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public function get(string $url, bool $binary = false, array $opts = []) + public function get(string $url, array $opts = [], int &$redirects = 0) { $stamp1 = microtime(true); @@ -87,119 +86,119 @@ class HTTPRequest implements IHTTPRequest return CurlResult::createErrorCurl($url); } - $curlOptions = []; + $ch = @curl_init($url); - $curlOptions[CURLOPT_HEADER] = true; + if (($redirects > 8) || (!$ch)) { + return CurlResult::createErrorCurl($url); + } + + @curl_setopt($ch, CURLOPT_HEADER, true); if (!empty($opts['cookiejar'])) { - $curlOptions[CURLOPT_COOKIEJAR] = $opts["cookiejar"]; - $curlOptions[CURLOPT_COOKIEFILE] = $opts["cookiejar"]; + curl_setopt($ch, CURLOPT_COOKIEJAR, $opts["cookiejar"]); + curl_setopt($ch, CURLOPT_COOKIEFILE, $opts["cookiejar"]); } // These settings aren't needed. We're following the location already. - // $curlOptions[CURLOPT_FOLLOWLOCATION] =true; - // $curlOptions[CURLOPT_MAXREDIRS] = 5; + // @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + // @curl_setopt($ch, CURLOPT_MAXREDIRS, 5); if (!empty($opts['accept_content'])) { - $curlOptions[CURLOPT_HTTPHEADER][] = ['Accept: ' . $opts['accept_content']]; + curl_setopt( + $ch, + CURLOPT_HTTPHEADER, + ['Accept: ' . $opts['accept_content']] + ); } if (!empty($opts['header'])) { - $curlOptions[CURLOPT_HTTPHEADER][] = $opts['header']; + curl_setopt($ch, CURLOPT_HTTPHEADER, $opts['header']); } - $curlOptions[CURLOPT_RETURNTRANSFER] = true; - $curlOptions[CURLOPT_USERAGENT] = $this->getUserAgent(); + @curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + @curl_setopt($ch, CURLOPT_USERAGENT, $this->getUserAgent()); $range = intval($this->config->get('system', 'curl_range_bytes', 0)); if ($range > 0) { - $curlOptions[CURLOPT_RANGE] = '0-' . $range; + @curl_setopt($ch, CURLOPT_RANGE, '0-' . $range); } // Without this setting it seems as if some webservers send compressed content // This seems to confuse curl so that it shows this uncompressed. /// @todo We could possibly set this value to "gzip" or something similar - $curlOptions[CURLOPT_ENCODING] = ''; + curl_setopt($ch, CURLOPT_ENCODING, ''); if (!empty($opts['headers'])) { - $curlOptions[CURLOPT_HTTPHEADER][] = $opts['headers']; + @curl_setopt($ch, CURLOPT_HTTPHEADER, $opts['headers']); } if (!empty($opts['nobody'])) { - $curlOptions[CURLOPT_NOBODY] = $opts['nobody']; + @curl_setopt($ch, CURLOPT_NOBODY, $opts['nobody']); } - $curlOptions[CURLOPT_CONNECTTIMEOUT] = 10; + @curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); if (!empty($opts['timeout'])) { - $curlOptions[CURLOPT_TIMEOUT] = $opts['timeout']; + @curl_setopt($ch, CURLOPT_TIMEOUT, $opts['timeout']); } else { $curl_time = $this->config->get('system', 'curl_timeout', 60); - $curlOptions[CURLOPT_TIMEOUT] = intval($curl_time); + @curl_setopt($ch, CURLOPT_TIMEOUT, intval($curl_time)); } // by default we will allow self-signed certs // but you can override this $check_cert = $this->config->get('system', 'verifyssl'); - $curlOptions[CURLOPT_SSL_VERIFYPEER] = ($check_cert) ? true : false; + @curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, (($check_cert) ? true : false)); if ($check_cert) { - $curlOptions[CURLOPT_SSL_VERIFYHOST] = 2; + @curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); } $proxy = $this->config->get('system', 'proxy'); if (!empty($proxy)) { - $curlOptions[CURLOPT_HTTPPROXYTUNNEL] = 1; - $curlOptions[CURLOPT_PROXY] = $proxy; + @curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1); + @curl_setopt($ch, CURLOPT_PROXY, $proxy); $proxyuser = $this->config->get('system', 'proxyuser'); if (!empty($proxyuser)) { - $curlOptions[CURLOPT_PROXYUSERPWD] = $proxyuser; + @curl_setopt($ch, CURLOPT_PROXYUSERPWD, $proxyuser); } } if ($this->config->get('system', 'ipv4_resolve', false)) { - $curlOptions[CURLOPT_IPRESOLVE] = CURL_IPRESOLVE_V4; + curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); } - if ($binary) { - $curlOptions[CURLOPT_BINARYTRANSFER] = 1; + $logger = $this->logger; + + $s = @curl_exec($ch); + $curl_info = @curl_getinfo($ch); + + // Special treatment for HTTP Code 416 + // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/416 + if (($curl_info['http_code'] == 416) && ($range > 0)) { + @curl_setopt($ch, CURLOPT_RANGE, ''); + $s = @curl_exec($ch); + $curl_info = @curl_getinfo($ch); } - $onRedirect = function( - RequestInterface $request, - ResponseInterface $response, - UriInterface $uri - ) { - $this->logger->notice('Curl redirect.', ['url' => $request->getUri(), 'to' => $uri]); - }; + $curlResponse = new CurlResult($url, $s, $curl_info, curl_errno($ch), curl_error($ch)); - $client = new Client([ - 'allow_redirect' => [ - 'max' => 8, - 'on_redirect' => $onRedirect, - 'track_redirect' => true, - 'strict' => true, - 'referer' => true, - ], - 'curl' => $curlOptions - ]); - - try { - $response = $client->get($url); - return new GuzzleResponse($response, $url); - } catch (RequestException $exception) { - if ($exception->hasResponse()) { - return new GuzzleResponse($exception->getResponse(), $url, $exception->getCode(), $exception->getMessage()); - } else { - return new GuzzleResponse(null, $url, $exception->getCode(), $exception->getMessage()); - } - } finally { - $this->profiler->saveTimestamp($stamp1, 'network'); + if (!Network::isRedirectBlocked($url) && $curlResponse->isRedirectUrl()) { + $redirects++; + $this->logger->notice('Curl redirect.', ['url' => $url, 'to' => $curlResponse->getRedirectUrl()]); + @curl_close($ch); + return $this->get($curlResponse->getRedirectUrl(), $opts, $redirects); } + + @curl_close($ch); + + $this->profiler->saveTimestamp($stamp1, 'network'); + + return $curlResponse; } /** @@ -431,9 +430,9 @@ class HTTPRequest implements IHTTPRequest * * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public function fetch(string $url, bool $binary = false, int $timeout = 0, string $accept_content = '', string $cookiejar = '', int &$redirects = 0) + public function fetch(string $url, int $timeout = 0, string $accept_content = '', string $cookiejar = '', int &$redirects = 0) { - $ret = $this->fetchFull($url, $binary, $timeout, $accept_content, $cookiejar, $redirects); + $ret = $this->fetchFull($url, $timeout, $accept_content, $cookiejar, $redirects); return $ret->getBody(); } @@ -445,16 +444,16 @@ class HTTPRequest implements IHTTPRequest * * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public function fetchFull(string $url, bool $binary = false, int $timeout = 0, string $accept_content = '', string $cookiejar = '', int &$redirects = 0) + public function fetchFull(string $url, int $timeout = 0, string $accept_content = '', string $cookiejar = '', int &$redirects = 0) { return $this->get( $url, - $binary, [ 'timeout' => $timeout, 'accept_content' => $accept_content, 'cookiejar' => $cookiejar - ] + ], + $redirects ); }