Используя Delphi и TINetHttp, почему я получаю исключение перенаправления TINetHttp с одним URL, а не другим? - PullRequest
1 голос
/ 25 апреля 2020

Пожалуйста, кто-нибудь может объяснить, что происходит в следующей ситуации? Дело в том, что один провайдер перенаправляет 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&amp;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;

1 Ответ

1 голос
/ 25 апреля 2020

Когда POST-запрос возвращает код состояния 307, Win Inet не выполняет автоматическое перенаправление c и вместо этого возвращает ошибку 12168.

Так что, я полагаю, ваш первый провайдер возвращает старый код 302 в то время как другой возвращает 307.

См. здесь для полного списка кодов перенаправления HTTP.

...