Jump to content
Marcio

IdHttp not connect IP Camera error 401

Recommended Posts

I'm connecting to an IP camera to capture the image but an error occurs that I can't solve.

 

My code

 

function TForm2.fGetImagem(pUsuario, pSenha, pUrl : string ; out  pImagem : TJPEGImage ) :Boolean;
var
  MS: TMemoryStream;
  IdHTTP1 : TIdHTTP;
  I       : Integer;

begin
  I  := 0;
  MS := TMemoryStream.Create;
  IdHTTP1 := TIdHTTP.Create(nil);
  With IdHTTP1 do
  begin
    ReadTimeout      := 15000;
    Request.BasicAuthentication := False;
    Request.Username := pUsuario;
    Request.Password := pSenha;
    Request.UserAgent := 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36';
    HTTPOptions := [hoInProcessAuth, hoForceEncodeParams];


  end;

 

  try
    while (IdHTTP1.ResponseCode <> 200) AND (I < 2 ) do
      try
        MS.Clear;

        IdHTTP1.Get(pUrl, MS);

        MS.Position := 0;
        if ( MS.Size > 0 ) and ( IdHTTP1.ResponseCode = 200 ) then
        begin
          pImagem.LoadFromStream(MS);
          pImagem.CompressionQuality := 40;
          pImagem.Scale              := jsHalf;
          pImagem.Compress;
          Break;
        end;
        I := I + 1;
      except
        On E: Exception do
        begin
            ShowMessage(E.Message+IdHTTP1.ResponseText );
          I := I + 1;
          IdHTTP1.Disconnect;
        end;
      end;
  finally
    if IdHTTP1.ResponseCode = 200 then
      Result := True
    else
      Result := False;

    //Limpa variaveis
    MS.Free;
    IdHTTP1.Disconnect;
    IdHTTP1.Free;
  end;

end;
 

 

Error http/1.1 401 unauthorized

 

And I get headers in my connection :
Connection: close
Content-Length: 0
WWW-Authenticate: Digest realm="Login to 65B90F5B97C45465", qop="auth", 
nonce="44eedea6-bf2d-4d70-870a-14277bf1e02d", opaque=""

 

In the camera material you have this information, but I did not understand how to return it if you receive the 401 error

 

Video products support either basic authentication or digest authentication, see RFC 2617 for detail. If the http request sent by client does not provide valid "Authorization" header information, video products would return HTTP status code 401 and some information for authentication, then client should calculate authentication information according RFC 2617, and sent request again with authentication information using “Authorization” header. Video products return the required resource only if authorization information correct.

For example:

1. When basic authentication fails, response is:

HTTP/1.1 401 Unauthorized WWW-Authenticate: Basic realm="XXXXXX"

The client encodes the username and password with base64, and then sends it to server. A valid Authorization like this:

Authorization: Basic VXZVXZ

2. When digest authentication fails, response is:

HTTP/1.1 401 Unauthorized WWW-Authenticate: Digest realm="DH_00408CA5EA04", nonce="000562fdY631973ef04f77a3ede7c1832ff48720ef95ad", stale=FALSE, qop="auth"

The client calculates the digest authorization using information like username, password, nonce, HTTP method and URI with MD5, and then sends it to server.

For example:

Authorization: Digest username="admin", realm="DH_00408CA5EA04", nc=00000001, cnonce="0a4f113b", qop="auth", nonce="000562fdY631973ef04f77a3ede7c1832ff48720ef95ad", uri="/cgi-bin/magicBox.cgi?action=getLanguageCaps", response="65002de02df697e946b750590b44f8bf"

 

 

 

 

Share this post


Link to post

Your camera supports BASIC and DIGEST authentications.  By default, TIdHTTP enables only BASIC authentication, which you are explicitly disabling by setting the TIdHTTP.Request.BasicAuthorization property to False.

 

You need to either:

  • re-enable BASIC authentication by setting TIdHTTP.Request.BasicAuthorization to True.
  • enable DIGEST authentication by adding the IdAuthenticationDigest, or IdAllAuthentications, unit to your Form's uses clause.
Edited by Remy Lebeau

Share this post


Link to post

Remy,

 

I did it according to your guidance, put true on the authorization and includes the Unit IdAllAuthentications and then tried it with the IdAuthenticationDigest.

And yet when executing get, it returns the http / 1.1 401 unauthorized error

 

    Request.BasicAuthentication := true;

 

in the rest of the code I kept the same, I must still perform some other implementation

Edited by Marcio

Share this post


Link to post
On 3/20/2021 at 5:24 AM, Marcio said:

I did it according to your guidance, put true on the authorization and includes the Unit IdAllAuthentications and then tried it with the IdAuthenticationDigest.

I suggested EITHER approach, not BOTH.  Use either BASIC or DIGEST.

On 3/20/2021 at 5:24 AM, Marcio said:

And yet when executing get, it returns the http / 1.1 401 unauthorized error

Did you verify that TIdHTTP is actually trying to send BASIC/DIGEST authentication in its request?

On 3/20/2021 at 5:24 AM, Marcio said:

in the rest of the code I kept the same, I must still perform some other implementation

I'm guessing either you are not setting the TIdHTTP.Request.Username/Password correctly (are you ABSOLUTELY SURE you are using the correct credentials? Are there any non-ASCII characters present in them?), or the camera is not accepting Indy's flavor of DIGEST authentication (BASIC is very, well, basic and difficult to get wrong).

 

Can you provide an example showing the raw HTTP messages from start to end?

Share this post


Link to post

Remy,

 

I put a log component, and put the result attached, tried all the ways and I was unable to make the connection on the camera.

I collected and collected some parameters of the component events and follows below.

I saw on GIT, that there was an instance of a user about the difficulty of Digest authentication with Idhttp.

If you can help me I will be very grateful for the help

 

https://github.com/IndySockets/Indy/issues/182

 

log eventos.txt

log.txt

Edited by Marcio

Share this post


Link to post

Remy,

 

Remy,

I did the same process with TNetHTTPClient and it worked without errors.

 

procedure TForm2.Teste;
var
  MS: TMemoryStream;
begin
  MS      := TMemoryStream.Create;

  MS.Clear;

  NetHTTPClient1.Get('http://admin:seleta77@192.168.73.45:80/cgi-bin/snapshot.cgi?channel=1',
                     MS);

        MS.Position := 0;
        if ( MS.Size > 0 ) then //and ( IdHTTP1.ResponseCode = 200 ) then
        begin
                MS.SaveToFile('C:\temp\TesteCamera\Teste.jpeg');
        end;
  MS.Free;
end;
 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×