diff --git a/src/Network/CurlResult.php b/src/Network/CurlResult.php index dc83182a6..e246f4fa5 100644 --- a/src/Network/CurlResult.php +++ b/src/Network/CurlResult.php @@ -119,7 +119,7 @@ class CurlResult $header = ''; $base = $result; - while (preg_match('/^HTTP\/[1-2].+? [1-5][0-9][0-9]/', $base)) { + while (preg_match('/^HTTP\/.+? \d+/', $base)) { $chunk = substr($base, 0, strpos($base, "\r\n\r\n") + 4); $header .= $chunk; $base = substr($base, strlen($chunk)); @@ -177,7 +177,7 @@ class CurlResult $this->redirectUrl .= '?' . $old_location_query; } - $this->isRedirectUrl = filter_var($this->redirectUrl, FILTER_VALIDATE_URL); + $this->isRedirectUrl = filter_var($this->redirectUrl, FILTER_VALIDATE_URL) !== false; } else { $this->isRedirectUrl = false; } diff --git a/tests/datasets/curl/about.body b/tests/datasets/curl/about.body new file mode 100644 index 000000000..86d8712d0 --- /dev/null +++ b/tests/datasets/curl/about.body @@ -0,0 +1,17 @@ + + + + + + + + + + +
+
+ + + + + diff --git a/tests/datasets/curl/about.head b/tests/datasets/curl/about.head new file mode 100644 index 000000000..c1d4b165d --- /dev/null +++ b/tests/datasets/curl/about.head @@ -0,0 +1,21 @@ +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: DENY +x-content-type-options: nosniff +x-xss-protection: 1; mode=block +vary: Accept-Encoding +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 +x-frame-options: SAMEORIGIN +x-content-type-options: nosniff +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 +x-xss-protection: 1; mode=block + diff --git a/tests/datasets/curl/about.redirect b/tests/datasets/curl/about.redirect new file mode 100644 index 000000000..9033e0f66 --- /dev/null +++ b/tests/datasets/curl/about.redirect @@ -0,0 +1,22 @@ +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: DENY +x-content-type-options: nosniff +x-xss-protection: 1; mode=block +vary: Accept-Encoding +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 +x-frame-options: SAMEORIGIN +x-content-type-options: nosniff +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 +x-xss-protection: 1; mode=block + diff --git a/tests/src/Network/CurlResultTest.php b/tests/src/Network/CurlResultTest.php new file mode 100644 index 000000000..13a14d985 --- /dev/null +++ b/tests/src/Network/CurlResultTest.php @@ -0,0 +1,119 @@ + 200, + 'content_type' => 'text/html; charset=utf-8', + 'url' => 'https://test.local' + ]); + + $this->assertTrue($curlResult->isSuccess()); + $this->assertFalse($curlResult->isTimeout()); + $this->assertFalse($curlResult->isRedirectUrl()); + $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()); + $this->assertSame('https://test.local', $curlResult->getRedirectUrl()); + } + + /** + * @small + */ + public function testRedirect() + { + $header = file_get_contents(__DIR__ . '/../../datasets/curl/about.head'); + $body = file_get_contents(__DIR__ . '/../../datasets/curl/about.body'); + + + $curlResult = new CurlResult('https://test.local/test/it', $header . $body, [ + 'http_code' => 301, + 'content_type' => 'text/html; charset=utf-8', + 'url' => 'https://test.local/test/it', + 'redirect_url' => 'https://test.other' + ]); + + $this->assertTrue($curlResult->isSuccess()); + $this->assertFalse($curlResult->isTimeout()); + $this->assertTrue($curlResult->isRedirectUrl()); + $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()); + $this->assertSame('https://test.other/test/it', $curlResult->getRedirectUrl()); + } + + /** + * @small + */ + public function testTimeout() + { + $header = file_get_contents(__DIR__ . '/../../datasets/curl/about.head'); + $body = file_get_contents(__DIR__ . '/../../datasets/curl/about.body'); + + + $curlResult = new CurlResult('https://test.local/test/it', $header . $body, [ + 'http_code' => 500, + 'content_type' => 'text/html; charset=utf-8', + 'url' => 'https://test.local/test/it', + 'redirect_url' => 'https://test.other' + ], CURLE_OPERATION_TIMEDOUT, 'Tested error'); + + $this->assertFalse($curlResult->isSuccess()); + $this->assertTrue($curlResult->isTimeout()); + $this->assertFalse($curlResult->isRedirectUrl()); + $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()); + $this->assertSame('Tested error', $curlResult->getError()); + } + + /** + * @small + */ + public function testRedirectHeader() + { + $header = file_get_contents(__DIR__ . '/../../datasets/curl/about.redirect'); + $body = file_get_contents(__DIR__ . '/../../datasets/curl/about.body'); + + + $curlResult = new CurlResult('https://test.local/test/it?key=value', $header . $body, [ + 'http_code' => 301, + 'content_type' => 'text/html; charset=utf-8', + 'url' => 'https://test.local/test/it?key=value', + ]); + + $this->assertTrue($curlResult->isSuccess()); + $this->assertFalse($curlResult->isTimeout()); + $this->assertTrue($curlResult->isRedirectUrl()); + $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()); + $this->assertSame('https://test.other/some/?key=value', $curlResult->getRedirectUrl()); + } +}