grund; } /** Den Inhalt der Adresse, oder null wenn sie nicht mit 200 antwortet. */ public function get(string $url): ?string { $this->grund = ''; // Kein http, kein file, kein ftp: ein Update, das über eine unverschlüsselte Verbindung // kommt, kann unterwegs ausgetauscht worden sein. if (!str_starts_with($url, 'https://')) { $this->grund = 'Nur HTTPS-Adressen werden geholt.'; return null; } if (function_exists('curl_init')) { $curl = curl_init($url); curl_setopt_array($curl, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_FOLLOWLOCATION => true, CURLOPT_MAXREDIRS => 3, CURLOPT_SSL_VERIFYPEER => true, CURLOPT_SSL_VERIFYHOST => 2, CURLOPT_CONNECTTIMEOUT => $this->connectTimeout, CURLOPT_TIMEOUT => $this->timeout, CURLOPT_USERAGENT => 'KantSites-Updater', ]); $antwort = curl_exec($curl); $status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE); $fehler = curl_errno($curl); $text = curl_error($curl); curl_close($curl); if (is_string($antwort) && 200 === $status) { return $antwort; } // Ein fehlender Zertifikatsspeicher ist keine kaputte Leitung, sondern eine // Einstellung - und er sieht sonst genauso aus wie eine gesperrte Verbindung. $this->grund = match (true) { in_array($fehler, self::ZERTIFIKATSFEHLER, true) => 'Das Zertifikat der Gegenstelle lässt sich nicht prüfen: Diesem PHP fehlt ein Zertifikatsspeicher (curl.cainfo in der php.ini). Geholt wird trotzdem nur mit Prüfung - ein Update ohne sie könnte unterwegs ausgetauscht worden sein.', 0 !== $fehler => 'Die Verbindung kam nicht zustande: '.$text, 0 === $status => 'Der Server hat nicht geantwortet.', default => sprintf('Die Adresse antwortet mit %d statt 200.', $status), }; // Bei einem Zertifikatsproblem lohnt der zweite Weg: Der Dateizeiger benutzt die // Einstellungen von OpenSSL, und die sind manchmal gesetzt, wo curl nichts findet. if (!in_array($fehler, self::ZERTIFIKATSFEHLER, true)) { return null; } } if (!filter_var(ini_get('allow_url_fopen'), FILTER_VALIDATE_BOOL)) { $this->grund = '' !== $this->grund ? $this->grund : 'Dieser Server darf keine Adressen abrufen: curl fehlt und allow_url_fopen ist abgeschaltet.'; return null; } $context = stream_context_create([ 'http' => ['timeout' => $this->timeout, 'follow_location' => 1, 'max_redirects' => 3, 'header' => "User-Agent: KantSites-Updater\r\n"], 'ssl' => ['verify_peer' => true, 'verify_peer_name' => true], ]); $antwort = @file_get_contents($url, false, $context); if (is_string($antwort)) { $this->grund = ''; return $antwort; } if ('' === $this->grund) { $this->grund = 'Die Adresse war über den Dateizeiger nicht erreichbar.'; } return null; } }