'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); ?>