5 votes

Delphi - Indy (IDHTTP) Garder la session

Ok, j'ai un Idhttp créé dynamiquement comme ceci

procedure TForm1.Button1Click(Sender: TObject);
Var
   Resp : String;
begin
     Resp := webSession('https://www.website.com'); // HTTPS site requires session to keep alive
     if Length(Resp)>0 then
        MessageDlg('Got the body ok',mtInformation,[mbOk],0);
end;

function TForm1.webSession(sURL : ansistring) : ansistring;
var
   SStream    : Tstringstream;
   HTTPCon    : TIdHTTP;
   AntiFreeze : TIdAntiFreeze;
   CompressorZLib: TIdCompressorZLib;
   ConnectionIntercept: TIdConnectionIntercept;
   SSLIOHandlerSocketOpenSSL: TIdSSLIOHandlerSocketOpenSSL;
   CookieManager: TIdCookieManager;
begin
    CompressorZLib :=  TIdCompressorZLib.Create;
    ConnectionIntercept :=TIdConnectionIntercept.Create;
    SSLIOHandlerSocketOpenSSL :=  TIdSSLIOHandlerSocketOpenSSL.Create;
     Result := '';
     if Length(SettingsForm.edtProxyServer.text) >= 7 then  // 0.0.0.0
     Try
        SStream := NIL;
        AntiFreeze := NIL;
        HTTPCon := NIL;
        Try
           SStream := tstringstream.Create('');
           { Create & Set IdHTTP properties }
           HTTPCon := TIdHTTP.create;
           HTTPCon.AllowCookies:=true;
           HTTPCon.CookieManager :=CookieManager;
           HTTPCon.Compressor := CompressorZLib;
           HTTPCon.Intercept := ConnectionIntercept;
           HTTPCon.IOHandler := SSLIOHandlerSocketOpenSSL;
           HTTPCon.HandleRedirects := true;
           { Check Proxy }
           if checkproxy('http://www.google.com') then
           Begin
                HTTPCon.ProxyParams.ProxyServer := SettingsForm.edtProxyServer.text;
                HTTPCon.ProxyParams.ProxyPort := StrToInt(SettingsForm.edtProxyPort.Text);
                HTTPCon.ProxyParams.BasicAuthentication := True;
                HTTPCon.ProxyParams.ProxyUsername := SettingsForm.edtProxyServer.Text;
                HTTPCon.ProxyParams.ProxyPassword := SettingsForm.edtProxyUserName.Text;
           End;
           { Create another AntiFreeze - only 1/app }
           AntiFreeze := TIdAntiFreeze.Create(nil);
           AntiFreeze.Active := true;
           HTTPCon.Get(sURL,SStream);
           Result := UTF8ToWideString(SStream.DataString);
        Finally
           If Assigned(HTTPCon) then FreeAndNil(HTTPCon);
           If Assigned(AntiFreeze) then FreeAndNil(AntiFreeze);
           If Assigned(SStream) then FreeAndNil(SStream);
           If Assigned(CookieManager) then FreeAndNil (CookieManager );
           If Assigned(CompressorZLib) then FreeAndNil (CompressorZLib );
           If Assigned(ConnectionIntercept) then FreeAndNil (ConnectionIntercept );
           If Assigned(SSLIOHandlerSocketOpenSSL) then FreeAndNil (SSLIOHandlerSocketOpenSSL);

        End;
     Except
        { Handle exceptions }
        On E:Exception do
           MessageDlg('Exception: '+E.Message,mtError, [mbOK], 0);
     End;
end;

function TForm1.checkproxy(sURL : ansistring) : boolean;
var
   HTTPCon : TIdHTTP;
   AntiFreeze : TIdAntiFreeze;
