friendica-directory/src/classes/Pollers/Directory.php

124 lines
3.1 KiB
PHP
Raw Normal View History

2018-11-12 03:08:33 +01:00
<?php
namespace Friendica\Directory\Pollers;
2020-07-17 22:41:02 +02:00
use Friendica\Directory\Utils\Network;
2018-11-12 03:08:33 +01:00
/**
* @author Hypolite Petovan <hypolite@mrpetovan.com>
2018-11-12 03:08:33 +01:00
*/
class Directory
{
/**
* @var \Atlas\Pdo\Connection
*/
private $atlas;
/**
* @var \Friendica\Directory\Models\ProfilePollQueue
*/
private $profilePollQueueModel;
/**
* @var \Psr\Log\LoggerInterface
*/
private $logger;
/**
* @var array
*/
private $settings = [
'probe_timeout' => 5
];
public function __construct(
\Atlas\Pdo\Connection $atlas,
\Friendica\Directory\Models\ProfilePollQueue $profilePollQueueModel,
\Psr\Log\LoggerInterface $logger,
array $settings)
{
$this->atlas = $atlas;
$this->profilePollQueueModel = $profilePollQueueModel;
$this->logger = $logger;
$this->settings = array_merge($this->settings, $settings);
}
/**
* @param string $directory_url
* @param int|null $last_polled
* @return bool
*/
public function __invoke(string $directory_url, int $last_polled = null): bool
{
$this->logger->info('Pull from directory with URL: ' . $directory_url);
try {
$host = parse_url($directory_url, PHP_URL_HOST);
if (!$host) {
throw new \Exception('Missing hostname in polled directory URL: ' . $directory_url);
}
if (!\Friendica\Directory\Utils\Network::isPublicHost($host)) {
throw new \Exception('Private/reserved IP in polled directory URL: ' . $directory_url);
}
$profiles = $this->getPullResult($directory_url, $last_polled);
foreach ($profiles as $profile_url) {
$result = $this->profilePollQueueModel->add($profile_url);
$this->logger->debug('Profile queue add URL: ' . $profile_url . ' - ' . $result);
2018-11-12 03:08:33 +01:00
}
$this->logger->info('Successfully pulled ' . count($profiles) . ' profiles');
return true;
} catch (\Exception $e) {
$this->logger->warning($e->getMessage());
return false;
}
}
private function getPullResult(string $directory_url, ?int $last_polled = null): array
{
$path = '/sync/pull/all';
if ($last_polled) {
$path = '/sync/pull/since/' . $last_polled;
}
//Prepare the CURL call.
$handle = curl_init();
$options = array(
//Timeouts
CURLOPT_TIMEOUT => max($this->settings['probe_timeout'], 1), //Minimum of 1 second timeout.
CURLOPT_CONNECTTIMEOUT => 1,
//Redirecting
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_MAXREDIRS => 8,
//SSL
CURLOPT_SSL_VERIFYPEER => true,
// CURLOPT_VERBOSE => true,
// CURLOPT_CERTINFO => true,
CURLOPT_SSL_VERIFYHOST => 2,
CURLOPT_PROTOCOLS => CURLPROTO_HTTP | CURLPROTO_HTTPS,
//Basic request
2020-07-17 22:41:02 +02:00
CURLOPT_USERAGENT => Network::USER_AGENT,
2018-11-12 03:08:33 +01:00
CURLOPT_RETURNTRANSFER => true,
CURLOPT_URL => $directory_url . $path
);
curl_setopt_array($handle, $options);
$this->logger->info('Pulling profiles from directory URL: ' . $directory_url . $path);
//Probe the site.
$pull_data = curl_exec($handle);
//Done with CURL now.
curl_close($handle);
$data = json_decode($pull_data, true);
if (!isset($data['results']) || !is_array($data['results'])) {
throw new \Exception('Invalid directory pull data for directory with URL: ' . $directory_url . $path);
}
return $data['results'];
}
}