Callback запису cURL може зберігати обмежений префікс тіла й зупиняти передавання, щойно цю межу досягнуто. Використовуйте власний прапорець, щоб відрізняти таку навмисну зупинку від іншої помилки запису.

Для нового handle, у якого цільовий URL уже налаштовано:

$limit = 32768;
$prefix = '';
$limitReached = false;

curl_setopt_array($ch, [
    CURLOPT_PROXY => 'socks5h://proxy.example.net:1080',
    CURLOPT_HEADER => false,
    CURLOPT_WRITEFUNCTION => function ($handle, $chunk)
        use (&$prefix, &$limitReached, $limit) {
        $remaining = $limit - strlen($prefix);
        $prefix .= substr($chunk, 0, $remaining);

        if (strlen($prefix) >= $limit) {
            $limitReached = true;
            return 0;
        }

        return strlen($chunk);
    },
]);

$result = curl_exec($ch);
$error = curl_errno($ch);

$expectedStop = $limitReached && $error === CURLE_WRITE_ERROR;
if ($result === false && !$expectedStop) {
    throw new RuntimeException(curl_error($ch), $error);
}

Схема socks5h в URL проксі просить проксі розв'язати ім'я цільового хоста. Для дозволеної перевірки публічної цілі на показаному новому handle запис без облікового запису зі списку SOCKS5-проксі може надати цю кінцеву точку. Перевірка сертифіката TLS зберігає звичайні налаштування.

Повернення нуля для непорожнього фрагмента повідомляє libcurl, що callback не прийняв надані дані. Передавання переривається з CURLE_WRITE_ERROR. Тут очікуваним вважається лише поєднання цієї помилки та прапорця limitReached callback-а.

Відповідь, коротша за межу, завершується нормально. На межі або вище prefix зберігає щонайбільше 32 KiB, навіть якщо останній callback отримує більший фрагмент. Розміри фрагментів різняться; запитаний розмір буфера не гарантує викликів фіксованої довжини.

Це обмежує збережене тіло, а не кожен байт, уже поміщений у буфер або переданий з'єднанням. Префікс може закінчитися всередині багатобайтового символу, значення JSON або елемента HTML, тому не вважайте його повним документом, який можна розібрати.

Схожі статті