php / php/php-src

Infinite waiting for CURLOPT_WRITEFUNCTION in case of no response

Đang mở
#13,711 7 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Bug Extension: curl Status: Needs Triage
Ngôn ngữ chính
C
Star
40.4k
Fork
8.1k
Merge trung bình
2 ngày 13 giờ
Pull request đã merge (30 ngày)
96

Mô tả

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

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Hướng nghiên cứu

Issue cung cấp một bản tái hiện bằng PHP curl_exec sử dụng CURLOPT_WRITEFUNCTION và một URL streaming vô thời hạn; trước tiên hãy tái hiện trường hợp phản hồi bị treo và theo dõi cách tùy chọn này được xử lý trong php-src. So sánh hành vi quan sát được với ngữ nghĩa timeout và lỗi được yêu cầu, đồng thời xem công việc là hoàn tất khi một khoảng thời gian không có phản hồi có thể được phát hiện và xử lý như mô tả.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
php
Lĩnh vực
networking
Loại issue
Lỗi
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Đình trệ
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
35/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.