Пожалуйста, кто-нибудь может объяснить, что происходит в следующей ситуации? Дело в том, что один провайдер перенаправляет URL-адрес, а другой - нет или происходит что-то другое?
Я использую Delphi TINetHttp (обертку вокруг Win Inet) для входа на cpanel на ISP и восстановить код сеанса. Я использую метод обратного вызова TINetHttp, чтобы получить перенаправленный URL-адрес, из которого я могу извлечь код сеанса. С одним провайдером код работает правильно, но с другим обратный вызов выдает исключение Error 12168 - The HTTP redirect request must be confirmed by the user
, а glboal var NewURL устанавливается в пустую строку
Предполагается, что URL для входа в систему равен https://MyServer.net:2083/login/?user=username&pass=password
и установлен флаг INetHttp flNoAutoRedirect в FALSE, так что перенаправления разрешены. Затем следующее получит код сеанса от одного провайдера
var
NewURL : string;
url:= 'https://MyServer.net:2083/login/?user=username&pass=password'
RunWebPageCode(url, true); //navigate to the logon page, INetHttp callback sets NewURL to the redirected url
SessionID := ExtractBetween(NewURL , '/cpsess', '/frontend'); //get the session code from the redirected url
Здесь вызывается обратный вызов INetHttp и задается глобальный var NewURL для перенаправленного URL (что-то вроде https://MyServer.net:2083/cpsess1111633888/frontend/x3/index.html?login=1&post_login=9962390421682
) из которого я извлекаю код сеанса от /cpsess
до /frontend
.
С другим провайдером, с почти идентичным (и правильным) URL, отличающимся только именем домена, и флагом INetHttp1 flNoAutoRedirect, установленным в значение FALSE, обратный вызов INetHttp генерирует исключение 12168, а NewURL устанавливается в пустое string.
Однако, если у обоих ISP установлен флаг flNoAutoRedirect, установленный в значение TRUE, поэтому обратный вызов INetHttp не вызывается, я могу вместо этого извлечь идентификатор сеанса из html пустой страницы, которую я получаю на котором будет выглядеть что-то вроде
<html><head><META HTTP-EQUIV="refresh"CONTENT="2;URL=/cpsess1796422993/frontend/paper_lantern/index.html login=1&post_login=99510958918744"></head><body></body></html>
, поэтому следующий код работает для обоих ISP (если флаг flNoAutoRedirect установлен в TRUE)
url:= 'https://MyServer.net:2083/login/?user=username&pass=password'
RunWebPageCode(url, true); //navigate to the logon page
page := GetWebPageText(url, true); /get the html of the landing page
SessionID := ExtractBetween(page, '/cpsess', '/frontend');
Полный код ниже приведены различные функции на случай, если это поможет.
var
NewURL : string;
procedure Tjhm.RunWebPageCode(TheURL: string; secure: Boolean);
begin
try
try
if secure then
INetHttp1.Flags := INetHttp1.Flags + [flSecure]
else
INetHttp1.Flags := INetHttp1.Flags - [flSecure];
INetHttp1.Verb := vePost;
INetHttp1.Url := TheURL ;
INetHttp1.Open;
INetHttp1.OpenRequest;
INetHttp1.SendRequest;
except
on E : Exception do
begin
showmessage ('error running web page code +slinebreak
+ 'Exception class name = '+E.ClassName+ slinebreak
+ 'Exception message = '+E.Message);
end //on E
end;
finally
INetHttp1.Close;
end;
end;
procedure Tjhm.INetHttp1Callback(Sender: TObject; Status: Integer; Information: Pointer; InformationLength: Integer);
const
INTERNET_STATUS_REDIRECT = 110; //a constant in WinInet but redefined here for clarity
begin
if Status = INTERNET_STATUS_REDIRECT then //we have been redirected
begin
newURL := PAnsiChar(Information); // put new url into global var, typecast as 'Information' is a pointer to a non unicode char string
end;
end;
function Tjhm.ExtractBetween(const Value, A, B: string): string;
{utility to get the text between two delimiters}
var
aPos, bPos: Integer;
begin
result := '';
aPos := Pos(A, Value);
if aPos > 0 then begin
aPos := aPos + Length(A);
bPos := PosEx(B, Value, aPos);
if bPos > 0 then begin
result := Copy(Value, aPos, bPos - aPos);
end;
end;
end;