Interromper uma transferência PHP cURL após um prefixo do corpo
Mantenha um prefixo limitado numa função de escrita e reconheça apenas o erro de escrita causado deliberadamente por essa função.
Uma função de escrita do cURL pode guardar um prefixo limitado do corpo e interromper a transferência assim que esse limite é atingido. Use o seu próprio indicador para distinguir essa paragem deliberada de outra falha de escrita.
Para um handle novo cujo URL de destino já está configurado:
$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);
}
O esquema socks5h do URL do proxy pede ao proxy que resolva o nome do host de destino. Para um teste permitido contra um destino público no handle novo mostrado, uma entrada sem conta da lista de proxies SOCKS5 pode fornecer esse endpoint. A verificação do certificado TLS mantém as suas definições normais.
Devolver zero para um bloco não vazio diz ao libcurl que a função não aceitou os dados fornecidos. Aborta com CURLE_WRITE_ERROR. Aqui só é considerada esperada a combinação desse erro e do indicador limitReached da função.
Uma resposta mais curta do que o limite termina normalmente. No limite ou acima, prefix retém no máximo 32 KiB mesmo que a função final receba um bloco maior. Os tamanhos dos blocos variam; um tamanho de buffer pedido não garante chamadas de comprimento fixo.
Isto limita o corpo retido, não cada byte já guardado em buffer ou transferido na ligação. O prefixo pode terminar a meio de um carácter multibyte, de um valor JSON ou de um elemento HTML, por isso não assuma que é um documento completo que possa ser analisado.