代理负责传送数据。你的写回调返回了错误的值。于是 libcurl 中止,周围的代码又报出一次“代理下载失败”。

回调必须报告它实际处理了多少个收到的字节。返回不同的数字即表示失败。对于有意阻塞的可写接收端,片段可能像这样:

curl_setopt($handle, CURLOPT_PROXY, 'http://proxy.example:8080');
curl_setopt($handle, CURLOPT_WRITEFUNCTION,
    function ($handle, $chunk) use ($sink) {
        $written = fwrite($sink, $chunk);
        return $written === false ? 0 : $written;
    }
);

这里假定现有应用自己持有句柄和可写接收端。写入失败或写入不完整会中止,而不会悄悄声称整个分块已保存。非阻塞接收端需要恰当的缓冲以及暂停/恢复设计;这个小片段并没有提供这样的设计。

按字节计数,而不是按显示的字符计数。数据可能是二进制的,也可能是多字节文本序列的一部分。一次回调并不一定对应一行、一个 JSON 文档或服务端的一条消息。

增量解析需要在多次回调之间维护自己的状态。反过来,把小块全部累积到结束,对于很小且有界的响应也许可行,但它不是应对庞大或无尽数据流的内存策略。

保留传输结果和回调失败的证据。在建立有效的代理路由之后,仍可能发生本地磁盘错误或解析器中止。如果你打算在前缀之后停止,请把这个有意的回调停止单独标记出来。更换代理地址无法修复已经停止接收数据的接收端。

相关文章