2

When accessing this URL in my PC browser, I see a screenshot from a stream recorded by my HikVision NVR

http://admin:[email protected]/ISAPI/Streaming/channels/201/picture?videoResolutionWidth=1920&videoResolutionHeight=1080

but when I try to access the same url from an php file executed by Apache server on a RaspberryPi board I have in the same network, get the 401 Unauthorized error, I tried 3 different ways of accessing the url, and none worked

<?php

/* v1 */
$data = file_get_contents("http://admin:[email protected]/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; 
?>

And the errors are those :

v1:

[Tue Nov 02 21:31:17.529527 2021] [:error] [pid 30366] [client 192.168.1.29:65434] PHP Warning:  file_get_contents(http://[email protected]/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

When accessing the URL in browser with correct password, the image shows correctly, the headers are as follows:

GENERAL

Request URL: http://admin:[email protected]/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:[email protected]/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.

1
  • 1
    php.net/manual/en/wrappers.http.php#118291: "Passing authentication information in the URL [...] works for HTTP "Basic" access authentication but not for HTTP "Digest" access authentication." And what do we see in the results of your wget attempt ...? Authentication selected: Digest Commented Nov 3, 2021 at 9:06

1 Answer 1

4

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);
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you both! That was the issue, BASIC auth vs DIGEST .. I only tried the wget once, yesterday while I was writing this question, I tried to give you as many details as I could.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.