php - 具有相同请求标头的 BASH cURL 和 PHP cURL 的不同响应
问题描述
这是一个非常有趣的问题。
我正在为微型网络广播播放器编写 API。为了获得当前曲目,我正在解析演员服务器前端。
在http://deepmix.ru的示例中,它是一个 SHOUTcast 1.x 服务器,我能够解析 URI http://85.21.79.31:7128/played.html。
当我在 FireFox 中请求 URI 时,我会看到显示已播放曲目列表的网页。如果我从托管我的 API 的服务器的 BASH 请求带有 cURL 的 URI,我会得到该服务器的 404。
$ curl -v -G http://85.21.79.31:7128/played.html
* Trying 85.21.79.31...
* Connected to 85.21.79.31 (85.21.79.31) port 7128 (#0)
> GET /played.html HTTP/1.1
> Host: 85.21.79.31:7128
> User-Agent: curl/7.47.0
> Accept: */*
>
ICY 404 Resource Not Found
icy-notice1:<BR>SHOUTcast Distributed Network Audio Server/Linux v1.9.8<BR>
icy-notice2:The resource requested was not found<BR>
* Connection #0 to host 85.21.79.31 left intact
我认为适当的用户代理可能会帮助并添加Mozilla
以接收网页。所以这奏效了。
$ curl -v -A "Mozilla" -G http://85.21.79.31:7128/played.html
* Trying 85.21.79.31...
* Connected to 85.21.79.31 (85.21.79.31) port 7128 (#0)
> GET /played.html HTTP/1.1
> Host: 85.21.79.31:7128
> User-Agent: Mozilla
> Accept: */*
>
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< content-type:text/html
<
<HTML>[...]<title>SHOUTcast Administrator</title>[...]</HEAD><BODY topmargin=0 leftmargin=0 marginheight=0 marginwidth=0 bgcolor=#000000 text=#EEEEEE link=#001155 vlink=#001155 alink=#FF0000><font class=default><table width=100% border=0 cellpadding=0 cellspacing=0><tr><td height=50><font class=logoText> SHOUTcast Song History</font></td></tr><tr><td height=14 align=right><font class=ltv><a id=ltv href="http://www.shoutcast.com/">SHOUTcast Server Version 1.9.8/Linux</a>[...]</body></html>
根据我的发现,我将请求转移到我的 PHP cURL 实现中。
$curlHandler = curl_init();
curl_setopt_array(
$curlHandler,
[
CURLINFO_HEADER_OUT => true,
CURLOPT_URL => 'http://85.21.79.31:7128/played.html',
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_USERAGENT => 'Mozilla',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HEADER => false,
CURLOPT_NOBODY => true
]
);
$response = curl_exec( $curlHandler );
$info = curl_getinfo( $curlHandler );
curl_close( $curlHandler );
var_dump( $info );
var_dump( $response );
但我得到了 404 响应。
array(31) {
["request_header"]=>
string(87) "GET /played.html HTTP/1.1
Host: 85.21.79.31:7128
User-Agent: Mozilla
Accept: */*
"
}
Warning: file_get_contents(http://85.21.79.31:7128/played.html): failed to open stream: HTTP request failed! ICY 404 Resource Not Found
in /vagrant/src/Readers/CurrentTrackReader.php on line 50
在比较请求标头时没有区别。所以我假设我看不到 BASH 和 PHP 的 cURL 实现之间存在差异。
那么这里会发生什么?
更新 (2019-07-31)
附加运行时环境信息
操作系统
Linux hostname 4.19.0-0.bpo.5-amd64 #1 SMP Debian 4.19.37-4~bpo9+1 (2019-06-19) x86_64 GNU/Linux
PHP
PHP Version 7.3.7-2+0~20190725.42+debian9~1.gbp848ca5
更新 (2019-07-31)
有关 cURL 的其他信息
重击
$ curl --version
curl 7.47.0 (x86_64-pc-linux-gnu) libcurl/7.47.0 GnuTLS/3.4.10 zlib/1.2.8 libidn/1.32 librtmp/2.3
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp smb smbs smtp smtps telnet tftp
Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz TLS-SRP UnixSockets
phpinfo()
cURL support | enabled
cURL Information | 7.52.1
Age | 3
Features
AsynchDNS | Yes
CharConv | No
Debug | No
GSS-Negotiate | No
IDN | Yes
IPv6 | Yes
krb4 | No
Largefile | Yes
libz | Yes
NTLM | Yes
NTLMWB | Yes
SPNEGO | Yes
SSL | Yes
SSPI | No
TLS-SRP | Yes
HTTP2 | Yes
GSSAPI | Yes
KERBEROS5 | Yes
UNIX_SOCKETS | Yes
PSL | Yes
HTTPS_PROXY | Yes
Protocols | dict, file, ftp, ftps, gopher, http, https, imap, imaps, ldap, ldaps, pop3, pop3s, rtmp, rtsp, scp, sftp, smb, smbs, smtp, smtps, telnet, tftp
Host | x86_64-pc-linux-gnu
SSL Version | OpenSSL/1.0.2s
ZLib Version | 1.2.8
libSSH Version | libssh2/1.7.0
Directive | Local Value | Master Value
curl.cainfo | no value | no value
解决方案
这是我自己的一个很大的错。
首先,我把它留CURLOPT_NOBODY => true
在了代码中(见问题),这导致了一个空的响应。
其次,我留file_get_contents( $uri )
在了我的代码中,这导致了问题中发布的警告。
总之,在删除这两个 cURL 时,它们都按预期工作。
推荐阅读
- android - 如何将 RTSP 视频 url 播放到 EXOPlayer
- php - 模型中的 Yii2 Getter Setter
- ruby-on-rails - 允许的参数仍然未经允许
- c# - 推迟任务的开始
- python - 打印并覆盖最后一个可变长度行(在 IPython 中)
- rust - 如何在运行时打印函数、变量名、闭包等的文本?
- javascript - 元素选择器内的jQuery变量
- javascript - 在没有映射或循环的情况下向所有对象数组添加键
- sql - 将 SQL 查询结果转换为 XML
- c# - ASP.NET Core Web API StringLocalizer 不提供 resx 文件中的值