From dee1899628380998d3a284e41bfc49ce0737dd2f Mon Sep 17 00:00:00 2001 From: Philipp <admin@philipp.info> Date: Fri, 20 Aug 2021 19:48:14 +0200 Subject: [PATCH] Fix IHTTPResult::getHeader/s() - Split functionality "getHeader()" and "getHeaders()" analog to IMessageInterface::getHeader/s() - Fix functionality at various places - Adapt CurlResultTest --- src/Network/CurlResult.php | 18 ++++++++++++------ src/Network/HTTPRequest.php | 3 +-- src/Network/IHTTPResult.php | 22 +++++++++++++++++++--- src/Protocol/DFRN.php | 2 +- 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 +++++++++----- 10 files changed, 89 insertions(+), 22 deletions(-) create mode 100644 tests/datasets/curl/about.head.php create mode 100644 tests/datasets/curl/about.redirect.php diff --git a/src/Network/CurlResult.php b/src/Network/CurlResult.php index 6fb0153b6..227d26140 100644 --- a/src/Network/CurlResult.php +++ b/src/Network/CurlResult.php @@ -242,23 +242,29 @@ class CurlResult implements IHTTPResult } /** {@inheritDoc} */ - public function getHeader(string $field = '') + public function getHeader($header) { - if (empty($field)) { - return $this->header; + if (empty($header)) { + return ''; } - $field = strtolower(trim($field)); + $header = strtolower(trim($header)); $headers = $this->getHeaderArray(); - if (isset($headers[$field])) { - return $headers[$field]; + if (isset($headers[$header])) { + return $headers[$header]; } 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 523efc698..72311ea19 100644 --- a/src/Network/HTTPRequest.php +++ b/src/Network/HTTPRequest.php @@ -493,8 +493,7 @@ 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 be190c80c..5904bcfa3 100644 --- a/src/Network/IHTTPResult.php +++ b/src/Network/IHTTPResult.php @@ -2,6 +2,8 @@ namespace Friendica\Network; +use Psr\Http\Message\MessageInterface; + /** * Temporary class to map Friendica used variables based on PSR-7 HTTPResponse */ @@ -23,15 +25,25 @@ interface IHTTPResult /** * Returns the headers + * @see MessageInterface::getHeader() * - * @param string $field optional header field. Return all fields if empty + * @param string $header optional header field. Return all fields if empty * * @return string the headers or the specified content of the header variable */ - public function getHeader(string $field = ''); + public function getHeader($header); + + /** + * Returns all headers + * @see MessageInterface::getHeaders() + * + * @return string[][] + */ + public function getHeaders(); /** * Check if a specified header exists + * @see MessageInterface::hasHeader() * * @param string $field header field * @@ -41,8 +53,10 @@ interface IHTTPResult /** * Returns the headers as an associated array + * @see MessageInterface::getHeaders() + * @deprecated * - * @return array associated header array + * @return string[][] associated header array */ public function getHeaderArray(); @@ -62,6 +76,8 @@ 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 832e2bde2..cd63291ee 100644 --- a/src/Protocol/DFRN.php +++ b/src/Protocol/DFRN.php @@ -985,7 +985,7 @@ class DFRN return -9; // timed out } - if (($curl_stat == 503) && (stristr($postResult->getHeader(), 'retry-after'))) { + if (($curl_stat == 503) && $postResult->inHeader('retry-after')) { return -10; } diff --git a/src/Protocol/OStatus.php b/src/Protocol/OStatus.php index e813cc250..8d818471b 100644 --- a/src/Protocol/OStatus.php +++ b/src/Protocol/OStatus.php @@ -735,7 +735,8 @@ class OStatus $xml = ''; - if (stristr($curlResult->getHeader(), 'Content-Type: application/atom+xml')) { + if ($curlResult->inHeader('Content-Type') && + stristr($curlResult->getHeader('Content-Type'), 'application/atom+xml')) { $xml = $curlResult->getBody(); } @@ -928,7 +929,8 @@ class OStatus $xml = ''; - if (stristr($curlResult->getHeader(), 'Content-Type: application/atom+xml')) { + if ($curlResult->inHeader('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/Protocol/Salmon.php b/src/Protocol/Salmon.php index 81b1f7528..53367f6d0 100644 --- a/src/Protocol/Salmon.php +++ b/src/Protocol/Salmon.php @@ -215,7 +215,7 @@ class Salmon return -1; } - if (($return_code == 503) && (stristr($postResult->getHeader(), 'retry-after'))) { + if (($return_code == 503) && $postResult->inHeader('retry-after')) { return -1; } diff --git a/src/Util/ParseUrl.php b/src/Util/ParseUrl.php index d5c9f02ad..75210af0f 100644 --- a/src/Util/ParseUrl.php +++ b/src/Util/ParseUrl.php @@ -232,7 +232,6 @@ class ParseUrl } } - $header = $curlResult->getHeader(); $body = $curlResult->getBody(); if ($do_oembed) { @@ -273,7 +272,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', $header, $matches)) { + if (preg_match('/charset=([a-z0-9-_.\/]+)/i', $curlResult->getContentType(), $matches)) { $charset = trim(trim(trim(array_pop($matches)), ';,')); } diff --git a/tests/datasets/curl/about.head.php b/tests/datasets/curl/about.head.php new file mode 100644 index 000000000..d0be0feb4 --- /dev/null +++ b/tests/datasets/curl/about.head.php @@ -0,0 +1,20 @@ +<?php + +return [ + '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 new file mode 100644 index 000000000..5ae3fd88f --- /dev/null +++ b/tests/datasets/curl/about.redirect.php @@ -0,0 +1,21 @@ +<?php + +return [ + '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", +]; diff --git a/tests/src/Network/CurlResultTest.php b/tests/src/Network/CurlResultTest.php index 090479642..c28dc5f1b 100644 --- a/tests/src/Network/CurlResultTest.php +++ b/tests/src/Network/CurlResultTest.php @@ -53,6 +53,7 @@ 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'); @@ -65,7 +66,7 @@ class CurlResultTest extends TestCase self::assertTrue($curlResult->isSuccess()); self::assertFalse($curlResult->isTimeout()); self::assertFalse($curlResult->isRedirectUrl()); - self::assertSame($header, $curlResult->getHeader()); + self::assertSame($headerArray, $curlResult->getHeaders()); self::assertSame($body, $curlResult->getBody()); self::assertSame('text/html; charset=utf-8', $curlResult->getContentType()); self::assertSame('https://test.local', $curlResult->getUrl()); @@ -80,6 +81,7 @@ 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'); @@ -93,7 +95,7 @@ class CurlResultTest extends TestCase self::assertTrue($curlResult->isSuccess()); self::assertFalse($curlResult->isTimeout()); self::assertTrue($curlResult->isRedirectUrl()); - self::assertSame($header, $curlResult->getHeader()); + self::assertSame($headerArray, $curlResult->getHeaders()); self::assertSame($body, $curlResult->getBody()); self::assertSame('text/html; charset=utf-8', $curlResult->getContentType()); self::assertSame('https://test.local/test/it', $curlResult->getUrl()); @@ -106,6 +108,7 @@ 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'); @@ -119,7 +122,7 @@ class CurlResultTest extends TestCase self::assertFalse($curlResult->isSuccess()); self::assertTrue($curlResult->isTimeout()); self::assertFalse($curlResult->isRedirectUrl()); - self::assertSame($header, $curlResult->getHeader()); + self::assertSame($headerArray, $curlResult->getHeaders()); self::assertSame($body, $curlResult->getBody()); self::assertSame('text/html; charset=utf-8', $curlResult->getContentType()); self::assertSame('https://test.local/test/it', $curlResult->getRedirectUrl()); @@ -134,6 +137,7 @@ 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'); @@ -146,7 +150,7 @@ class CurlResultTest extends TestCase self::assertTrue($curlResult->isSuccess()); self::assertFalse($curlResult->isTimeout()); self::assertTrue($curlResult->isRedirectUrl()); - self::assertSame($header, $curlResult->getHeader()); + self::assertSame($headerArray, $curlResult->getHeaders()); self::assertSame($body, $curlResult->getBody()); self::assertSame('text/html; charset=utf-8', $curlResult->getContentType()); self::assertSame('https://test.local/test/it?key=value', $curlResult->getUrl()); @@ -204,7 +208,7 @@ class CurlResultTest extends TestCase 'url' => 'https://test.local' ]); - self::assertNotEmpty($curlResult->getHeader()); + self::assertNotEmpty($curlResult->getHeaders()); self::assertEmpty($curlResult->getHeader('wrongHeader')); } }