2

在我的 PC 浏览器中访问此 URL 时,我看到了来自我的海康威视 NVR 记录的流的屏幕截图

http://admin:441e3!@192.168.1.90/ISAPI/Streaming/channels/201/picture?videoResolutionWidth=1920&videoResolutionHeight=1080

但是当我尝试从 Apache 服务器在同一网络中的 RaspberryPi 板上执行的 php 文件访问相同的 url 时,得到 401 Unauthorized 错误,我尝试了 3 种不同的访问 url 的方式,但都没有

<?php

/* v1 */
$data = file_get_contents("http://admin:441e3!@192.168.1.90/ISAPI/Streaming/channels/201/picture?videoResolutionWidth=1920&videoResolutionHeight=1080");
header('Content-type: image/jpeg');
echo $data;

/* v2 */

$username = 'admin';
$password = '441e3!';
$url = 'http://192.168.1.90/ISAPI/Streaming/channels/201/picture?videoResolutionWidth=1920&videoResolutionHeight=1080';



$context = stream_context_create(array(
    'http' => array(
        'header'  => "Authorization: Basic " . base64_encode("$username:$password")
    )
));
$data = file_get_contents($url, false, $context);

header('Content-type: image/jpeg');
echo $data;

/* v3 */

$login = 'admin';
$password = '441e3!';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "$login:$password");
$data = curl_exec($ch);
curl_close($ch);

header('Content-type: image/jpeg');
echo $data; 
?>

错误是:

v1:

[Tue Nov 02 21:31:17.529527 2021] [:error] [pid 30366] [client 192.168.1.29:65434] PHP Warning:  file_get_contents(http://...@192.168.1.90/ISAPI/Streaming/channels/201/picture?videoResolutionWidth=1920&amp;videoResolutionHeight=1080): failed to open stream: HTTP request failed! HTTP/1.0 401 Unauthorized\r\n in /var/www/html/security                                                                   _cam3.php on line 30

v2 & v3 error:

[Tue Nov 02 21:55:07.643803 2021] [:error] [pid 26933] [client 192.168.1.29:60984] PHP Warning:  file_get_contents(http://192.168.1.90/ISAPI/Streaming/channels/201/picture?videoResolutionWidth=1920&amp;videoResolutionHeight=1080)     : failed to open stream: HTTP request failed! HTTP/1.0 401 Unauthorized\r\n in /var/www/html/security_cam3.php on line 24

用正确的密码在浏览器中访问URL时,图像正确显示,标题如下:

GENERAL

Request URL: http://admin:441e3!@192.168.1.90/ISAPI/Streaming/channels/201/picture?videoResolutionWidth=1920&videoResolutionHeight=1080
Request Method: GET
Status Code: 200 OK
Remote Address: 192.168.1.90:80
Referrer Policy: strict-origin-when-cross-origin

RESPONSE HEADERS

HTTP/1.1 200 OK
Connection: close
Pragma: no-cache
Cache-Control: no-cache
Content-Type: image/jpeg
Content-Length: 123814

REQUEST HEADERS

GET /ISAPI/Streaming/channels/201/picture?videoResolutionWidth=1920&videoResolutionHeight=1080 HTTP/1.1
Host: 192.168.1.90
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9

QUERY STRING PARAMETERS

videoResolutionWidth: 1920
videoResolutionHeight: 1080

I also tried accessing the image directly from RaspberryPi command line, using wget command, the image saved correctly, so it must be something on the PHP side.

root@bananapi:~# wget 'http://admin:441e3!-@192.168.1.90/ISAPI/Streaming/channels/201/picture?videoResolutionWidth=1920&videoResolutionHeight=1080'
--2021-11-02 22:57:50--  http://admin:*password*@192.168.1.90/ISAPI/Streaming/channels/201/picture?videoResolutionWidth=1920&videoResolutionHeight=1080
Connecting to 192.168.1.90:80... connected.
HTTP request sent, awaiting response... 401 Unauthorized
Authentication selected: Digest realm="da9ea0f8f352408658c64b0a", domain="::", qop="auth", nonce="e1f5166b2054a18a2a17595a4bbfaf23:1635894137125", opaque="", algorithm="MD5", stale="FALSE"
Reusing existing connection to 192.168.1.90:80.
HTTP request sent, awaiting response... 200 OK
Length: 125170 (122K) [image/jpeg]
Saving to: ‘picture?videoResolutionWidth=1920&videoResolutionHeight=1080’

picture?videoResolutionWidth=1920&videoResolutionHeight=10 100%[======================================================================================================================================>] 122.24K  --.-KB/s    in 0.003s

2021-11-02 22:57:50 (39.7 MB/s) - ‘picture?videoResolutionWidth=1920&videoResolutionHeight=1080’ saved [125170/125170]


Any help is appreciated.

4

1 回答 1

3

Changing my comment to an answer:

Did you actually try v3 by itself and not part of the combined script? You will definitely not get a file_get_contents error if you're using cURL, which makes me suspect cURL might actually be working (but possibly not returning the data you're expecting). Add a check to see if cURL's $data === false, and if so, check the output of curl_error($ch).

One other thing I noticed is, based on the wget code, it looks like that succeeded using HTTP Digest auth (CURLAUTH_DIGEST), rather than Basic auth.

So, overall, I'd recommend this as a next step:

$login = 'admin';
$password = '441e3!';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
curl_setopt($ch, CURLOPT_USERPWD, "$login:$password");
$data = curl_exec($ch);

if ($data === false) {
    echo 'ERROR: ' . curl_error($ch);
}
else {
    header('Content-type: image/jpeg');
    echo $data; 
}

curl_close($ch);
于 2021-11-03T02:01:51.317 回答