1
0
Files
PonyWave-Tools/url_expander/expand.php
2025-03-21 21:03:50 +01:00

175 lines
6.2 KiB
PHP

<?php
header('Content-Type: application/json');
// Fehlerberichterstattung für Debug-Zwecke (in der Produktion auskommentieren)
// error_reporting(E_ALL);
// ini_set('display_errors', 1);
// CORS-Header setzen (bei Bedarf anpassen)
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: POST, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type");
// OPTIONS-Anfragen für CORS-Preflight behandeln
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(200);
exit();
}
// Nur POST-Anfragen zulassen
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
echo json_encode(['error' => 'Nur POST-Anfragen erlaubt']);
exit();
}
// URL aus der Anfrage abrufen
$url = isset($_POST['url']) ? trim($_POST['url']) : '';
// Überprüfen, ob eine URL angegeben wurde
if (empty($url)) {
echo json_encode(['error' => 'Keine URL angegeben']);
exit();
}
// Überprüfen, ob die URL gültig ist
if (!filter_var($url, FILTER_VALIDATE_URL)) {
echo json_encode(['error' => 'Ungültige URL']);
exit();
}
// Funktion, um eine URL zu erweitern und weiterleitungen zu verfolgen
function expandUrl($url, $maxRedirects = 10) {
$redirects = 0;
$redirectChain = [$url]; // Speichern der ursprünglichen URL als erster Eintrag in der Kette
// Zuerst versuchen mit HEAD-Anfrage (schneller)
$options = [
CURLOPT_URL => $url,
CURLOPT_HEADER => true,
CURLOPT_NOBODY => true, // Nur HEAD-Anfrage
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false, // Wir verfolgen Weiterleitungen manuell
CURLOPT_MAXREDIRS => 0, // Keine automatischen Weiterleitungen
CURLOPT_TIMEOUT => 8, // Zeitlimit (Sekunden)
CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36',
CURLOPT_SSL_VERIFYPEER => false, // SSL-Prüfung deaktivieren
CURLOPT_SSL_VERIFYHOST => 0, // SSL-Hostprüfung deaktivieren
CURLOPT_HTTPHEADER => [ // Standard-Header für eine normale Browser-Anfrage
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language: de,en-US;q=0.7,en;q=0.3',
'Connection: keep-alive',
'Upgrade-Insecure-Requests: 1',
'Cache-Control: max-age=0'
]
];
$currentUrl = $url;
$method = 'HEAD'; // Wir fangen mit HEAD an, könnten aber zu GET wechseln
while ($redirects < $maxRedirects) {
// cURL-Session initialisieren
$ch = curl_init();
$options[CURLOPT_URL] = $currentUrl;
curl_setopt_array($ch, $options);
// Anfrage ausführen
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
// Bei einem 405 (Method Not Allowed) oder sonstigen Fehler, zu GET wechseln
if (($response === false || $httpCode >= 400) && $method === 'HEAD') {
curl_close($ch);
// Auf GET-Anfrage umstellen
$method = 'GET';
$options[CURLOPT_NOBODY] = false; // GET statt HEAD
$options[CURLOPT_HEADER] = true; // Headers im Output behalten
continue; // Wiederholen mit neuer Methode
}
// Fehlerprüfung
if ($response === false) {
$error = curl_error($ch);
curl_close($ch);
return ['error' => 'cURL-Fehler: ' . $error];
}
// Bei Fehlern, die nicht durch Methodenwechsel behoben werden können, abbrechen
if ($httpCode >= 400 && $method === 'GET') {
curl_close($ch);
return ['error' => 'HTTP-Fehler: ' . $httpCode];
}
// Auf Weiterleitungen prüfen
if ($httpCode >= 300 && $httpCode < 400) {
// Header extrahieren
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$header = substr($response, 0, $headerSize);
// Location-Header suchen
if (preg_match('/Location:(.*?)\r/i', $header, $matches)) {
$locationUrl = trim($matches[1]);
// Relative URL in absolute umwandeln
if (!preg_match('/^https?:\/\//i', $locationUrl)) {
$parts = parse_url($currentUrl);
$base = $parts['scheme'] . '://' . $parts['host'];
if (isset($parts['port'])) $base .= ':' . $parts['port'];
if (substr($locationUrl, 0, 1) === '/') {
$locationUrl = $base . $locationUrl;
} else {
$path = isset($parts['path']) ? $parts['path'] : '/';
$path = substr($path, 0, strrpos($path, '/') + 1);
$locationUrl = $base . $path . $locationUrl;
}
}
// Zur Weiterleitungskette hinzufügen
$redirectChain[] = $locationUrl;
$currentUrl = $locationUrl;
$redirects++;
curl_close($ch);
continue;
}
}
// Keine Weiterleitung mehr - wir haben die Ziel-URL erreicht
curl_close($ch);
break;
}
// Letzter URL ist die Ziel-URL
$finalUrl = end($redirectChain);
// Überprüfe ob wir das Maximum an Weiterleitungen erreicht haben
if ($redirects >= $maxRedirects) {
return [
'expanded_url' => $finalUrl,
'redirect_chain' => $redirectChain,
'info' => 'Maximale Anzahl von Weiterleitungen erreicht'
];
}
// URL auf Sonderzeichen und Encodierung prüfen
$finalUrl = htmlspecialchars_decode($finalUrl);
// Alle URLs in der Kette dekodieren
$decodedChain = array_map('htmlspecialchars_decode', $redirectChain);
// Erfolgreiche Expansion
return [
'expanded_url' => $finalUrl,
'redirect_chain' => $decodedChain,
'redirect_count' => count($decodedChain) - 1
];
}
// URL erweitern
$result = expandUrl($url);
// Ergebnis zurückgeben
echo json_encode($result);
?>