Use legit engines
This commit is contained in:
parent
65f977918f
commit
dbd255da96
1 changed files with 106 additions and 44 deletions
128
index.php
128
index.php
|
|
@ -4,18 +4,21 @@ declare(strict_types=1);
|
|||
// -------------------- CONSTANTES --------------------
|
||||
const CACHE_DIR = '/var/cache/homepage';
|
||||
const INSTANCES_JSON = CACHE_DIR . '/instances.json';
|
||||
const URLS_TXT = CACHE_DIR . '/urls.txt';
|
||||
const URLS_TXT = __DIR__ . '/urls.txt'; // ← Hors du cache, à la racine
|
||||
const INSTANCES_URL = 'https://searx.space/data/instances.json';
|
||||
const CACHE_MAX_AGE = 3600; // 1 heure
|
||||
const BANG_FILE = __DIR__ . '/bang.json';
|
||||
const USE_SEARX_INSTANCES = true; // false → utilise engines.txt
|
||||
|
||||
// -------------------- HEADERS DE SÉCURITÉ --------------------
|
||||
header('X-Frame-Options: SAMEORIGIN');
|
||||
header('X-Content-Type-Options: nosniff');
|
||||
header('Referrer-Policy: no-referrer-when-downgrade');
|
||||
header("Content-Security-Policy: default-src 'none'; frame-ancestors 'none'; sandbox");
|
||||
header('X-Search-Mode: ' . (USE_SEARX_INSTANCES ? 'searx' : 'engines')); // ← Point 6
|
||||
|
||||
// -------------------- CLASSES --------------------
|
||||
|
||||
class CacheManager
|
||||
{
|
||||
private array $urlsCache = [];
|
||||
|
|
@ -109,22 +112,58 @@ class BangManager
|
|||
}
|
||||
}
|
||||
|
||||
class RequestHandler
|
||||
class EngineManager
|
||||
{
|
||||
private static ?array $cachedEngines = null;
|
||||
private array $engines = [];
|
||||
|
||||
public function __construct(private string $file = __DIR__ . '/engines.txt')
|
||||
{
|
||||
if (self::$cachedEngines === null) {
|
||||
$this->loadEngines();
|
||||
self::$cachedEngines = $this->engines;
|
||||
} else {
|
||||
$this->engines = self::$cachedEngines;
|
||||
}
|
||||
}
|
||||
|
||||
private function loadEngines(): void
|
||||
{
|
||||
if (!file_exists($this->file)) {
|
||||
throw new RuntimeException("Fichier engines.txt introuvable");
|
||||
}
|
||||
$lines = file($this->file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
||||
$this->engines = array_filter($lines, fn($line) => !empty(trim($line)));
|
||||
}
|
||||
|
||||
public function getRandomEngine(): string
|
||||
{
|
||||
if (empty($this->engines)) {
|
||||
throw new RuntimeException("Aucun moteur de recherche configuré dans engines.txt");
|
||||
}
|
||||
return $this->engines[array_rand($this->engines)];
|
||||
}
|
||||
}
|
||||
|
||||
class SearxHandler
|
||||
{
|
||||
public function __construct(private CacheManager $cache, private BangManager $bang) {}
|
||||
|
||||
public function handle(): void {
|
||||
public function handle(): void
|
||||
{
|
||||
$method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
|
||||
$query = $_REQUEST['q'] ?? null;
|
||||
|
||||
if ($query !== null && !$this->bang->tryRedirect($query)) {
|
||||
$instance = rtrim($this->cache->getRandomUrl(), '/');
|
||||
$url = $instance . '/search?' . http_build_query(['q' => $query]);
|
||||
|
||||
if ($method === 'GET') {
|
||||
$this->redirectGet($instance, $query);
|
||||
header("Location: $url");
|
||||
exit;
|
||||
} elseif ($method === 'POST') {
|
||||
$this->redirectGet($instance, $query);
|
||||
// $this->proxyPost($instance, $_POST);
|
||||
header("Location: $url"); // Redirige en GET pour simplifier
|
||||
exit;
|
||||
} else {
|
||||
http_response_code(405);
|
||||
exit('Méthode non autorisée');
|
||||
|
|
@ -135,57 +174,80 @@ class RequestHandler
|
|||
header("Location: $instance");
|
||||
exit;
|
||||
} elseif ($method === 'POST') {
|
||||
$this->proxyPost($instance, $_POST);
|
||||
header("Location: $instance");
|
||||
exit;
|
||||
} else {
|
||||
http_response_code(405);
|
||||
exit('Méthode non autorisée');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function redirectGet(string $instance, string $query): void {
|
||||
$url = $instance . '/search?' . http_build_query(['q' => $query]);
|
||||
class EngineHandler
|
||||
{
|
||||
public function __construct(private EngineManager $engineManager, private BangManager $bang) {}
|
||||
|
||||
public function handle(): void
|
||||
{
|
||||
$method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
|
||||
$query = $_REQUEST['q'] ?? null;
|
||||
|
||||
if ($query !== null && !$this->bang->tryRedirect($query)) {
|
||||
$engineTemplate = $this->engineManager->getRandomEngine();
|
||||
$url = sprintf($engineTemplate, rawurlencode($query));
|
||||
|
||||
if ($method === 'GET') {
|
||||
header("Location: $url");
|
||||
exit;
|
||||
}
|
||||
|
||||
private function proxyPost(string $urlBase, array $postData): void {
|
||||
$url = $urlBase . '/search';
|
||||
$ch = curl_init($url);
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_POST => true,
|
||||
CURLOPT_POSTFIELDS => http_build_query($postData),
|
||||
CURLOPT_HEADER => false,
|
||||
CURLOPT_FOLLOWLOCATION => true,
|
||||
CURLOPT_TIMEOUT => 10,
|
||||
CURLOPT_SSL_VERIFYPEER => true,
|
||||
]);
|
||||
$response = curl_exec($ch);
|
||||
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
|
||||
http_response_code($code);
|
||||
echo $response;
|
||||
} elseif ($method === 'POST') {
|
||||
header("Location: $url"); // Redirige en GET
|
||||
exit;
|
||||
} else {
|
||||
http_response_code(405);
|
||||
exit('Méthode non autorisée');
|
||||
}
|
||||
} elseif ($query === null) {
|
||||
// Rediriger vers la page d'accueil du premier moteur
|
||||
$engineTemplate = $this->engineManager->getRandomEngine();
|
||||
$homepage = str_replace('?query=%s', '', str_replace('?q=%s', '', $engineTemplate));
|
||||
if ($method === 'GET') {
|
||||
header("Location: $homepage");
|
||||
exit;
|
||||
} elseif ($method === 'POST') {
|
||||
header("Location: $homepage");
|
||||
exit;
|
||||
} else {
|
||||
http_response_code(405);
|
||||
exit('Méthode non autorisée');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------- EXECUTION --------------------
|
||||
try {
|
||||
$bang = new BangManager();
|
||||
$engineManager = new EngineManager();
|
||||
|
||||
if (USE_SEARX_INSTANCES) {
|
||||
$cache = new CacheManager();
|
||||
if ($cache->isExpired()) {
|
||||
if (!$cache->downloadInstances() || !$cache->extractValidUrls()) {
|
||||
http_response_code(500);
|
||||
exit('Erreur interne : impossible de générer le cache.');
|
||||
exit('Erreur interne : veuillez réessayer plus tard.');
|
||||
}
|
||||
}
|
||||
$handler = new SearxHandler($cache, $bang);
|
||||
} else {
|
||||
$handler = new EngineHandler($engineManager, $bang);
|
||||
}
|
||||
|
||||
$bang = new BangManager();
|
||||
$handler = new RequestHandler($cache, $bang);
|
||||
$handler->handle();
|
||||
|
||||
} catch (\Throwable $e) {
|
||||
// Ne pas exposer les détails techniques → Point 3
|
||||
error_log('Erreur interne : ' . $e->getMessage() . ' | Trace: ' . $e->getTraceAsString());
|
||||
http_response_code(500);
|
||||
exit('Erreur interne : ' . $e->getMessage());
|
||||
exit('Erreur interne : veuillez réessayer plus tard.');
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue