我该如何使用PHP/cURL代理请求并代理响应头?

3
我有一个浏览器客户端正在从我的Web服务中获取部分内容,例如使用Range:bytes = 100000-200000。请求进入一个PHP页面,fetch.php。在该PHP页面中,我使用 $ _SERVER ['HTTP_RANGE'] 获取所请求的范围,然后使用 curl_setopt 设置到curl请求中- CURLOPT_RANGE 。 我遇到的问题是,远程服务器响应206 Partial Content 状态和 Content-Range 标头,但我的PHP页面只回复了一个 200 OK 而没有 Content-Range ,因此结果是客户端认为已经完成的部分文件。问题是,在PHP中如何将生成的 Content-Range 设置为原始请求?
如果我事先知道范围(我不知道),那么我可以使用 header 命令并完成它,但是范围包含在响应中。我可以在curl中设置接收所有带有内容的标头,然后解析标头,使用 header 设置它,并将响应设置为206,然后输出所有数据...但是数据是二进制的,更何况非常大,因此这似乎是次优的选择。
我想知道是否可以在PHP中设置选项,以便不发送任何自己的标头,基本上只是将整个响应回显给请求者。没有充分考虑这一点,这可能与其他标头,缓存,连接,代理等有问题。
也许我可以以某种方式从curl中接收仅标头(某种部分执行?),获取所需内容,设置标头和响应代码,然后基本上完成exec并直接输出实际响应?从curl中看不出如何实现这一点。
设置实际反向代理也不是一个选项,因为PHP脚本实际上确定了资源的目标服务器(它不是静态的)。
我想我可以跳过使用curl并直接进行TCP / TLS连接,并管理HTTP请求/响应。
还有其他想法或可能性吗?谢谢!
2个回答

1

这可能不是最好的解决方案,但它适用于我需要的场景。基本上,只需使用stream_socket_client执行自己的HTTP(S)获取,并确保传递必要的响应代码和标头,例如:

while ( true ) {
    $h = stream_get_line( $fp, 2048, "\r\n");
    if ( !$h ) {
        break;
    }
    if ( 0==strncasecmp( $h, 'Content-', 8 ) ) {
        header( $h );
    }
    else if ( 0==strncasecmp( $h, 'HTTP/1.', 7 ) ) {
        header( $h );
    }
}

fpassthru( $fp );

0
也许我可以通过curl只接收头部信息。
这是HTTP协议的一部分,请参见:在PHP中使用HTTP HEAD命令的最简单方法是什么? 否则,我不明白问题出在哪里。
如果您只收到部分响应,则可能是由于连接超时。可以使用以下方式更改它:
CURLOPT_CONNECTTIMEOUT

我有一个客户端和两个服务器,代理和实际服务器:C->P->S。客户端通过Range头请求部分内容。代理使用curl将请求传递给服务器。服务器正确响应206部分内容。然而,PHP代理响应返回为200 OK,因此客户端看起来像代理忽略了请求的部分,并且只是进行了完整响应,而实际上它是部分的。我需要让curl和PHP返回已正确满足响应的部分。 - mark
我还不完全确定,但是在我的理解中,您正在向一个服务器请求206头,然后从另一个服务器发送它。难道您不需要像这样开始页面吗: <?php header("HTTP/1.0 206 Partial Content"); ?> - Kohjah Breese
你说得对,我可以像你说的那样强制响应代码,但据我所知,我无法从主服务器的响应中获取Content-Range以放置该标头。我可以让curl返回标头,但它也会返回所有内容(我宁愿不要将其作为一个大字符串返回)...我没有看到在不获取内容的情况下获取标头的方法。最终,我成功地使用了stream_socket_client而不是curl;我将在这个问题中发布它作为答案,以防其他人遇到这个问题。 - mark

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接