php / php/php-src

Infinite waiting for CURLOPT_WRITEFUNCTION in case of no response

Offen
#13,711 7 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Bug Extension: curl Status: Needs Triage
Vorherrschende Sprache
C
Sterne
40.4k
Forks
8.2k
Ø Merge
2 T. 13 Std.
Gemergte PRs (30 T.)
96

Beschreibung

Description

To reach an address that responds every 5 seconds, I use CURLOPT_WRITEFUNCTION. Since I want to maintain an infinite connection, I have CURLOPT_TIMEOUT => 0.

function writer($ch, $data) {
  handler($data);
  return strlen($data);
}

$ch = curl_init("$urlcam/cgi-bin/eventManager.cgi?action=attach&codes=[NewFile]&heartbeat=5");
curl_setopt_array($ch, [
        CURLOPT_CONNECTTIMEOUT => 20,
        CURLOPT_TIMEOUT => 0,
        CURLOPT_RETURNTRANSFER => 1,
        CURLOPT_WRITEFUNCTION => 'writer'
    ]);

$result = curl_exec($ch);
curl_close($ch);

The response looks like this:

--myboundary
Content-Type: text/plain
Content-Length: 9
Heartbeat
--myboundary
Content-Type: text/plain
Content-Length: 9
Heartbeat
...

Everything works as long as there is a response from the url. However, if the url stops responding, nothing happens. No error or warning. The PHP script will stay inside the "writer" function and never leave it.

For example, if you implement this functionality using fopen:

$resource = fopen("http://".$host.$uri, 'r', false, $context);
while (!feof($resource)) {
    print_r(date("d-m-Y H:i:s"));
    $line = fgets($resource);
    if (str_contains($line,"--myboundary")) {
        handler($response);
        $response = '';
    } else {
        $response.=$line;
    }
}

Then the print_r function will be called every minute. Yes, if the url is restored, the fopen connection will not be restored, but at least we can handle the error/state to restart the script. In the case of CURL, this cannot be done as nothing happens.

We need to add functionality to leave the function specified in CURLOPT_WRITEFUNCTION. I suppose you could take CURLOPT_CONNECTTIMEOUT and display an error if the WRITEFUNCTION has not received a response within that time.

PHP Version

8.1.23

Operating System

Ubuntu 20.04

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Das Issue enthält eine PHP-Reproduktion mit curl_exec, die CURLOPT_WRITEFUNCTION und eine URL mit unbegrenztem Streaming verwendet; beginne damit, den Fall der ausbleibenden Antwort zu reproduzieren und die Verarbeitung der Option in php-src nachzuverfolgen. Vergleiche das beobachtete Verhalten mit den angeforderten Timeout- und Fehlersemantiken und ziehe die Arbeit als erledigt in Betracht, wenn ein Zeitraum ohne Antwort wie beschrieben erkannt und behandelt werden kann.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
php
Bereich
networking
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.