2022-03-22 09:24:31 +00:00
|
|
|
<?php
|
|
|
|
|
2023-12-23 19:52:56 +00:00
|
|
|
use GuzzleHttp\Client;
|
|
|
|
use GuzzleHttp\Handler\MockHandler;
|
|
|
|
use GuzzleHttp\HandlerStack;
|
|
|
|
use GuzzleHttp\Psr7\Response;
|
|
|
|
use GuzzleHttp\Psr7\Request;
|
|
|
|
use GuzzleHttp\Exception\RequestException;
|
2022-03-22 09:24:31 +00:00
|
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
|
|
|
|
final class UrlHelperTest extends TestCase {
|
2022-03-22 11:32:32 +00:00
|
|
|
public function test_rewrite_relative(): void {
|
2022-03-22 09:24:31 +00:00
|
|
|
// protocol-neutral URL
|
|
|
|
$this->assertEquals(
|
|
|
|
'https://example.com/example.html',
|
|
|
|
UrlHelper::rewrite_relative('http://example.com/example/', '//example.com/example.html')
|
|
|
|
);
|
|
|
|
|
|
|
|
// magnet allowed because it's a href attribute
|
|
|
|
$this->assertEquals(
|
|
|
|
'magnet:?xt=urn:btih:...',
|
2023-12-23 19:52:56 +00:00
|
|
|
UrlHelper::rewrite_relative(
|
|
|
|
'http://example.com/example/',
|
2022-03-22 09:24:31 +00:00
|
|
|
'magnet:?xt=urn:btih:...',
|
2023-12-23 19:52:56 +00:00
|
|
|
"a",
|
|
|
|
"href",
|
|
|
|
""
|
|
|
|
)
|
2022-03-22 09:24:31 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
// disallowed magnet
|
|
|
|
$this->assertEquals(
|
|
|
|
'http://example.com?xt=urn:btih:...',
|
2023-12-23 19:52:56 +00:00
|
|
|
UrlHelper::rewrite_relative(
|
|
|
|
'http://example.com/example/',
|
|
|
|
'magnet:?xt=urn:btih:...'
|
|
|
|
)
|
2022-03-22 09:24:31 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertEquals(
|
|
|
|
'https://apod.nasa.gov/apod/image/2203/Road2Stars_EsoHoralek_1080.jpg',
|
|
|
|
UrlHelper::rewrite_relative('https://apod.nasa.gov/apod/ap220315.html', 'image/2203/Road2Stars_EsoHoralek_1080.jpg')
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertEquals(
|
|
|
|
'https://apod.nasa.gov/apod/image/2203/Road2Stars_EsoHoralek_1080.jpg',
|
|
|
|
UrlHelper::rewrite_relative('https://apod.nasa.gov/apod/ap220315.html', './image/2203/Road2Stars_EsoHoralek_1080.jpg')
|
|
|
|
);
|
|
|
|
|
2022-03-22 11:32:32 +00:00
|
|
|
$this->assertEquals(
|
|
|
|
'http://example.com/test/url',
|
|
|
|
UrlHelper::rewrite_relative('http://example.com/test/url', '')
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertEquals(
|
|
|
|
'http://www.example.com/test',
|
|
|
|
UrlHelper::rewrite_relative('http://www.example2.com ', 'http://www.example.com/test')
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertEquals(
|
|
|
|
'http://www.example.com/test',
|
|
|
|
UrlHelper::rewrite_relative('http://www.example.com/test2 ', 'http://www.example.com/test')
|
|
|
|
);
|
2023-12-23 19:52:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public function test_fetch(): void {
|
|
|
|
$mock = new MockHandler();
|
|
|
|
|
|
|
|
UrlHelper::$client = new Client([
|
|
|
|
'handler' => HandlerStack::create($mock),
|
|
|
|
]);
|
|
|
|
|
|
|
|
$mock->append(new Response(200, [], 'Hello, World'));
|
|
|
|
$result = UrlHelper::fetch('https://www.example.com');
|
|
|
|
$this->assertEquals(200, UrlHelper::$fetch_last_error_code);
|
|
|
|
$this->assertEquals('Hello, World', $result);
|
2023-12-29 00:31:03 +00:00
|
|
|
$mock->reset();
|
2023-12-23 19:52:56 +00:00
|
|
|
|
|
|
|
foreach (['ftp://ftp.example.com', 'http://127.0.0.1', 'blah', '', 42, null] as $url) {
|
|
|
|
$result = UrlHelper::fetch($url);
|
|
|
|
$this->assertFalse($result);
|
|
|
|
}
|
|
|
|
|
2023-12-23 19:58:39 +00:00
|
|
|
$mock->append(new Response(200, ['Content-Length' => (string) PHP_INT_MAX]));
|
2023-12-23 19:52:56 +00:00
|
|
|
$result = UrlHelper::fetch('https://www.example.com/very-large-content-length');
|
|
|
|
$this->assertFalse($result);
|
2023-12-29 00:31:03 +00:00
|
|
|
$mock->reset();
|
2023-12-23 19:52:56 +00:00
|
|
|
|
|
|
|
$mock->append(new Response(301, ['Location' => 'https://www.example.com']));
|
|
|
|
$result = UrlHelper::fetch(['url' => 'https://example.com', 'followlocation' => false]);
|
|
|
|
$this->assertFalse($result);
|
2023-12-29 00:31:03 +00:00
|
|
|
$mock->reset();
|
2023-12-23 19:52:56 +00:00
|
|
|
|
2023-12-29 00:31:03 +00:00
|
|
|
$mock->append(new Response(301, ['Location' => 'http://127.0.0.1']));
|
2023-12-23 19:52:56 +00:00
|
|
|
$result = UrlHelper::fetch(['url' => 'https://example.com', 'followlocation' => true]);
|
|
|
|
$this->assertFalse($result);
|
2023-12-29 00:31:03 +00:00
|
|
|
$this->assertMatchesRegularExpression('%failed extended validation%', UrlHelper::$fetch_last_error);
|
2023-12-23 19:52:56 +00:00
|
|
|
$this->assertEquals('http://127.0.0.1', UrlHelper::$fetch_effective_url);
|
2023-12-29 00:31:03 +00:00
|
|
|
$mock->reset();
|
2023-12-23 19:52:56 +00:00
|
|
|
|
|
|
|
$mock->append(new Response(200, [], ''));
|
|
|
|
$result = UrlHelper::fetch('https://www.example.com');
|
|
|
|
$this->assertFalse($result);
|
|
|
|
$this->assertEquals('Successful response, but no content was received.', UrlHelper::$fetch_last_error);
|
2023-12-29 00:31:03 +00:00
|
|
|
$mock->reset();
|
2022-03-22 11:32:32 +00:00
|
|
|
|
2023-12-24 11:21:43 +00:00
|
|
|
// Fake a 403 for basic auth and success with `CURLAUTH_ANY` in the retry attempt
|
|
|
|
$mock->append(
|
|
|
|
new Response(403, []),
|
|
|
|
new Response(200, [], 'Hello, World'),
|
|
|
|
);
|
|
|
|
$result = UrlHelper::fetch([
|
|
|
|
'url' => 'https://example.com/requires-credentials',
|
|
|
|
'login' => 'some_username',
|
|
|
|
'pass' => 'some_password',
|
|
|
|
'auth_type' => 'basic',
|
|
|
|
]);
|
|
|
|
$this->assertEquals(200, UrlHelper::$fetch_last_error_code);
|
|
|
|
$this->assertEquals('Hello, World', $result);
|
|
|
|
$this->assertEquals($mock->getLastOptions()['curl'][\CURLOPT_HTTPAUTH], \CURLAUTH_ANY);
|
2023-12-29 00:31:03 +00:00
|
|
|
$mock->reset();
|
2022-03-22 09:24:31 +00:00
|
|
|
}
|
|
|
|
}
|