From ef06fab744f1b33908b89672288ce3d5a50cf8ce Mon Sep 17 00:00:00 2001 From: Philipp Date: Sun, 11 Oct 2020 23:24:40 +0200 Subject: [PATCH 01/15] Revert "Update src/Network/GuzzleResponse.php" This reverts commit 79e667b3 --- src/Network/GuzzleResponse.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Network/GuzzleResponse.php b/src/Network/GuzzleResponse.php index b1bbaa965..18155d1d2 100644 --- a/src/Network/GuzzleResponse.php +++ b/src/Network/GuzzleResponse.php @@ -89,7 +89,12 @@ class GuzzleResponse extends Response implements IHTTPResult, ResponseInterface public function getContentType() { $contentTypes = $this->getHeader('Content-Type') ?? []; - return array_pop($contentTypes) ?? ''; + $countTypes = count($contentTypes); + if ($countTypes > 0) { + return $contentTypes[$countTypes - 1]; + } else { + return ''; + } } /** {@inheritDoc} */ From 16f5965fd444a4f5d28906623a5ceba5e41cc138 Mon Sep 17 00:00:00 2001 From: Philipp Date: Sun, 11 Oct 2020 23:25:14 +0200 Subject: [PATCH 02/15] Revert "Use last entry for Content-Type" This reverts commit e17befb7 --- src/Network/GuzzleResponse.php | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/Network/GuzzleResponse.php b/src/Network/GuzzleResponse.php index 18155d1d2..72d87ae9f 100644 --- a/src/Network/GuzzleResponse.php +++ b/src/Network/GuzzleResponse.php @@ -88,13 +88,7 @@ class GuzzleResponse extends Response implements IHTTPResult, ResponseInterface /** {@inheritDoc} */ public function getContentType() { - $contentTypes = $this->getHeader('Content-Type') ?? []; - $countTypes = count($contentTypes); - if ($countTypes > 0) { - return $contentTypes[$countTypes - 1]; - } else { - return ''; - } + return implode($this->getHeader('Content-Type')); } /** {@inheritDoc} */ From 36ba6b9f2d9a6ea07f68d369bca94cb4a3dd79a8 Mon Sep 17 00:00:00 2001 From: Philipp Date: Sun, 11 Oct 2020 23:25:19 +0200 Subject: [PATCH 03/15] Revert "Remove unnecessary exception message (avoid log flooding)" This reverts commit 8c718515 --- src/Network/HTTPRequest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Network/HTTPRequest.php b/src/Network/HTTPRequest.php index c37db4c9a..d85932ed8 100644 --- a/src/Network/HTTPRequest.php +++ b/src/Network/HTTPRequest.php @@ -215,9 +215,9 @@ class HTTPRequest implements IHTTPRequest } catch (TransferException $exception) { if ($exception instanceof RequestException && $exception->hasResponse()) { - return new GuzzleResponse($exception->getResponse(), $url, $exception->getCode(), ''); + return new GuzzleResponse($exception->getResponse(), $url, $exception->getCode(), $exception->getMessage()); } else { - return new CurlResult($url, '', ['http_code' => $exception->getCode()], $exception->getCode(), ''); + return new CurlResult($url, '', ['http_code' => $exception->getCode()], $exception->getCode(), $exception->getMessage()); } } finally { $this->profiler->saveTimestamp($stamp1, 'network'); From 88c95a352b70621dc54b5b95cea6c3d319818f40 Mon Sep 17 00:00:00 2001 From: Philipp Date: Sun, 11 Oct 2020 23:25:23 +0200 Subject: [PATCH 04/15] Revert "Fix redirect logging" This reverts commit b8314f0c --- src/Network/HTTPRequest.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Network/HTTPRequest.php b/src/Network/HTTPRequest.php index d85932ed8..1f6b26292 100644 --- a/src/Network/HTTPRequest.php +++ b/src/Network/HTTPRequest.php @@ -179,14 +179,12 @@ class HTTPRequest implements IHTTPRequest $curlOptions[CURLOPT_BINARYTRANSFER] = 1; } - $logger = $this->logger; - $onRedirect = function( RequestInterface $request, ResponseInterface $response, UriInterface $uri - ) use ($logger) { - $logger->notice('Curl redirect.', ['url' => $request->getUri(), 'to' => $uri]); + ) { + $this->logger->notice('Curl redirect.', ['url' => $request->getUri(), 'to' => $uri]); }; $onHeaders = function (ResponseInterface $response) use ($opts) { From 40349bfdc427dee9f5e65343a9ece4a18d0b3ee4 Mon Sep 17 00:00:00 2001 From: Philipp Date: Sun, 11 Oct 2020 23:25:29 +0200 Subject: [PATCH 05/15] Revert "IHTTPResult::getContentType is now a string again" This reverts commit 40b11442 --- src/Model/Photo.php | 2 +- src/Model/User.php | 2 +- src/Network/CurlResult.php | 6 +++--- src/Network/GuzzleResponse.php | 2 +- src/Network/IHTTPResult.php | 2 +- src/Network/Probe.php | 2 +- src/Util/Images.php | 18 ++++++++++-------- src/Util/ParseUrl.php | 8 +++++--- tests/src/Network/CurlResultTest.php | 8 ++++---- 9 files changed, 27 insertions(+), 23 deletions(-) diff --git a/src/Model/Photo.php b/src/Model/Photo.php index 5f8551fa2..dc60f25f3 100644 --- a/src/Model/Photo.php +++ b/src/Model/Photo.php @@ -427,7 +427,7 @@ class Photo $contType = $ret->getContentType(); } else { $img_str = ''; - $contType = ''; + $contType = []; } if ($quit_on_error && ($img_str == "")) { diff --git a/src/Model/User.php b/src/Model/User.php index e6f20f738..48d934896 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -1008,7 +1008,7 @@ class User $contType = $curlResult->getContentType(); } else { $img_str = ''; - $contType = ''; + $contType = []; } $type = Images::getMimeTypeByData($img_str, $photo, $contType); diff --git a/src/Network/CurlResult.php b/src/Network/CurlResult.php index 4ecdd68d1..ca1ead91d 100644 --- a/src/Network/CurlResult.php +++ b/src/Network/CurlResult.php @@ -37,7 +37,7 @@ class CurlResult implements IHTTPResult private $returnCode; /** - * @var string the content type of the Curl call + * @var string[] the content type of the Curl call */ private $contentType; @@ -223,9 +223,9 @@ class CurlResult implements IHTTPResult private function checkInfo() { if (isset($this->info['content_type'])) { - $this->contentType = $this->info['content_type']; + $this->contentType = [$this->info['content_type']]; } else { - $this->contentType = ''; + $this->contentType = []; } } diff --git a/src/Network/GuzzleResponse.php b/src/Network/GuzzleResponse.php index 72d87ae9f..69e88b402 100644 --- a/src/Network/GuzzleResponse.php +++ b/src/Network/GuzzleResponse.php @@ -88,7 +88,7 @@ class GuzzleResponse extends Response implements IHTTPResult, ResponseInterface /** {@inheritDoc} */ public function getContentType() { - return implode($this->getHeader('Content-Type')); + return $this->getHeader('Content-Type'); } /** {@inheritDoc} */ diff --git a/src/Network/IHTTPResult.php b/src/Network/IHTTPResult.php index 38a117628..acee2dde9 100644 --- a/src/Network/IHTTPResult.php +++ b/src/Network/IHTTPResult.php @@ -19,7 +19,7 @@ interface IHTTPResult /** * Returns the Content Type * - * @return string the Content Type + * @return string[] the Content Types */ public function getContentType(); diff --git a/src/Network/Probe.php b/src/Network/Probe.php index cfd036843..14dcdea33 100644 --- a/src/Network/Probe.php +++ b/src/Network/Probe.php @@ -429,7 +429,7 @@ class Probe } // If it isn't a HTML file then exit - if (($curlResult->getContentType() != '') && !strstr(strtolower($curlResult->getContentType()), 'html')) { + if (!in_array('html', $curlResult->getContentType())) { return false; } diff --git a/src/Util/Images.php b/src/Util/Images.php index 1b52b91a1..f0aefb9f2 100644 --- a/src/Util/Images.php +++ b/src/Util/Images.php @@ -75,23 +75,25 @@ class Images /** * Fetch image mimetype from the image data or guessing from the file name * - * @param string $image_data Image data - * @param string $filename File name (for guessing the type via the extension) - * @param string $mimeType possible mime type + * @param string $image_data Image data + * @param string $filename File name (for guessing the type via the extension) + * @param string[] $mimeTypes possible mime types * * @return string * @throws \Exception */ - public static function getMimeTypeByData(string $image_data, string $filename = '', string $mimeType = '') + public static function getMimeTypeByData(string $image_data, string $filename = '', array $mimeTypes = []) { - if (substr($mimeType, 0, 6) == 'image/') { - Logger::info('Using default mime type', ['filename' => $filename, 'mime' => $mimeType]); - return $mimeType; + foreach ($mimeTypes as $mimeType) { + if (substr($mimeType, 0, 6) == 'image/') { + Logger::info('Using default mime type', ['filename' => $filename, 'mime' => $mimeTypes]); + return $mimeType; + } } $image = @getimagesizefromstring($image_data); if (!empty($image['mime'])) { - Logger::info('Mime type detected via data', ['filename' => $filename, 'default' => $mimeType, 'mime' => $image['mime']]); + Logger::info('Mime type detected via data', ['filename' => $filename, 'default' => $mimeTypes, 'mime' => $image['mime']]); return $image['mime']; } diff --git a/src/Util/ParseUrl.php b/src/Util/ParseUrl.php index 1a81a256c..ee2bedd1e 100644 --- a/src/Util/ParseUrl.php +++ b/src/Util/ParseUrl.php @@ -166,7 +166,7 @@ class ParseUrl } // If it isn't a HTML file then exit - if (($curlResult->getContentType() != '') && !strstr(strtolower($curlResult->getContentType()), 'html')) { + if (!in_array('html', $curlResult->getContentType())) { return $siteinfo; } @@ -198,8 +198,10 @@ class ParseUrl $charset = ''; // Look for a charset, first in headers // Expected form: Content-Type: text/html; charset=ISO-8859-4 - if (preg_match('/charset=([a-z0-9-_.\/]+)/i', $curlResult->getContentType(), $matches)) { - $charset = trim(trim(trim(array_pop($matches)), ';,')); + foreach ($curlResult->getContentType() as $type) { + if (preg_match('/charset=([a-z0-9-_.\/]+)/i', $type, $matches)) { + $charset = trim(trim(trim(array_pop($matches)), ';,')); + } } // Then in body that gets precedence diff --git a/tests/src/Network/CurlResultTest.php b/tests/src/Network/CurlResultTest.php index 03a528812..4bc066b80 100644 --- a/tests/src/Network/CurlResultTest.php +++ b/tests/src/Network/CurlResultTest.php @@ -68,7 +68,7 @@ class CurlResultTest extends TestCase $this->assertFalse($curlResult->isRedirectUrl()); $this->assertSame($headerArray, $curlResult->getHeaders()); $this->assertSame($body, $curlResult->getBody()); - $this->assertSame('text/html; charset=utf-8', $curlResult->getContentType()); + $this->assertSame(['text/html; charset=utf-8'], $curlResult->getContentType()); $this->assertSame('https://test.local', $curlResult->getUrl()); $this->assertSame('https://test.local', $curlResult->getRedirectUrl()); } @@ -97,7 +97,7 @@ class CurlResultTest extends TestCase $this->assertTrue($curlResult->isRedirectUrl()); $this->assertSame($headerArray, $curlResult->getHeaders()); $this->assertSame($body, $curlResult->getBody()); - $this->assertSame('text/html; charset=utf-8', $curlResult->getContentType()); + $this->assertSame(['text/html; charset=utf-8'], $curlResult->getContentType()); $this->assertSame('https://test.local/test/it', $curlResult->getUrl()); $this->assertSame('https://test.other/test/it', $curlResult->getRedirectUrl()); } @@ -124,7 +124,7 @@ class CurlResultTest extends TestCase $this->assertFalse($curlResult->isRedirectUrl()); $this->assertSame($headerArray, $curlResult->getHeaders()); $this->assertSame($body, $curlResult->getBody()); - $this->assertSame('text/html; charset=utf-8', $curlResult->getContentType()); + $this->assertSame(['text/html; charset=utf-8'], $curlResult->getContentType()); $this->assertSame('https://test.local/test/it', $curlResult->getRedirectUrl()); $this->assertSame('Tested error', $curlResult->getError()); } @@ -152,7 +152,7 @@ class CurlResultTest extends TestCase $this->assertTrue($curlResult->isRedirectUrl()); $this->assertSame($headerArray, $curlResult->getHeaders()); $this->assertSame($body, $curlResult->getBody()); - $this->assertSame('text/html; charset=utf-8', $curlResult->getContentType()); + $this->assertSame(['text/html; charset=utf-8'], $curlResult->getContentType()); $this->assertSame('https://test.local/test/it?key=value', $curlResult->getUrl()); $this->assertSame('https://test.other/some/?key=value', $curlResult->getRedirectUrl()); } From 6fcbb9866f0a7b9db9f47299e80e23cd11d67aef Mon Sep 17 00:00:00 2001 From: Philipp Date: Sun, 11 Oct 2020 23:25:33 +0200 Subject: [PATCH 06/15] Revert "Fix Content-Type for `CurlResult` class" This reverts commit 02bc99f6 --- src/Network/CurlResult.php | 6 +++--- tests/src/Network/CurlResultTest.php | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Network/CurlResult.php b/src/Network/CurlResult.php index ca1ead91d..4ecdd68d1 100644 --- a/src/Network/CurlResult.php +++ b/src/Network/CurlResult.php @@ -37,7 +37,7 @@ class CurlResult implements IHTTPResult private $returnCode; /** - * @var string[] the content type of the Curl call + * @var string the content type of the Curl call */ private $contentType; @@ -223,9 +223,9 @@ class CurlResult implements IHTTPResult private function checkInfo() { if (isset($this->info['content_type'])) { - $this->contentType = [$this->info['content_type']]; + $this->contentType = $this->info['content_type']; } else { - $this->contentType = []; + $this->contentType = ''; } } diff --git a/tests/src/Network/CurlResultTest.php b/tests/src/Network/CurlResultTest.php index 4bc066b80..03a528812 100644 --- a/tests/src/Network/CurlResultTest.php +++ b/tests/src/Network/CurlResultTest.php @@ -68,7 +68,7 @@ class CurlResultTest extends TestCase $this->assertFalse($curlResult->isRedirectUrl()); $this->assertSame($headerArray, $curlResult->getHeaders()); $this->assertSame($body, $curlResult->getBody()); - $this->assertSame(['text/html; charset=utf-8'], $curlResult->getContentType()); + $this->assertSame('text/html; charset=utf-8', $curlResult->getContentType()); $this->assertSame('https://test.local', $curlResult->getUrl()); $this->assertSame('https://test.local', $curlResult->getRedirectUrl()); } @@ -97,7 +97,7 @@ class CurlResultTest extends TestCase $this->assertTrue($curlResult->isRedirectUrl()); $this->assertSame($headerArray, $curlResult->getHeaders()); $this->assertSame($body, $curlResult->getBody()); - $this->assertSame(['text/html; charset=utf-8'], $curlResult->getContentType()); + $this->assertSame('text/html; charset=utf-8', $curlResult->getContentType()); $this->assertSame('https://test.local/test/it', $curlResult->getUrl()); $this->assertSame('https://test.other/test/it', $curlResult->getRedirectUrl()); } @@ -124,7 +124,7 @@ class CurlResultTest extends TestCase $this->assertFalse($curlResult->isRedirectUrl()); $this->assertSame($headerArray, $curlResult->getHeaders()); $this->assertSame($body, $curlResult->getBody()); - $this->assertSame(['text/html; charset=utf-8'], $curlResult->getContentType()); + $this->assertSame('text/html; charset=utf-8', $curlResult->getContentType()); $this->assertSame('https://test.local/test/it', $curlResult->getRedirectUrl()); $this->assertSame('Tested error', $curlResult->getError()); } @@ -152,7 +152,7 @@ class CurlResultTest extends TestCase $this->assertTrue($curlResult->isRedirectUrl()); $this->assertSame($headerArray, $curlResult->getHeaders()); $this->assertSame($body, $curlResult->getBody()); - $this->assertSame(['text/html; charset=utf-8'], $curlResult->getContentType()); + $this->assertSame('text/html; charset=utf-8', $curlResult->getContentType()); $this->assertSame('https://test.local/test/it?key=value', $curlResult->getUrl()); $this->assertSame('https://test.other/some/?key=value', $curlResult->getRedirectUrl()); } From 0449077126fa94730baa1526b9c38b8faefd1d5d Mon Sep 17 00:00:00 2001 From: Philipp Date: Sun, 11 Oct 2020 23:25:40 +0200 Subject: [PATCH 07/15] Revert "Fix IHTTPResult::getHeader() - Now returns a string array, like expected - Fix usages - Fix dataset" This reverts commit 80bd0a4d --- src/Content/Text/BBCode.php | 4 +-- src/Model/Photo.php | 5 ++-- src/Model/User.php | 6 ++--- src/Network/CurlResult.php | 10 +++----- src/Network/IHTTPResult.php | 4 +-- src/Network/Probe.php | 2 +- src/Protocol/OStatus.php | 4 +-- src/Util/Images.php | 18 ++++++-------- src/Util/ParseUrl.php | 8 +++--- tests/datasets/curl/about.head.php | 32 ++++++++++++------------ tests/datasets/curl/about.redirect.php | 34 +++++++++++++------------- 11 files changed, 59 insertions(+), 68 deletions(-) diff --git a/src/Content/Text/BBCode.php b/src/Content/Text/BBCode.php index 5256c3c8a..594cd9a6c 100644 --- a/src/Content/Text/BBCode.php +++ b/src/Content/Text/BBCode.php @@ -491,8 +491,8 @@ class BBCode } $i = $curlResult->getBody(); - $contType = $curlResult->getContentType(); - $type = Images::getMimeTypeByData($i, $mtch[1], $contType); + $type = $curlResult->getContentType(); + $type = Images::getMimeTypeByData($i, $mtch[1], $type); if ($i) { $Image = new Image($i, $type); diff --git a/src/Model/Photo.php b/src/Model/Photo.php index dc60f25f3..6380f4278 100644 --- a/src/Model/Photo.php +++ b/src/Model/Photo.php @@ -424,17 +424,16 @@ class Photo if (!empty($image_url)) { $ret = DI::httpRequest()->get($image_url, true); $img_str = $ret->getBody(); - $contType = $ret->getContentType(); + $type = $ret->getContentType(); } else { $img_str = ''; - $contType = []; } if ($quit_on_error && ($img_str == "")) { return false; } - $type = Images::getMimeTypeByData($img_str, $image_url, $contType); + $type = Images::getMimeTypeByData($img_str, $image_url, $type); $Image = new Image($img_str, $type); if ($Image->isValid()) { diff --git a/src/Model/User.php b/src/Model/User.php index 48d934896..68c42e40e 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -1005,13 +1005,13 @@ class User $curlResult = DI::httpRequest()->get($photo, true); if ($curlResult->isSuccess()) { $img_str = $curlResult->getBody(); - $contType = $curlResult->getContentType(); + $type = $curlResult->getContentType(); } else { $img_str = ''; - $contType = []; + $type = ''; } - $type = Images::getMimeTypeByData($img_str, $photo, $contType); + $type = Images::getMimeTypeByData($img_str, $photo, $type); $Image = new Image($img_str, $type); if ($Image->isValid()) { diff --git a/src/Network/CurlResult.php b/src/Network/CurlResult.php index 4ecdd68d1..b2eefcbaa 100644 --- a/src/Network/CurlResult.php +++ b/src/Network/CurlResult.php @@ -245,7 +245,7 @@ class CurlResult implements IHTTPResult public function getHeader($header) { if (empty($header)) { - return []; + return ''; } $header = strtolower(trim($header)); @@ -256,7 +256,7 @@ class CurlResult implements IHTTPResult return $headers[$header]; } - return []; + return ''; } /** {@inheritDoc} */ @@ -289,11 +289,7 @@ class CurlResult implements IHTTPResult $parts = explode(':', $line); $headerfield = strtolower(trim(array_shift($parts))); $headerdata = trim(implode(':', $parts)); - if (empty($this->header_fields[$headerfield])) { - $this->header_fields[$headerfield] = [$headerdata]; - } elseif (!in_array($headerdata, $this->header_fields[$headerfield])) { - $this->header_fields[$headerfield][] = $headerdata; - } + $this->header_fields[$headerfield] = $headerdata; } return $this->header_fields; diff --git a/src/Network/IHTTPResult.php b/src/Network/IHTTPResult.php index acee2dde9..77ee86976 100644 --- a/src/Network/IHTTPResult.php +++ b/src/Network/IHTTPResult.php @@ -19,7 +19,7 @@ interface IHTTPResult /** * Returns the Content Type * - * @return string[] the Content Types + * @return string the Content Type */ public function getContentType(); @@ -29,7 +29,7 @@ interface IHTTPResult * * @param string $header optional header field. Return all fields if empty * - * @return string[] the headers or the specified content of the header variable + * @return string the headers or the specified content of the header variable */ public function getHeader($header); diff --git a/src/Network/Probe.php b/src/Network/Probe.php index 14dcdea33..cfd036843 100644 --- a/src/Network/Probe.php +++ b/src/Network/Probe.php @@ -429,7 +429,7 @@ class Probe } // If it isn't a HTML file then exit - if (!in_array('html', $curlResult->getContentType())) { + if (($curlResult->getContentType() != '') && !strstr(strtolower($curlResult->getContentType()), 'html')) { return false; } diff --git a/src/Protocol/OStatus.php b/src/Protocol/OStatus.php index 1d95a6f3a..ef38aaebe 100644 --- a/src/Protocol/OStatus.php +++ b/src/Protocol/OStatus.php @@ -747,7 +747,7 @@ class OStatus $xml = ''; if ($curlResult->inHeader('Content-Type') && - in_array('application/atom+xml', $curlResult->getHeader('Content-Type'))) { + stristr($curlResult->getHeader('Content-Type'), 'application/atom+xml')) { $xml = $curlResult->getBody(); } @@ -941,7 +941,7 @@ class OStatus $xml = ''; if ($curlResult->inHeader('Content-Type') && - in_array('application/atom+xml', $curlResult->getHeader('Content-Type'))) { + stristr($curlResult->getHeader('Content-Type'), 'application/atom+xml')) { Logger::log('Directly fetched XML for URI ' . $related_uri, Logger::DEBUG); $xml = $curlResult->getBody(); } diff --git a/src/Util/Images.php b/src/Util/Images.php index f0aefb9f2..f39b0db00 100644 --- a/src/Util/Images.php +++ b/src/Util/Images.php @@ -75,25 +75,23 @@ class Images /** * Fetch image mimetype from the image data or guessing from the file name * - * @param string $image_data Image data - * @param string $filename File name (for guessing the type via the extension) - * @param string[] $mimeTypes possible mime types + * @param string $image_data Image data + * @param string $filename File name (for guessing the type via the extension) + * @param string $mime default mime type * * @return string * @throws \Exception */ - public static function getMimeTypeByData(string $image_data, string $filename = '', array $mimeTypes = []) + public static function getMimeTypeByData(string $image_data, string $filename = '', string $mime = '') { - foreach ($mimeTypes as $mimeType) { - if (substr($mimeType, 0, 6) == 'image/') { - Logger::info('Using default mime type', ['filename' => $filename, 'mime' => $mimeTypes]); - return $mimeType; - } + if (substr($mime, 0, 6) == 'image/') { + Logger::info('Using default mime type', ['filename' => $filename, 'mime' => $mime]); + return $mime; } $image = @getimagesizefromstring($image_data); if (!empty($image['mime'])) { - Logger::info('Mime type detected via data', ['filename' => $filename, 'default' => $mimeTypes, 'mime' => $image['mime']]); + Logger::info('Mime type detected via data', ['filename' => $filename, 'default' => $mime, 'mime' => $image['mime']]); return $image['mime']; } diff --git a/src/Util/ParseUrl.php b/src/Util/ParseUrl.php index ee2bedd1e..1a81a256c 100644 --- a/src/Util/ParseUrl.php +++ b/src/Util/ParseUrl.php @@ -166,7 +166,7 @@ class ParseUrl } // If it isn't a HTML file then exit - if (!in_array('html', $curlResult->getContentType())) { + if (($curlResult->getContentType() != '') && !strstr(strtolower($curlResult->getContentType()), 'html')) { return $siteinfo; } @@ -198,10 +198,8 @@ class ParseUrl $charset = ''; // Look for a charset, first in headers // Expected form: Content-Type: text/html; charset=ISO-8859-4 - foreach ($curlResult->getContentType() as $type) { - if (preg_match('/charset=([a-z0-9-_.\/]+)/i', $type, $matches)) { - $charset = trim(trim(trim(array_pop($matches)), ';,')); - } + if (preg_match('/charset=([a-z0-9-_.\/]+)/i', $curlResult->getContentType(), $matches)) { + $charset = trim(trim(trim(array_pop($matches)), ';,')); } // Then in body that gets precedence diff --git a/tests/datasets/curl/about.head.php b/tests/datasets/curl/about.head.php index b7773b81a..d0be0feb4 100644 --- a/tests/datasets/curl/about.head.php +++ b/tests/datasets/curl/about.head.php @@ -1,20 +1,20 @@ [''], - 'date' => ['Thu, 11 Oct 2018 18:43:54 GMT'], - 'content-type' => ['text/html; charset=utf-8'], - 'vary' => ['Accept-Encoding'], - 'server' => ['Mastodon'], - 'x-frame-options' => ['DENY', 'SAMEORIGIN'], - 'x-content-type-options' => ['nosniff'], - 'x-xss-protection' => ['1; mode=block'], - 'etag' => ['W/"706e6c48957e1d46ecf9d7597a7880af"'], - 'cache-control' => ['max-age=0, private, must-revalidate'], - 'set-cookie' => ['_mastodon_session=v3kcy%2FW3aZYBBvZUohuwksEKwzYIyEUlEuJ1KqTAfWPKvVQq%2F4UuJ39zp621VyfpQNlvY46TL%2FYutzXowSLYQBNFCJcrEiF04aU0TdtHls9zynMiyeHhoVgCijOXWXNt9%2FCmpQ49RkNEujkv9NaJ0cum32MCVZKjE9%2BMKmLM%2F8ZygZeLBGJ7sg%3D%3D--QGIiU0%2FpXc3Aym8F--he2iRRPePOdtEs3z%2BufSXg%3D%3D; path=/; secure; HttpOnly'], - 'x-request-id' => ['a0c0b8e7-cd60-4efa-b79b-cf1b0d5a0784'], - 'x-runtime' => ['0.049566'], - 'strict-transport-security' => ['max-age=31536000; includeSubDomains; preload'], - 'referrer-policy' => ['same-origin'], - 'content-security-policy' => ["frame-ancestors 'none'; script-src 'self'; object-src 'self'; img-src * data: blob:; media-src 'self' data:; font-src 'self' data: https://fonts.gstatic.com/; connect-src 'self' blob: wss://mastodonten.de"], + 'http/2 200' => '', + 'date' => 'Thu, 11 Oct 2018 18:43:54 GMT', + 'content-type' => 'text/html; charset=utf-8', + 'vary' => 'Accept-Encoding', + 'server' => 'Mastodon', + 'x-frame-options' => 'SAMEORIGIN', + 'x-content-type-options' => 'nosniff', + 'x-xss-protection' => '1; mode=block', + 'etag' => 'W/"706e6c48957e1d46ecf9d7597a7880af"', + 'cache-control' => 'max-age=0, private, must-revalidate', + 'set-cookie' => '_mastodon_session=v3kcy%2FW3aZYBBvZUohuwksEKwzYIyEUlEuJ1KqTAfWPKvVQq%2F4UuJ39zp621VyfpQNlvY46TL%2FYutzXowSLYQBNFCJcrEiF04aU0TdtHls9zynMiyeHhoVgCijOXWXNt9%2FCmpQ49RkNEujkv9NaJ0cum32MCVZKjE9%2BMKmLM%2F8ZygZeLBGJ7sg%3D%3D--QGIiU0%2FpXc3Aym8F--he2iRRPePOdtEs3z%2BufSXg%3D%3D; path=/; secure; HttpOnly', + 'x-request-id' => 'a0c0b8e7-cd60-4efa-b79b-cf1b0d5a0784', + 'x-runtime' => '0.049566', + 'strict-transport-security' => 'max-age=31536000; includeSubDomains; preload', + 'referrer-policy' => 'same-origin', + 'content-security-policy' => "frame-ancestors 'none'; script-src 'self'; object-src 'self'; img-src * data: blob:; media-src 'self' data:; font-src 'self' data: https://fonts.gstatic.com/; connect-src 'self' blob: wss://mastodonten.de", ]; diff --git a/tests/datasets/curl/about.redirect.php b/tests/datasets/curl/about.redirect.php index f01689aad..5ae3fd88f 100644 --- a/tests/datasets/curl/about.redirect.php +++ b/tests/datasets/curl/about.redirect.php @@ -1,21 +1,21 @@ [''], - 'date' => ['Thu, 11 Oct 2018 18:43:54 GMT'], - 'content-type' => ['text/html; charset=utf-8'], - 'vary' => ['Accept-Encoding'], - 'server' => ['Mastodon'], - 'location' => ['https://test.other/some/'], - 'x-frame-options' => ['DENY', 'SAMEORIGIN'], - 'x-content-type-options' => ['nosniff'], - 'x-xss-protection' => ['1; mode=block'], - 'etag' => ['W/"706e6c48957e1d46ecf9d7597a7880af"'], - 'cache-control' => ['max-age=0, private, must-revalidate'], - 'set-cookie' => ['_mastodon_session=v3kcy%2FW3aZYBBvZUohuwksEKwzYIyEUlEuJ1KqTAfWPKvVQq%2F4UuJ39zp621VyfpQNlvY46TL%2FYutzXowSLYQBNFCJcrEiF04aU0TdtHls9zynMiyeHhoVgCijOXWXNt9%2FCmpQ49RkNEujkv9NaJ0cum32MCVZKjE9%2BMKmLM%2F8ZygZeLBGJ7sg%3D%3D--QGIiU0%2FpXc3Aym8F--he2iRRPePOdtEs3z%2BufSXg%3D%3D; path=/; secure; HttpOnly'], - 'x-request-id' => ['a0c0b8e7-cd60-4efa-b79b-cf1b0d5a0784'], - 'x-runtime' => ['0.049566'], - 'strict-transport-security' => ['max-age=31536000; includeSubDomains; preload'], - 'referrer-policy' => ['same-origin'], - 'content-security-policy' => ["frame-ancestors 'none'; script-src 'self'; object-src 'self'; img-src * data: blob:; media-src 'self' data:; font-src 'self' data: https://fonts.gstatic.com/; connect-src 'self' blob: wss://mastodonten.de"], + 'http/2 301' => '', + 'date' => 'Thu, 11 Oct 2018 18:43:54 GMT', + 'content-type' => 'text/html; charset=utf-8', + 'vary' => 'Accept-Encoding', + 'server' => 'Mastodon', + 'location' => 'https://test.other/some/', + 'x-frame-options' => 'SAMEORIGIN', + 'x-content-type-options' => 'nosniff', + 'x-xss-protection' => '1; mode=block', + 'etag' => 'W/"706e6c48957e1d46ecf9d7597a7880af"', + 'cache-control' => 'max-age=0, private, must-revalidate', + 'set-cookie' => '_mastodon_session=v3kcy%2FW3aZYBBvZUohuwksEKwzYIyEUlEuJ1KqTAfWPKvVQq%2F4UuJ39zp621VyfpQNlvY46TL%2FYutzXowSLYQBNFCJcrEiF04aU0TdtHls9zynMiyeHhoVgCijOXWXNt9%2FCmpQ49RkNEujkv9NaJ0cum32MCVZKjE9%2BMKmLM%2F8ZygZeLBGJ7sg%3D%3D--QGIiU0%2FpXc3Aym8F--he2iRRPePOdtEs3z%2BufSXg%3D%3D; path=/; secure; HttpOnly', + 'x-request-id' => 'a0c0b8e7-cd60-4efa-b79b-cf1b0d5a0784', + 'x-runtime' => '0.049566', + 'strict-transport-security' => 'max-age=31536000; includeSubDomains; preload', + 'referrer-policy' => 'same-origin', + 'content-security-policy' => "frame-ancestors 'none'; script-src 'self'; object-src 'self'; img-src * data: blob:; media-src 'self' data:; font-src 'self' data: https://fonts.gstatic.com/; connect-src 'self' blob: wss://mastodonten.de", ]; From 2e8ad098b9917dca48889c6bb36e167596e475a7 Mon Sep 17 00:00:00 2001 From: Philipp Date: Sun, 11 Oct 2020 23:25:47 +0200 Subject: [PATCH 08/15] Revert "HTTPRequest: Replace getInfo() with new parameter 'content_length'" This reverts commit f3cd973c --- src/Network/CurlResult.php | 6 ++++++ src/Network/GuzzleResponse.php | 5 +++++ src/Network/HTTPRequest.php | 13 ++----------- src/Network/IHTTPRequest.php | 1 - src/Network/IHTTPResult.php | 5 +++++ src/Network/Probe.php | 7 ++++++- src/Util/ParseUrl.php | 7 ++++++- 7 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/Network/CurlResult.php b/src/Network/CurlResult.php index b2eefcbaa..b0e801010 100644 --- a/src/Network/CurlResult.php +++ b/src/Network/CurlResult.php @@ -319,6 +319,12 @@ class CurlResult implements IHTTPResult return $this->body; } + /** {@inheritDoc} */ + public function getInfo() + { + return $this->info; + } + /** {@inheritDoc} */ public function isRedirectUrl() { diff --git a/src/Network/GuzzleResponse.php b/src/Network/GuzzleResponse.php index 69e88b402..c6cab7c9e 100644 --- a/src/Network/GuzzleResponse.php +++ b/src/Network/GuzzleResponse.php @@ -121,6 +121,11 @@ class GuzzleResponse extends Response implements IHTTPResult, ResponseInterface return $this->url; } + public function getInfo() + { + // TODO: Implement getInfo() method. + } + /** {@inheritDoc} */ public function isRedirectUrl() { diff --git a/src/Network/HTTPRequest.php b/src/Network/HTTPRequest.php index 1f6b26292..ffc095b66 100644 --- a/src/Network/HTTPRequest.php +++ b/src/Network/HTTPRequest.php @@ -30,7 +30,6 @@ use Friendica\Util\Network; use Friendica\Util\Profiler; use GuzzleHttp\Client; use GuzzleHttp\Exception\RequestException; -use GuzzleHttp\Exception\TransferException; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\UriInterface; @@ -187,13 +186,6 @@ class HTTPRequest implements IHTTPRequest $this->logger->notice('Curl redirect.', ['url' => $request->getUri(), 'to' => $uri]); }; - $onHeaders = function (ResponseInterface $response) use ($opts) { - if (!empty($opts['content_length']) && - $response->getHeaderLine('Content-Length') > $opts['content_length']) { - throw new TransferException('The file is too big!'); - } - }; - $client = new Client([ 'allow_redirect' => [ 'max' => 8, @@ -210,9 +202,8 @@ class HTTPRequest implements IHTTPRequest try { $response = $client->get($url); return new GuzzleResponse($response, $url); - } catch (TransferException $exception) { - if ($exception instanceof RequestException && - $exception->hasResponse()) { + } catch (RequestException $exception) { + if ($exception->hasResponse()) { return new GuzzleResponse($exception->getResponse(), $url, $exception->getCode(), $exception->getMessage()); } else { return new CurlResult($url, '', ['http_code' => $exception->getCode()], $exception->getCode(), $exception->getMessage()); diff --git a/src/Network/IHTTPRequest.php b/src/Network/IHTTPRequest.php index 49993085e..3f9b7f27a 100644 --- a/src/Network/IHTTPRequest.php +++ b/src/Network/IHTTPRequest.php @@ -75,7 +75,6 @@ interface IHTTPRequest * 'nobody' => only return the header * 'cookiejar' => path to cookie jar file * 'header' => header array - * 'content_length' => int maximum File content length * * @return IHTTPResult */ diff --git a/src/Network/IHTTPResult.php b/src/Network/IHTTPResult.php index 77ee86976..5904bcfa3 100644 --- a/src/Network/IHTTPResult.php +++ b/src/Network/IHTTPResult.php @@ -82,6 +82,11 @@ interface IHTTPResult */ public function getBody(); + /** + * @return array + */ + public function getInfo(); + /** * @return boolean */ diff --git a/src/Network/Probe.php b/src/Network/Probe.php index cfd036843..3fe035286 100644 --- a/src/Network/Probe.php +++ b/src/Network/Probe.php @@ -423,11 +423,16 @@ class Probe */ private static function getHideStatus($url) { - $curlResult = DI::httpRequest()->get($url, false, ['content_length' => 1000000]); + $curlResult = DI::httpRequest()->get($url); if (!$curlResult->isSuccess()) { return false; } + // If the file is too large then exit + if (($curlResult->getInfo()['download_content_length'] ?? 0) > 1000000) { + return false; + } + // If it isn't a HTML file then exit if (($curlResult->getContentType() != '') && !strstr(strtolower($curlResult->getContentType()), 'html')) { return false; diff --git a/src/Util/ParseUrl.php b/src/Util/ParseUrl.php index 1a81a256c..c3cbda70e 100644 --- a/src/Util/ParseUrl.php +++ b/src/Util/ParseUrl.php @@ -160,11 +160,16 @@ class ParseUrl return $siteinfo; } - $curlResult = DI::httpRequest()->get($url, false, ['content_length' => 1000000]); + $curlResult = DI::httpRequest()->get($url); if (!$curlResult->isSuccess()) { return $siteinfo; } + // If the file is too large then exit + if (($curlResult->getInfo()['download_content_length'] ?? 0) > 1000000) { + return $siteinfo; + } + // If it isn't a HTML file then exit if (($curlResult->getContentType() != '') && !strstr(strtolower($curlResult->getContentType()), 'html')) { return $siteinfo; From 9536a0e39c8dc41f474a3f0d8f077c62987909c6 Mon Sep 17 00:00:00 2001 From: Philipp Date: Sun, 11 Oct 2020 23:25:51 +0200 Subject: [PATCH 09/15] Revert "Use CurlResult for failed HTTPRequests (legacy usage)" This reverts commit 1a42f35a --- src/Network/HTTPRequest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Network/HTTPRequest.php b/src/Network/HTTPRequest.php index ffc095b66..1ced5fca7 100644 --- a/src/Network/HTTPRequest.php +++ b/src/Network/HTTPRequest.php @@ -206,7 +206,7 @@ class HTTPRequest implements IHTTPRequest if ($exception->hasResponse()) { return new GuzzleResponse($exception->getResponse(), $url, $exception->getCode(), $exception->getMessage()); } else { - return new CurlResult($url, '', ['http_code' => $exception->getCode()], $exception->getCode(), $exception->getMessage()); + return new GuzzleResponse(null, $url, $exception->getCode(), $exception->getMessage()); } } finally { $this->profiler->saveTimestamp($stamp1, 'network'); From 4b59fe4cf7e8068736af216600fed72a2027f844 Mon Sep 17 00:00:00 2001 From: Philipp Date: Sun, 11 Oct 2020 23:25:55 +0200 Subject: [PATCH 10/15] Revert "Update lock" This reverts commit 64004cf1 --- composer.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.lock b/composer.lock index 02a31227a..0d650ad15 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "6c141820d2160b278dffecc3e89f86e3", + "content-hash": "aa279ba22954af464cd7b4a5e2d74eec", "packages": [ { "name": "asika/simple-console", From 069753416d75fa63d6e476ae5706f30b43c9730f Mon Sep 17 00:00:00 2001 From: Philipp Date: Sun, 11 Oct 2020 23:26:03 +0200 Subject: [PATCH 11/15] Revert "Fix IHTTPResult::getHeader/s() - Split functionality "getHeader()" and "getHeaders()" analog to IMessageInterface::getHeader/s() - Fix functionality at various places - Adapt CurlResultTest" This reverts commit 933ea7c9 --- mod/parse_url.php | 11 +++++------ src/Network/CurlResult.php | 18 ++++++------------ src/Network/HTTPRequest.php | 3 ++- src/Network/IHTTPResult.php | 22 +++------------------- src/Protocol/DFRN.php | 4 ++-- src/Protocol/OStatus.php | 6 ++---- src/Protocol/Salmon.php | 2 +- src/Util/ParseUrl.php | 3 ++- tests/datasets/curl/about.head.php | 20 -------------------- tests/datasets/curl/about.redirect.php | 21 --------------------- tests/src/Network/CurlResultTest.php | 14 +++++--------- 11 files changed, 28 insertions(+), 96 deletions(-) delete mode 100644 tests/datasets/curl/about.head.php delete mode 100644 tests/datasets/curl/about.redirect.php diff --git a/mod/parse_url.php b/mod/parse_url.php index 39aae4a5a..a1faab6ef 100644 --- a/mod/parse_url.php +++ b/mod/parse_url.php @@ -90,13 +90,12 @@ function parse_url_content(App $a) if ($curlResponse->isSuccess()) { // Convert the header fields into an array $hdrs = []; - $h = $curlResponse->getHeaders(); + $h = explode("\n", $curlResponse->getHeader()); foreach ($h as $l) { - foreach ($l as $k => $v) { - if (empty($hdrs[$k])) { - $hdrs[$k] = $v; - } - $hdrs[$k] .= " " . $v; + $header = array_map('trim', explode(':', trim($l), 2)); + if (count($header) == 2) { + list($k, $v) = $header; + $hdrs[$k] = $v; } } $type = null; diff --git a/src/Network/CurlResult.php b/src/Network/CurlResult.php index b0e801010..1187e45eb 100644 --- a/src/Network/CurlResult.php +++ b/src/Network/CurlResult.php @@ -242,29 +242,23 @@ class CurlResult implements IHTTPResult } /** {@inheritDoc} */ - public function getHeader($header) + public function getHeader(string $field = '') { - if (empty($header)) { - return ''; + if (empty($field)) { + return $this->header; } - $header = strtolower(trim($header)); + $field = strtolower(trim($field)); $headers = $this->getHeaderArray(); - if (isset($headers[$header])) { - return $headers[$header]; + if (isset($headers[$field])) { + return $headers[$field]; } return ''; } - /** {@inheritDoc} */ - public function getHeaders() - { - return $this->getHeaderArray(); - } - /** {@inheritDoc} */ public function inHeader(string $field) { diff --git a/src/Network/HTTPRequest.php b/src/Network/HTTPRequest.php index 1ced5fca7..37d268f61 100644 --- a/src/Network/HTTPRequest.php +++ b/src/Network/HTTPRequest.php @@ -465,7 +465,8 @@ class HTTPRequest implements IHTTPRequest 'timeout' => $timeout, 'accept_content' => $accept_content, 'cookiejar' => $cookiejar - ] + ], + $redirects ); } diff --git a/src/Network/IHTTPResult.php b/src/Network/IHTTPResult.php index 5904bcfa3..be190c80c 100644 --- a/src/Network/IHTTPResult.php +++ b/src/Network/IHTTPResult.php @@ -2,8 +2,6 @@ namespace Friendica\Network; -use Psr\Http\Message\MessageInterface; - /** * Temporary class to map Friendica used variables based on PSR-7 HTTPResponse */ @@ -25,25 +23,15 @@ interface IHTTPResult /** * Returns the headers - * @see MessageInterface::getHeader() * - * @param string $header optional header field. Return all fields if empty + * @param string $field optional header field. Return all fields if empty * * @return string the headers or the specified content of the header variable */ - public function getHeader($header); - - /** - * Returns all headers - * @see MessageInterface::getHeaders() - * - * @return string[][] - */ - public function getHeaders(); + public function getHeader(string $field = ''); /** * Check if a specified header exists - * @see MessageInterface::hasHeader() * * @param string $field header field * @@ -53,10 +41,8 @@ interface IHTTPResult /** * Returns the headers as an associated array - * @see MessageInterface::getHeaders() - * @deprecated * - * @return string[][] associated header array + * @return array associated header array */ public function getHeaderArray(); @@ -76,8 +62,6 @@ interface IHTTPResult public function getRedirectUrl(); /** - * @see MessageInterface::getBody() - * * @return string */ public function getBody(); diff --git a/src/Protocol/DFRN.php b/src/Protocol/DFRN.php index f718e0a74..d20864cf7 100644 --- a/src/Protocol/DFRN.php +++ b/src/Protocol/DFRN.php @@ -1358,7 +1358,7 @@ class DFRN return -9; // timed out } - if (($curl_stat == 503) && $postResult->inHeader('retry-after')) { + if (($curl_stat == 503) && stristr($postResult->getHeader(), 'retry-after')) { return -10; } @@ -1453,7 +1453,7 @@ class DFRN return -9; // timed out } - if (($curl_stat == 503) && $postResult->inHeader('retry-after')) { + if (($curl_stat == 503) && (stristr($postResult->getHeader(), 'retry-after'))) { return -10; } diff --git a/src/Protocol/OStatus.php b/src/Protocol/OStatus.php index ef38aaebe..0635be87d 100644 --- a/src/Protocol/OStatus.php +++ b/src/Protocol/OStatus.php @@ -746,8 +746,7 @@ class OStatus $xml = ''; - if ($curlResult->inHeader('Content-Type') && - stristr($curlResult->getHeader('Content-Type'), 'application/atom+xml')) { + if (stristr($curlResult->getHeader(), 'Content-Type: application/atom+xml')) { $xml = $curlResult->getBody(); } @@ -940,8 +939,7 @@ class OStatus $xml = ''; - if ($curlResult->inHeader('Content-Type') && - stristr($curlResult->getHeader('Content-Type'), 'application/atom+xml')) { + if (stristr($curlResult->getHeader(), 'Content-Type: application/atom+xml')) { Logger::log('Directly fetched XML for URI ' . $related_uri, Logger::DEBUG); $xml = $curlResult->getBody(); } diff --git a/src/Protocol/Salmon.php b/src/Protocol/Salmon.php index 808462592..169a4d0cb 100644 --- a/src/Protocol/Salmon.php +++ b/src/Protocol/Salmon.php @@ -215,7 +215,7 @@ class Salmon return -1; } - if (($return_code == 503) && $postResult->inHeader('retry-after')) { + if (($return_code == 503) && (stristr($postResult->getHeader(), 'retry-after'))) { return -1; } diff --git a/src/Util/ParseUrl.php b/src/Util/ParseUrl.php index c3cbda70e..1596e015b 100644 --- a/src/Util/ParseUrl.php +++ b/src/Util/ParseUrl.php @@ -175,6 +175,7 @@ class ParseUrl return $siteinfo; } + $header = $curlResult->getHeader(); $body = $curlResult->getBody(); if ($do_oembed) { @@ -203,7 +204,7 @@ class ParseUrl $charset = ''; // Look for a charset, first in headers // Expected form: Content-Type: text/html; charset=ISO-8859-4 - if (preg_match('/charset=([a-z0-9-_.\/]+)/i', $curlResult->getContentType(), $matches)) { + if (preg_match('/charset=([a-z0-9-_.\/]+)/i', $header, $matches)) { $charset = trim(trim(trim(array_pop($matches)), ';,')); } diff --git a/tests/datasets/curl/about.head.php b/tests/datasets/curl/about.head.php deleted file mode 100644 index d0be0feb4..000000000 --- a/tests/datasets/curl/about.head.php +++ /dev/null @@ -1,20 +0,0 @@ - '', - 'date' => 'Thu, 11 Oct 2018 18:43:54 GMT', - 'content-type' => 'text/html; charset=utf-8', - 'vary' => 'Accept-Encoding', - 'server' => 'Mastodon', - 'x-frame-options' => 'SAMEORIGIN', - 'x-content-type-options' => 'nosniff', - 'x-xss-protection' => '1; mode=block', - 'etag' => 'W/"706e6c48957e1d46ecf9d7597a7880af"', - 'cache-control' => 'max-age=0, private, must-revalidate', - 'set-cookie' => '_mastodon_session=v3kcy%2FW3aZYBBvZUohuwksEKwzYIyEUlEuJ1KqTAfWPKvVQq%2F4UuJ39zp621VyfpQNlvY46TL%2FYutzXowSLYQBNFCJcrEiF04aU0TdtHls9zynMiyeHhoVgCijOXWXNt9%2FCmpQ49RkNEujkv9NaJ0cum32MCVZKjE9%2BMKmLM%2F8ZygZeLBGJ7sg%3D%3D--QGIiU0%2FpXc3Aym8F--he2iRRPePOdtEs3z%2BufSXg%3D%3D; path=/; secure; HttpOnly', - 'x-request-id' => 'a0c0b8e7-cd60-4efa-b79b-cf1b0d5a0784', - 'x-runtime' => '0.049566', - 'strict-transport-security' => 'max-age=31536000; includeSubDomains; preload', - 'referrer-policy' => 'same-origin', - 'content-security-policy' => "frame-ancestors 'none'; script-src 'self'; object-src 'self'; img-src * data: blob:; media-src 'self' data:; font-src 'self' data: https://fonts.gstatic.com/; connect-src 'self' blob: wss://mastodonten.de", -]; diff --git a/tests/datasets/curl/about.redirect.php b/tests/datasets/curl/about.redirect.php deleted file mode 100644 index 5ae3fd88f..000000000 --- a/tests/datasets/curl/about.redirect.php +++ /dev/null @@ -1,21 +0,0 @@ - '', - 'date' => 'Thu, 11 Oct 2018 18:43:54 GMT', - 'content-type' => 'text/html; charset=utf-8', - 'vary' => 'Accept-Encoding', - 'server' => 'Mastodon', - 'location' => 'https://test.other/some/', - 'x-frame-options' => 'SAMEORIGIN', - 'x-content-type-options' => 'nosniff', - 'x-xss-protection' => '1; mode=block', - 'etag' => 'W/"706e6c48957e1d46ecf9d7597a7880af"', - 'cache-control' => 'max-age=0, private, must-revalidate', - 'set-cookie' => '_mastodon_session=v3kcy%2FW3aZYBBvZUohuwksEKwzYIyEUlEuJ1KqTAfWPKvVQq%2F4UuJ39zp621VyfpQNlvY46TL%2FYutzXowSLYQBNFCJcrEiF04aU0TdtHls9zynMiyeHhoVgCijOXWXNt9%2FCmpQ49RkNEujkv9NaJ0cum32MCVZKjE9%2BMKmLM%2F8ZygZeLBGJ7sg%3D%3D--QGIiU0%2FpXc3Aym8F--he2iRRPePOdtEs3z%2BufSXg%3D%3D; path=/; secure; HttpOnly', - 'x-request-id' => 'a0c0b8e7-cd60-4efa-b79b-cf1b0d5a0784', - 'x-runtime' => '0.049566', - 'strict-transport-security' => 'max-age=31536000; includeSubDomains; preload', - 'referrer-policy' => 'same-origin', - 'content-security-policy' => "frame-ancestors 'none'; script-src 'self'; object-src 'self'; img-src * data: blob:; media-src 'self' data:; font-src 'self' data: https://fonts.gstatic.com/; connect-src 'self' blob: wss://mastodonten.de", -]; diff --git a/tests/src/Network/CurlResultTest.php b/tests/src/Network/CurlResultTest.php index 03a528812..e066fb89b 100644 --- a/tests/src/Network/CurlResultTest.php +++ b/tests/src/Network/CurlResultTest.php @@ -53,7 +53,6 @@ class CurlResultTest extends TestCase public function testNormal() { $header = file_get_contents(__DIR__ . '/../../datasets/curl/about.head'); - $headerArray = include(__DIR__ . '/../../datasets/curl/about.head.php'); $body = file_get_contents(__DIR__ . '/../../datasets/curl/about.body'); @@ -66,7 +65,7 @@ class CurlResultTest extends TestCase $this->assertTrue($curlResult->isSuccess()); $this->assertFalse($curlResult->isTimeout()); $this->assertFalse($curlResult->isRedirectUrl()); - $this->assertSame($headerArray, $curlResult->getHeaders()); + $this->assertSame($header, $curlResult->getHeader()); $this->assertSame($body, $curlResult->getBody()); $this->assertSame('text/html; charset=utf-8', $curlResult->getContentType()); $this->assertSame('https://test.local', $curlResult->getUrl()); @@ -81,7 +80,6 @@ class CurlResultTest extends TestCase public function testRedirect() { $header = file_get_contents(__DIR__ . '/../../datasets/curl/about.head'); - $headerArray = include(__DIR__ . '/../../datasets/curl/about.head.php'); $body = file_get_contents(__DIR__ . '/../../datasets/curl/about.body'); @@ -95,7 +93,7 @@ class CurlResultTest extends TestCase $this->assertTrue($curlResult->isSuccess()); $this->assertFalse($curlResult->isTimeout()); $this->assertTrue($curlResult->isRedirectUrl()); - $this->assertSame($headerArray, $curlResult->getHeaders()); + $this->assertSame($header, $curlResult->getHeader()); $this->assertSame($body, $curlResult->getBody()); $this->assertSame('text/html; charset=utf-8', $curlResult->getContentType()); $this->assertSame('https://test.local/test/it', $curlResult->getUrl()); @@ -108,7 +106,6 @@ class CurlResultTest extends TestCase public function testTimeout() { $header = file_get_contents(__DIR__ . '/../../datasets/curl/about.head'); - $headerArray = include(__DIR__ . '/../../datasets/curl/about.head.php'); $body = file_get_contents(__DIR__ . '/../../datasets/curl/about.body'); @@ -122,7 +119,7 @@ class CurlResultTest extends TestCase $this->assertFalse($curlResult->isSuccess()); $this->assertTrue($curlResult->isTimeout()); $this->assertFalse($curlResult->isRedirectUrl()); - $this->assertSame($headerArray, $curlResult->getHeaders()); + $this->assertSame($header, $curlResult->getHeader()); $this->assertSame($body, $curlResult->getBody()); $this->assertSame('text/html; charset=utf-8', $curlResult->getContentType()); $this->assertSame('https://test.local/test/it', $curlResult->getRedirectUrl()); @@ -137,7 +134,6 @@ class CurlResultTest extends TestCase public function testRedirectHeader() { $header = file_get_contents(__DIR__ . '/../../datasets/curl/about.redirect'); - $headerArray = include(__DIR__ . '/../../datasets/curl/about.redirect.php'); $body = file_get_contents(__DIR__ . '/../../datasets/curl/about.body'); @@ -150,7 +146,7 @@ class CurlResultTest extends TestCase $this->assertTrue($curlResult->isSuccess()); $this->assertFalse($curlResult->isTimeout()); $this->assertTrue($curlResult->isRedirectUrl()); - $this->assertSame($headerArray, $curlResult->getHeaders()); + $this->assertSame($header, $curlResult->getHeader()); $this->assertSame($body, $curlResult->getBody()); $this->assertSame('text/html; charset=utf-8', $curlResult->getContentType()); $this->assertSame('https://test.local/test/it?key=value', $curlResult->getUrl()); @@ -208,7 +204,7 @@ class CurlResultTest extends TestCase 'url' => 'https://test.local' ]); - $this->assertNotEmpty($curlResult->getHeaders()); + $this->assertNotEmpty($curlResult->getHeader()); $this->assertEmpty($curlResult->getHeader('wrongHeader')); } } From 0aaad3e3920ab75fbbb0e299d3e22bc5d084a4a0 Mon Sep 17 00:00:00 2001 From: Philipp Date: Sun, 11 Oct 2020 23:26:12 +0200 Subject: [PATCH 12/15] Revert "Use Guzzle for HTTPRequest and Result" This reverts commit fff94563 --- src/Network/GuzzleResponse.php | 152 --------------------------------- src/Network/HTTPRequest.php | 131 ++++++++++++++-------------- 2 files changed, 62 insertions(+), 221 deletions(-) delete mode 100644 src/Network/GuzzleResponse.php diff --git a/src/Network/GuzzleResponse.php b/src/Network/GuzzleResponse.php deleted file mode 100644 index c6cab7c9e..000000000 --- a/src/Network/GuzzleResponse.php +++ /dev/null @@ -1,152 +0,0 @@ -. - * - */ - -namespace Friendica\Network; - -use Friendica\Core\Logger; -use Friendica\Core\System; -use Friendica\Network\HTTPException\NotImplementedException; -use GuzzleHttp\Psr7\Response; -use Psr\Http\Message\ResponseInterface; - -/** - * A content wrapper class for Guzzle call results - */ -class GuzzleResponse extends Response implements IHTTPResult, ResponseInterface -{ - /** @var string The URL */ - private $url; - /** @var boolean */ - private $isTimeout; - /** @var boolean */ - private $isSuccess; - /** - * @var int the error number or 0 (zero) if no error - */ - private $errorNumber; - - /** - * @var string the error message or '' (the empty string) if no - */ - private $error; - - public function __construct(ResponseInterface $response, string $url, $errorNumber = 0, $error = '') - { - parent::__construct($response->getStatusCode(), $response->getHeaders(), $response->getBody(), $response->getProtocolVersion(), $response->getReasonPhrase()); - $this->url = $url; - $this->error = $error; - $this->errorNumber = $errorNumber; - - $this->checkSuccess(); - } - - private function checkSuccess() - { - $this->isSuccess = ($this->getStatusCode() >= 200 && $this->getStatusCode() <= 299) || $this->errorNumber == 0; - - // Everything higher or equal 400 is not a success - if ($this->getReturnCode() >= 400) { - $this->isSuccess = false; - } - - if (!$this->isSuccess) { - Logger::notice('http error', ['url' => $this->url, 'code' => $this->getReturnCode(), 'error' => $this->error, 'callstack' => System::callstack(20)]); - Logger::debug('debug', ['info' => $this->getHeaders()]); - } - - if (!$this->isSuccess && $this->errorNumber == CURLE_OPERATION_TIMEDOUT) { - $this->isTimeout = true; - } else { - $this->isTimeout = false; - } - } - - /** {@inheritDoc} */ - public function getReturnCode() - { - return $this->getStatusCode(); - } - - /** {@inheritDoc} */ - public function getContentType() - { - return $this->getHeader('Content-Type'); - } - - /** {@inheritDoc} */ - public function inHeader(string $field) - { - return $this->hasHeader($field); - } - - /** {@inheritDoc} */ - public function getHeaderArray() - { - return $this->getHeaders(); - } - - /** {@inheritDoc} */ - public function isSuccess() - { - return $this->isSuccess; - } - - /** {@inheritDoc} */ - public function getUrl() - { - return $this->url; - } - - /** {@inheritDoc} */ - public function getRedirectUrl() - { - return $this->url; - } - - public function getInfo() - { - // TODO: Implement getInfo() method. - } - - /** {@inheritDoc} */ - public function isRedirectUrl() - { - throw new NotImplementedException(); - } - - /** {@inheritDoc} */ - public function getErrorNumber() - { - return $this->errorNumber; - } - - /** {@inheritDoc} */ - public function getError() - { - return $this->error; - } - - /** {@inheritDoc} */ - public function isTimeout() - { - return $this->isTimeout; - } -} diff --git a/src/Network/HTTPRequest.php b/src/Network/HTTPRequest.php index 37d268f61..e4ff04103 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, bool $binary = false, array $opts = [], int &$redirects = 0) { $stamp1 = microtime(true); @@ -87,130 +86,124 @@ 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'])) { - if (empty($curlOptions[CURLOPT_HTTPHEADER])) { - $curlOptions[CURLOPT_HTTPHEADER] = []; - } - array_push($curlOptions[CURLOPT_HTTPHEADER], 'Accept: ' . $opts['accept_content']); + curl_setopt( + $ch, + CURLOPT_HTTPHEADER, + ['Accept: ' . $opts['accept_content']] + ); } if (!empty($opts['header'])) { - if (empty($curlOptions[CURLOPT_HTTPHEADER])) { - $curlOptions[CURLOPT_HTTPHEADER] = []; - } - $curlOptions[CURLOPT_HTTPHEADER] = array_merge($opts['header'], $curlOptions[CURLOPT_HTTPHEADER]); + 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'])) { - if (empty($curlOptions[CURLOPT_HTTPHEADER])) { - $curlOptions[CURLOPT_HTTPHEADER] = []; - } - $curlOptions[CURLOPT_HTTPHEADER] = array_merge($opts['headers'], $curlOptions[CURLOPT_HTTPHEADER]); + @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; + @curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1); } - $onRedirect = function( - RequestInterface $request, - ResponseInterface $response, - UriInterface $uri - ) { - $this->logger->notice('Curl redirect.', ['url' => $request->getUri(), 'to' => $uri]); - }; + // don't let curl abort the entire application + // if it throws any errors. - $client = new Client([ - 'allow_redirect' => [ - 'max' => 8, - 'on_redirect' => $onRedirect, - 'track_redirect' => true, - 'strict' => true, - 'referer' => true, - ], - 'on_headers' => $onHeaders, - 'sink' => tempnam(get_temppath(), 'guzzle'), - 'curl' => $curlOptions - ]); + $s = @curl_exec($ch); + $curl_info = @curl_getinfo($ch); - 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'); + // 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); } + + $curlResponse = new CurlResult($url, $s, $curl_info, curl_errno($ch), curl_error($ch)); + + 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(), $binary, $opts, $redirects); + } + + @curl_close($ch); + + $this->profiler->saveTimestamp($stamp1, 'network'); + + return $curlResponse; } /** From b70b9d1139405a501665431d434904e74daf3e50 Mon Sep 17 00:00:00 2001 From: Philipp Date: Sun, 11 Oct 2020 23:26:17 +0200 Subject: [PATCH 13/15] Revert "Replace IHTTPResult for CurlResult usages" This reverts commit 97167d7b --- src/Model/GServer.php | 13 ++++++------- src/Network/CurlResult.php | 2 +- src/Network/IHTTPRequest.php | 6 +++--- tests/src/Core/InstallerTest.php | 26 +++++++++++++------------- 4 files changed, 23 insertions(+), 24 deletions(-) diff --git a/src/Model/GServer.php b/src/Model/GServer.php index ac86ef38b..323a23f49 100644 --- a/src/Model/GServer.php +++ b/src/Model/GServer.php @@ -30,7 +30,7 @@ use Friendica\Core\Worker; use Friendica\Database\DBA; use Friendica\DI; use Friendica\Module\Register; -use Friendica\Network\IHTTPResult; +use Friendica\Network\CurlResult; use Friendica\Protocol\Diaspora; use Friendica\Util\DateTimeFormat; use Friendica\Util\Network; @@ -630,19 +630,18 @@ class GServer /** * Detect server type by using the nodeinfo data * - * @param string $url address of the server - * @param IHTTPResult $httpResult - * + * @param string $url address of the server + * @param CurlResult $curlResult * @return array Server data * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - private static function fetchNodeinfo(string $url, IHTTPResult $httpResult) + private static function fetchNodeinfo(string $url, CurlResult $curlResult) { - if (!$httpResult->isSuccess()) { + if (!$curlResult->isSuccess()) { return []; } - $nodeinfo = json_decode($httpResult->getBody(), true); + $nodeinfo = json_decode($curlResult->getBody(), true); if (!is_array($nodeinfo) || empty($nodeinfo['links'])) { return []; diff --git a/src/Network/CurlResult.php b/src/Network/CurlResult.php index 1187e45eb..072ab15c2 100644 --- a/src/Network/CurlResult.php +++ b/src/Network/CurlResult.php @@ -101,7 +101,7 @@ class CurlResult implements IHTTPResult * * @param string $url optional URL * - * @return IHTTPResult a CURL with error response + * @return CurlResult a CURL with error response * @throws InternalServerErrorException */ public static function createErrorCurl($url = '') diff --git a/src/Network/IHTTPRequest.php b/src/Network/IHTTPRequest.php index 3f9b7f27a..3ebcc5dc1 100644 --- a/src/Network/IHTTPRequest.php +++ b/src/Network/IHTTPRequest.php @@ -57,7 +57,7 @@ interface IHTTPRequest * @param string $accept_content supply Accept: header with 'accept_content' as the value * @param string $cookiejar Path to cookie jar file * - * @return IHTTPResult With all relevant information, 'body' contains the actual fetched content. + * @return CurlResult With all relevant information, 'body' contains the actual fetched content. */ public function fetchFull(string $url, bool $binary = false, int $timeout = 0, string $accept_content = '', string $cookiejar = ''); @@ -76,7 +76,7 @@ interface IHTTPRequest * 'cookiejar' => path to cookie jar file * 'header' => header array * - * @return IHTTPResult + * @return CurlResult */ public function get(string $url, bool $binary = false, array $opts = []); @@ -88,7 +88,7 @@ interface IHTTPRequest * @param array $headers HTTP headers * @param int $timeout The timeout in seconds, default system config value or 60 seconds * - * @return IHTTPResult The content + * @return CurlResult The content */ public function post(string $url, $params, array $headers = [], int $timeout = 0); diff --git a/tests/src/Core/InstallerTest.php b/tests/src/Core/InstallerTest.php index 37a754bc9..00879680e 100644 --- a/tests/src/Core/InstallerTest.php +++ b/tests/src/Core/InstallerTest.php @@ -25,7 +25,7 @@ namespace Friendica\Core; use Dice\Dice; use Friendica\Core\Config\Cache; use Friendica\DI; -use Friendica\Network\IHTTPResult; +use Friendica\Network\CurlResult; use Friendica\Network\IHTTPRequest; use Friendica\Test\MockedTest; use Friendica\Test\Util\VFSTrait; @@ -297,14 +297,14 @@ class InstallerTest extends MockedTest $this->l10nMock->shouldReceive('t')->andReturnUsing(function ($args) { return $args; }); // Mocking the CURL Response - $IHTTPResult = \Mockery::mock(IHTTPResult::class); - $IHTTPResult + $curlResult = \Mockery::mock(CurlResult::class); + $curlResult ->shouldReceive('getReturnCode') ->andReturn('404'); - $IHTTPResult + $curlResult ->shouldReceive('getRedirectUrl') ->andReturn(''); - $IHTTPResult + $curlResult ->shouldReceive('getError') ->andReturn('test Error'); @@ -313,11 +313,11 @@ class InstallerTest extends MockedTest $networkMock ->shouldReceive('fetchFull') ->with('https://test/install/testrewrite') - ->andReturn($IHTTPResult); + ->andReturn($curlResult); $networkMock ->shouldReceive('fetchFull') ->with('http://test/install/testrewrite') - ->andReturn($IHTTPResult); + ->andReturn($curlResult); $this->dice->shouldReceive('create') ->with(IHTTPRequest::class) @@ -344,14 +344,14 @@ class InstallerTest extends MockedTest $this->l10nMock->shouldReceive('t')->andReturnUsing(function ($args) { return $args; }); // Mocking the failed CURL Response - $IHTTPResultF = \Mockery::mock(IHTTPResult::class); - $IHTTPResultF + $curlResultF = \Mockery::mock(CurlResult::class); + $curlResultF ->shouldReceive('getReturnCode') ->andReturn('404'); // Mocking the working CURL Response - $IHTTPResultW = \Mockery::mock(IHTTPResult::class); - $IHTTPResultW + $curlResultW = \Mockery::mock(CurlResult::class); + $curlResultW ->shouldReceive('getReturnCode') ->andReturn('204'); @@ -360,11 +360,11 @@ class InstallerTest extends MockedTest $networkMock ->shouldReceive('fetchFull') ->with('https://test/install/testrewrite') - ->andReturn($IHTTPResultF); + ->andReturn($curlResultF); $networkMock ->shouldReceive('fetchFull') ->with('http://test/install/testrewrite') - ->andReturn($IHTTPResultW); + ->andReturn($curlResultW); $this->dice->shouldReceive('create') ->with(IHTTPRequest::class) From 909da78e20983629ac9b2c8b22aa400c37870c0c Mon Sep 17 00:00:00 2001 From: Philipp Date: Sun, 11 Oct 2020 23:26:22 +0200 Subject: [PATCH 14/15] Revert "Introduce IHTTPResult Interface as abstraction for CurlResult" This reverts commit f238f4ef --- src/Network/CurlResult.php | 72 ++++++++++++++++++++++------ src/Network/IHTTPResult.php | 93 ------------------------------------- 2 files changed, 57 insertions(+), 108 deletions(-) delete mode 100644 src/Network/IHTTPResult.php diff --git a/src/Network/CurlResult.php b/src/Network/CurlResult.php index 072ab15c2..9f52edfad 100644 --- a/src/Network/CurlResult.php +++ b/src/Network/CurlResult.php @@ -29,7 +29,7 @@ use Friendica\Util\Network; /** * A content class for Curl call results */ -class CurlResult implements IHTTPResult +class CurlResult { /** * @var int HTTP return code or 0 if timeout or failure @@ -229,19 +229,33 @@ class CurlResult implements IHTTPResult } } - /** {@inheritDoc} */ + /** + * Gets the Curl Code + * + * @return string The Curl Code + */ public function getReturnCode() { return $this->returnCode; } - /** {@inheritDoc} */ + /** + * Returns the Curl Content Type + * + * @return string the Curl Content Type + */ public function getContentType() { return $this->contentType; } - /** {@inheritDoc} */ + /** + * Returns the Curl headers + * + * @param string $field optional header field. Return all fields if empty + * + * @return string the Curl headers or the specified content of the header variable + */ public function getHeader(string $field = '') { if (empty($field)) { @@ -259,7 +273,13 @@ class CurlResult implements IHTTPResult return ''; } - /** {@inheritDoc} */ + /** + * Check if a specified header exists + * + * @param string $field header field + * + * @return boolean "true" if header exists + */ public function inHeader(string $field) { $field = strtolower(trim($field)); @@ -269,7 +289,11 @@ class CurlResult implements IHTTPResult return array_key_exists($field, $headers); } - /** {@inheritDoc} */ + /** + * Returns the Curl headers as an associated array + * + * @return array associated header array + */ public function getHeaderArray() { if (!empty($this->header_fields)) { @@ -289,55 +313,73 @@ class CurlResult implements IHTTPResult return $this->header_fields; } - /** {@inheritDoc} */ + /** + * @return bool + */ public function isSuccess() { return $this->isSuccess; } - /** {@inheritDoc} */ + /** + * @return string + */ public function getUrl() { return $this->url; } - /** {@inheritDoc} */ + /** + * @return string + */ public function getRedirectUrl() { return $this->redirectUrl; } - /** {@inheritDoc} */ + /** + * @return string + */ public function getBody() { return $this->body; } - /** {@inheritDoc} */ + /** + * @return array + */ public function getInfo() { return $this->info; } - /** {@inheritDoc} */ + /** + * @return bool + */ public function isRedirectUrl() { return $this->isRedirectUrl; } - /** {@inheritDoc} */ + /** + * @return int + */ public function getErrorNumber() { return $this->errorNumber; } - /** {@inheritDoc} */ + /** + * @return string + */ public function getError() { return $this->error; } - /** {@inheritDoc} */ + /** + * @return bool + */ public function isTimeout() { return $this->isTimeout; diff --git a/src/Network/IHTTPResult.php b/src/Network/IHTTPResult.php deleted file mode 100644 index be190c80c..000000000 --- a/src/Network/IHTTPResult.php +++ /dev/null @@ -1,93 +0,0 @@ - Date: Sun, 11 Oct 2020 23:26:28 +0200 Subject: [PATCH 15/15] Revert "Add guzzlehttp/guzzle as composer requirement" This reverts commit d1366d3a --- composer.json | 1 - composer.lock | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 08216159e..efd4bd081 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,6 @@ "divineomega/password_exposed": "^2.8", "ezyang/htmlpurifier": "^4.7", "friendica/json-ld": "^1.0", - "guzzlehttp/guzzle": "^6.5", "league/html-to-markdown": "^4.8", "level-2/dice": "^4", "lightopenid/lightopenid": "dev-master", diff --git a/composer.lock b/composer.lock index 0d650ad15..8ba31ecb0 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "aa279ba22954af464cd7b4a5e2d74eec", + "content-hash": "fd22bd8c29dcea3d6b6eeb117d79af52", "packages": [ { "name": "asika/simple-console",