Some tests & implementation around verifying and parsing received webmentions

This commit is contained in:
Lewis Dale committed 2023-03-14 08:27:46 +00:00
1 parent 83ec00c8a0
commit 38885beb74
4 files changed
+142 -9

No files matched your search

+36 -8
View File
@@ -2,19 +2,39 @@
namespace Lewisdale\Webmentions;
use League\Uri\Exceptions\SyntaxError;
use Lewisdale\Webmentions\Exceptions\InvalidTargetException;
use Lewisdale\Webmentions\Exceptions\InvalidUrlException;
use Lewisdale\Webmentions\Gateways\WebmentionGatewayInterface;
use Lewisdale\Webmentions\Models\Webmention;
use Symfony\Component\HttpClient\HttpClient;
use League\Uri\Uri;
use Lewisdale\Webmentions\Exceptions\SourceNotFoundException;
use Lewisdale\Webmentions\Exceptions\TargetNotMentionedException;
use Symfony\Component\DomCrawler\Crawler;
use Symfony\Contracts\HttpClient\HttpClientInterface;
class Endpoint {
private readonly WebmentionGatewayInterface $gateway;
public function validateUrl(string $url) : bool {
return !!filter_var($url, FILTER_VALIDATE_URL);
}
function __construct(
private readonly HttpClientInterface $httpClient
)
{}
public function validateUrl(string $url) : bool {
try {
$uri = Uri::createFromString($url);
$scheme = $uri->getScheme();
$schemeValid = in_array($scheme, ["http", "https"]);
return $schemeValid && !!filter_var($url, FILTER_VALIDATE_URL);
} catch (SyntaxError $e)
{
return false;
}
}
public function receiveWebmention(string $source, string $target) : void
{
// Validate that both source and target are actual domains
@@ -29,21 +49,29 @@ class Endpoint {
}
// Parse content from the source
$client = HttpClient::create();
$response = $client->request('GET', $source);
$response = $this->httpClient->request('GET', $source);
if ($response->getStatusCode() === 200)
if ($response->getStatusCode() < 400)
{
$content = $this->parseContent($response->getContent());
$content = $this->parseContent($response->getContent(), $target);
$author = $this->parseAuthor($response->getContent());
$webmention = new Webmention(null, $target, $source, $content, $author);
$this->gateway->save($webmention);
} else {
throw new SourceNotFoundException();
}
}
private function parseContent(string $content) : ?string
private function parseContent(string $content, string $target) : ?string
{
$body = new Crawler($content);
$anchors = $body->filter('a[href="'. $target . '"]');
if (!$anchors->count()) {
throw new TargetNotMentionedException();
}
return null;
}