2010-02-14 31 views
5

Ok, tengo Idhttp crea de forma dinámica como la siguienteDelphi - Indy (IDHTTP) Mantener sesión


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; 

Tengo un sitio web que me obliga a mantener una sesión activa. ¿Cómo haría esto? Con un código similar al anterior.

Si creo un componente visual para todo, y lo uso todo es genial, pero cuando creo dinámicamente el componente (que REALMENTE deseo dejarlo de esta manera) no logra mantener viva la sesión.

Cualquier ayuda es apreciada.

Respuesta

5

No veo dónde crea una instancia CookieManager, pero ahí es donde debe realizar un seguimiento de la sesión. El servidor enviará algunas cookies que representan la sesión actual, y todas las demás solicitudes que envíe al servidor deberían incluir esa cookie para que el servidor sepa qué sesión usar.

Deberá mantener el objeto del administrador de cookies durante la sesión, o deberá guardar sus datos en otro lugar y luego volver a cargarlos cada vez que cree un nuevo administrador de cookies objeto. Prefiero el primero. De hecho, puede considerar mantener todo el objeto HTTP.

+0

que se olvidó de copiar el código para que .. Había intentado poner el administrador de cookies en el evento OnCreate, y luego dejar que todo (no nil'ing) pero que no parecía trabajo. En cuanto a mantener el objeto HTTP, eso era algo que realmente no quería hacer, pero podría hacerlo, supongo. Veré qué hace cuando guardo el objeto http. Realmente no quería hacer eso (sin un razonamiento particular) ... – Brad

1

Como Rob dijo que su TIdCookieManager es clave para mantener una sesión basada en cookies. El TIdCookieManager se podría crear en un evento de creación de módulo de datos o en el evento OnCreate() de formas principales y luego establecerlo cada vez que se crea un componente IdHTTP.

+0

Intentaré que OnCreate nuevamente, lo tenía como OnCreate en el formulario. (Por cierto, gracias por el código anterior, funcionó maravillosamente hasta que tuve que lidiar con este sitio y mantener una sesión.) – Brad

+0

¡No hay problema, me alegro de ser de ayuda! - ¿Has buscado usar hilos para las partes de comunicación? ¿Podría hacer un viaje más suave si se puede implementar en su código? –

+0

Sí, he estado viendo una demostración con subprocesos, pero el subproceso está por encima de mi nivel de conocimiento actual en Delphi.Y mucho de lo que hace este proyecto es contactar el mismo sitio web una y otra vez, por lo que no necesito/quiero solicitudes múltiples para este. Pero utilizo el mismo código base en otros proyectos, y sería bueno enhebrarlos. ¿Tiene alguna sugerencia sobre una buena demo de hilo? – Brad

2

Como mencionó en sus comentarios, está creando CookieManager en el controlador de eventos OnCreate, de modo que cuando se llame TForm1.webSession, CookieManager esté disponible, pero en el bloque finally de TForm1.webSession está liberando CookieManager, por lo que una vez dejas el método TForm1.webSession, CookieManager se queda sin memoria. Entonces, la próxima vez que se llame TForm1.webSession, CookieManager es Nil, y no se guarda ninguna cookie para usted.

Hay otras dos notas que no están relacionados con su pregunta, pero están relacionados con su código fuente:

1- Su método se vuelve AnsiString, pero se están utilizando Utf8ToWideString para asignar un valor a la variable de resultado. Utf8ToWideString devuelve WideString, por lo que el compilador debe convertir WideString en AnsiString, y no solo esto reduce el rendimiento, sino que también pierde los caracteres unicode en la cadena de retorno. Debe cambiar la firma de su método para devolver String (D2009 & D2010) o WideString (versiones anteriores de Delphi).

2- No necesita comprobar si se asignan SStream, AntiFreeze o HTTPCon en el bloque finally. Simplemente puede llamar al método Free o usar el procedimiento FreeAndNil.

Saludos

+0

Gracias por la información sobre el AnsiString, editaré el código de trabajo para solucionarlo. En el código que tenía el CookieManager en el evento OnCretae no tenía el código freeandnil en esa versión. – Brad

Cuestiones relacionadas