Bug #363
offen[Bugsink] ErrorException: Warning: file_get_contents(https://verl.optigov.app/api): Failed to open stream: Connection refused
0%
Beschreibung
Bugsink: https://bugsink.cytrus.de/issues/issue/f8181e34-5a7c-4413-97c4-fc67142e8e06/event/last/
Typ: NEW issue
Projekt: www-verl-de
Bugsink Alert
ErrorException: Warning: file_get_contents(https://verl.optigov.app/api): Failed to open stream: Connection refused
Automatisch erstellt durch n8n
KI-Analyse:
1. Ursache identifizieren¶
Der Stacktrace lügt nicht – aber er zeigt den Opfer, nicht den Täter.
Der Fehler file_get_contents(https://verl.optigov.app/api): Failed to open stream: Connection refused passiert sehr früh im Bootstrap (in public/index.php Zeile 17/20/21), bevor TYPO3 den Middleware-Dispatcher (MiddlewareDispatcher, VerifyHostHeader, etc.) regulär durchläuft.
Die im Stacktrace sichtbaren Middleware-Frames (VerifyHostHeader, NormalizedParamsAttribute, ResponsePropagation) sind Folgeerscheinungen: TYPO3 versucht, eine saubere Fehlerseite (Error Handling Middleware) zu rendern, scheitert aber daran, weil der Fehler bereits im index.php (oder einem sehr frühen require/autoload-Kontext) passiert ist.
Die eigentliche Ursache: In deiner public/index.php (Zeile 17, inside Closure, ausgeführt Zeile 20/21) wird synchrone HTTP-Kommunikation via file_get_contents() gegen https://verl.optigov.app/api ausgeführt.
-
"Connection refused": Der Zielhost (
verl.optigov.app) ist erreichbar (DNS klappt), aber Port 443 verweigert die Verbindung (kein Webserver lauscht, Firewall blockt, Service down, falscher Port/Protokoll). -
Architektureller Kapitalfehler: Externe HTTP-Calls im
index.php(Bootstrap-Kontext) blockieren den gesamten TYPO3-Start. Jeder Request (Backend, Frontend, CLI, Install Tool) wartet auf den Timeout/Refusal.
2. Fix beschreiben (konkret)¶
Sofortmaßnahme (Hotfix): public/index.php bereinigen¶
Öffne public/index.php. Suche den Block ca. Zeile 17–21. Er sieht vermutlich so aus:
// public:index.php ~ Zeile 17-21
$callback = function () { // Zeile 17
// ... Logik die file_get_contents('https://verl.optigov.app/api') nutzt ...
};
$callback(); // Zeile 20
// oder: $app->run(); // Zeile 21
Lösche diesen Code komplett oder kommentiere ihn aus. Der TYPO3-Bootstrap darf keine Business-Logik (API-Calls) enthalten.
Struktureller Fix (Richtige Integration)¶
Die Logik ("Daten von verl.optigov.app holen") gehört in eine eigene Extension als:
-
Middleware (PSR-15), wenn es auf jeden Request ankommt (z. B. Auth-Token validieren, Feature-Flags laden).
- Registrierung in
Configuration/RequestMiddlewares.php. -
Wichtig: Asynchron / Non-Blocking (ReactPHP/Guzzle Promises) oder gecacht (Redis/DB), nie synchron
file_get_contentsim Request-Zyklus.
- Registrierung in
- CommandController / Scheduler Task, wenn es ein periodischer Import/Sync ist.
- Service Class, die per Dependency Injection in Controller/Service genutzt wird.
Beispiel Middleware-Skeleton (sicher & performant):
// EXT:dein_projekt/Classes/Middleware/OptigovDataMiddleware.php
namespace Vendor\DeinProjekt\Middleware;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use TYPO3\CMS\Core\Cache\CacheManager;
use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
use GuzzleHttp\ClientInterface; // Nutze Guzzle (TYPO3 Core Dependency), nicht file_get_contents!
class OptigovDataMiddleware implements MiddlewareInterface
{
private FrontendInterface $cache;
private ClientInterface $httpClient;
public function __construct(CacheManager $cacheManager, ClientInterface $httpClient)
{
$this->cache = $cacheManager->getCache('optigov_api'); // Cache konfigurieren in ext_localconf.php
$this->httpClient = $httpClient;
}
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
// 1. Versuchen aus Cache (TTL z.B. 300s)
$data = $this->cache->get('api_data');
if ($data === false) {
// 2. Nur bei Cache-Miss: Async/Non-Blocking wäre besser, aber hier sync mit Timeout & Error Handling
try {
$response = $this->httpClient->request('GET', 'https://verl.optigov.app/api', [
'timeout' => 2.0, // WICHTIG: Hartes Timeout!
'http_errors' => false,
]);
if ($response->getStatusCode() === 200) {
$data = json_decode($response->getBody()->getContents(), true);
$this->cache->set('api_data', $data, ['tags' => ['optigov']], 300);
} else {
$data = []; // Fallback
}
} catch (\Throwable $e) {
// Logging via TYPO3 Logger, NICHT crashen!
\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Log\LogManager::class)
->getLogger(__CLASS__)->error('Optigov API unreachable', ['error' => $e->getMessage()]);
$data = $this->cache->get('api_data', true) ?? []; // Stale Cache als letztes Mittel
}
}
// 3. Daten in Request Attribute legen für Controller/View
$request = $request->withAttribute('optigovData', $data);
return $handler->handle($request);
}
}
Registrierung (Configuration/RequestMiddlewares.php):
return [
'optigov-data' => [
'target' => \Vendor\DeinProjekt\Middleware\OptigovDataMiddleware::class,
'before' => ['frontend'], // Oder 'after' => ['session'] je nach Use-Case
],
];
3. Betroffene TYPO3 Extension¶
Keine Core-Extension.
Es handelt sich um Projekt-spezifischen Code in public/index.php (oder eine manipulierte public/typo3/index.php / config/system/additional.php).
- Wenn der Code in
public/index.phpsteht: Keine Extension, sondern falsche Customization des Entry-Points. - Wenn der Code über
config/system/additional.phpoder einext_localconf.phpeines Projekt-Packages (sitepackage,project_base) eingebunden wird: Betroffene Extension = Dein Projekt-Package (z. B.vendor/project-baseodersitepackage).
Suche nach: file_get_contents, verl.optigov.app, curl_init, Guzzle in:
public/index.phppublic/typo3/index.phpconfig/system/additional.php-
packages/*/ext_localconf.php/Configuration/Services.yaml(Middlewares)
4. Confidence (0-100%)¶
98%
Begründung:
- Der Error Message (
file_get_contents... Connection refused) ist deterministisch. - Der Stacktrace zeigt
public:index.php:21als Einstiegspunkt (AbstractApplication::runwird vonindex.phpaufgerufen). - Die Middleware-Frames sind klassisches "Error Handling Rendering" (TYPO3 versucht freundlich zu sterben).
- Synchrones Netzwerk-IO im
index.phpist ein bekanntes Anti-Pattern, das genau dieses Fehlerbild (Totalausfall bei Downstream-Problemen) erzeugt.
Die verbleibenden 2% Unsicherheit: Minimale Chance, dass ein sehr früher auto_prepend_file (php.ini) oder eine manipulierte autoload.php den Call injiziert, aber der Frame public/index.php:21 deutet stark auf direkten Code im Entry Point hin.
Nichts anzuzeigen