I'm using Indy 10.5.7
I've recently been shown how to use Indy to login into a website with valid credentials. Now I can perform searches and return the results I need.
However, I still have a problem. I have to take for granted that I am logged in successfully based on a page redirect as I am unable to get a response code other than 200.
What I mean is, I would like to handle a situation where a user enters a typo in either the username or password, and at least inform them that something is amiss.
For the sake of this question, I have set Indy up as follows ...
var
client : TidHTTP;
cookieMan : TidCookieManager;
params : TStringList;
response : string;
begin
cookieMan := TidCookieManager.Create(nil);
client := TidHTTP.Create(nil);
params := TStringList.Create;
try
with client do
begin
ProtocolVersion := pv1_1;
HTTPOptions := [hoForceEncodeParams, hoKeepOrigProtocol];
AllowCookies := True;
cookieManager := cookieMan;
HandleRedirects := True;
//Request.UserAgent := 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0';
//Request.UserAgent := 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.103 Safari/537.36';
Request.UserAgent := 'Mozilla/5.0 (X11; U; Linux i586; en-US; rv:1.7.3) Gecko/20040924 Epiphany/1.4.4 (Ubuntu)';
//OnRedirect := handleRedirect;
end;
params.Add('username=aFakeUser');
params.Add('password=aFakePass');
try
response := client.Post('http://assurance.redtractor.org.uk/rtassurance/services.eb', params);
mmoResponseCodes.Lines.Add('No exception, INDY OK ' + intToStr(client.ResponseCode)); // << ALWAYS returns 200
// do nothing with params ... just to try to raise any exception
// I need to be logged in to reach the next page, this is a search page ...
response := client.Post('http://assurance.redtractor.org.uk/rtassurance/services/cr_services/checking.eb', params);
mmoResponseCodes.Lines.Add('Still no exception, INDY OK ' + intToStr(client.ResponseCode)); // << ALWAYS returns 200
mmoResponse.Text := response;
except
on e: EIdHTTPProtocolException do
begin
// No exception raised, I expected e.ErrorCode = 401
mmoResponseCodes.Lines.Add('Post Indy Error ' + intToStr(e.ErrorCode) + ' >>> ' + e.Message);
end;
end;
finally
client.Free;
cookieMan.Free;
params.Free;
end;
end;
I really don't know what I am doing wrong. I've seen lots of posts by Remy pointing out to catch exceptions and look at the e.ErrorCode, but I just can't raise an exception with my deliberately fake credentials.
May I ask you point me in the right direction please, and point out what I have done wrong ?
You are using HTML-based authentication (a posted HTML webform), not HTTP-based authentication (the HTTP Authentication
request header).
From an HTTP standpoint, a failed authentication of an HTML webform can still be reported as a successful 200 reply at the HTTP layer. The client requested a URL and the server delivered an HTML page in reply. Whether the HTML claims authentication was successful or failed is irrelevant, HTTP is just a transport, it doesn't care about the particular content being delivered. An HTTP error is only reported if an HTTP-layer error occurs. If HTML authentication fails, the resulting HTML page will usually contain an error message, and/or the login HTML webform again.
So, in this case, you are getting an HTTP 200 reply because HTTP did its job successfully. You will have to analyze the actual HTML being returned to know whether the authentication really succeeded or failed. There is no indication one way or the other at the HTTP layer.