Stop a PHP cURL Transfer After a Body Prefix
Keep a bounded prefix in a write callback and recognize only the write error deliberately caused by that callback.
A cURL write callback can retain a limited body prefix and stop the transfer once that limit is reached. Use your own flag to distinguish that deliberate stop from another write failure.
For a fresh handle whose target URL is already configured:
$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);
}
The proxy URL’s socks5h scheme asks the proxy to resolve the target hostname. For an allowed public-target test on the fresh handle shown, a no-account entry from the SOCKS5 proxy list can supply that endpoint. TLS certificate verification keeps its normal settings.
Returning zero for a nonempty chunk tells libcurl that the callback did not accept the supplied data. It aborts with CURLE_WRITE_ERROR. Only the combination of that error and the callback’s limitReached flag is treated as expected here.
A response shorter than the limit finishes normally. At or above the limit, prefix holds at most 32 KiB even if the final callback receives a larger chunk. Callback chunk sizes vary; a requested buffer size is not a promise of fixed-length calls.
This limits the retained body, not every byte already buffered or transferred on the connection. The prefix can end inside a multibyte character, JSON value or HTML element, so do not assume it is a complete parseable document.