Marcio 2 Posted March 19, 2021 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
Remy Lebeau 1394 Posted March 20, 2021 (edited) 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 March 20, 2021 by Remy Lebeau Share this post Link to post
Marcio 2 Posted March 20, 2021 (edited) 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 March 20, 2021 by Marcio Share this post Link to post
Remy Lebeau 1394 Posted March 22, 2021 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
Marcio 2 Posted March 27, 2021 (edited) 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 March 27, 2021 by Marcio Share this post Link to post
Marcio 2 Posted March 27, 2021 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