begin
     Result := False;
     Try
        { Inti vars }
        AntiFreeze := NIL;
        HTTPCon := NIL;
        Try
           { AntiFreeze }
           AntiFreeze := TIdAntiFreeze.Create(NIL);
           AntiFreeze.Active := true;
           { Create & Set IdHTTP properties }
           HTTPCon := TIdHTTP.Create(NIL);
           HTTPCon.ProxyParams.ProxyServer := SettingsForm.edtProxyServer.text;
           HTTPCon.ProxyParams.ProxyPort := StrToInt(SettingsForm.edtProxyPort.Text);
           HTTPCon.ProxyParams.BasicAuthentication := True;
           HTTPCon.ProxyParams.ProxyUsername := SettingsForm.edtProxyServer.Text;
           HTTPCon.ProxyParams.ProxyPassword := SettingsForm.edtProxyUserName.Text;
           HTTPCon.HandleRedirects := true;
           HTTPCon.ConnectTimeout := 1000;
           HTTPCon.Request.Connection := 'close';
           HTTPCon.Head(sURL);
        Finally
           { Cleanup }
           if Assigned(HTTPCon) then
           Begin
                { Return Success/Failure }
                Result := HTTPCon.ResponseCode = 200;
                If HTTPCon.Connected then HTTPCon.Disconnect;
                FreeAndNil(HTTPCon);
           End;
           if Assigned(AntiFreeze) then FreeAndNil(AntiFreeze);
        End;
     Except
        On E:EIdException do ;
        { Handle exceptions }
        On E:Exception do
           MessageDlg('Exception: '+E.Message,mtError, [mbOK], 0);
     End;
end;

J'ai un site web qui me demande de garder une session en vie. Comment dois-je m'y prendre ? Avec un code similaire au précédent.

Si je crée un composant visuel pour tout, et que je l'utilise, tout va bien, mais lorsque je crée dynamiquement le composant (ce que je veux VRAIMENT faire), il ne parvient pas à maintenir la session en vie.

Toute aide est appréciée.

5voto

Rob Kennedy Points 107381

Je ne vois pas où tu instancies CookieManager mais c'est là que vous devez garder la trace de la session. Le serveur enverra un cookie qui représente la session en cours, et toutes les autres demandes que vous enverrez au serveur devront inclure ce cookie afin que le serveur sache quelle session utiliser.

Vous devrez soit conserver l'objet cookie-manager pendant toute la durée de la session, soit enregistrer ses données ailleurs et les recharger à chaque fois que vous créez un nouvel objet cookie-manager. Je préfère la première solution. En fait, vous pourriez envisager de conserver l'objet HTTP dans son intégralité.

2voto

vcldeveloper Points 5570

Comme vous l'avez mentionné dans vos commentaires, vous créez CookieManager dans l'event-handler OnCreate, de sorte que lorsque TForm1.webSession est appelé, CookieManager est disponible, mais dans le bloc finally de TForm1.webSession vous libérez CookieManager, de sorte que dès que vous quittez la méthode TForm1.webSession, CookieManager n'est plus en mémoire. Ainsi, la prochaine fois que TForm1.webSession est appelée, CookieManager est Nil, et aucun cookie n'est enregistré pour vous.

Il y a deux autres notes qui ne sont pas liées à votre question, mais qui sont liées à votre code source :

1- Votre méthode retourne AnsiString, mais vous utilisez Utf8ToWideString pour assigner une valeur à la variable Result. Utf8ToWideString retourne WideString, donc le compilateur doit convertir WideString en AnsiString, et non seulement cela réduit la performance, mais aussi il perd les caractères unicode dans la chaîne de retour. Vous devez modifier la signature de votre méthode pour qu'elle renvoie soit String (D2009 & D2010) soit WideString (anciennes versions de Delphi).

2- Vous n'avez pas besoin de vérifier si SStream, AntiFreeze, ou HTTPCon sont assignés dans le bloc final. Vous pouvez simplement appeler la méthode Free, ou utiliser la procédure FreeAndNil.

Salutations

1voto

K.Sandell Points 1109

Comme Rob l'a dit, votre TIdCookieManager est essentiel pour maintenir une session basée sur les cookies. Le TIdCookieManager pourrait être créé dans l'événement create d'un datamodule ou dans l'événement OnCreate() de la mainforms, puis défini chaque fois que vous créez un composant IdHTTP.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X