Global, thread safe, gerenciador de cookies com Indy
Meu aplicativo Delphi 2010 carrega coisas usando multi-threading, os dados enviados são POSTados para um aplicativo PHP / web que requer login, então eu preciso usar um gerenciador de cookies compartilhados / globais (estou usandoRevisão Indy10 4743) desde TIdCookieManager não é thread-safe :(
Além disso, no lado do servidor, o id da sessão é automaticamente gerado a cada 5 minutos, então eudevo Mantenha os gerenciadores de cookies globais e locais em sincronia.
Meu código é assim:
TUploadThread = class(TThread)
// ...
var
GlobalCookieManager : TIdCookieManager;
procedure TUploadThread.Upload(FileName : String);
var
IdHTTP : TIdHTTP;
TheSSL : TIdSSLIOHandlerSocketOpenSSL;
TheCompressor : TIdCompressorZLib;
TheCookieManager : TIdCookieManager;
AStream : TIdMultipartFormDataStream;
begin
ACookieManager := TIdCookieManager.Create(IdHTTP);
// Automatically sync cookies between local & global Cookie managers
@TheCookieManager.OnNewCookie := pPointer(Cardinal(pPointer( procedure(ASender : TObject; ACookie : TIdCookie; var VAccept : Boolean)
begin
OmniLock.Acquire;
try
GlobalCookieManager.CookieCollection.AddCookie(ACookie, TIdHTTP(TIdCookieManager(ASender).Owner).URL{IdHTTP.URL});
finally
OmniLock.Release;
end; // try/finally
VAccept := True;
end )^ ) + $0C)^;
// ======================================== //
IdHTTP := TIdHTTP.Create(nil);
with IdHTTP do
begin
HTTPOptions := [hoForceEncodeParams, hoNoParseMetaHTTPEquiv];
AllowCookies := True;
HandleRedirects := True;
ProtocolVersion := pv1_1;
IOHandler := TheSSL;
Compressor := TheCompressor;
CookieManager := TheCookieManager;
end; // with
OmniLock.Acquire;
try
// Load login info/cookies
TheCookieManager.CookieCollection.AddCookies(GlobalCookieManager.CookieCollection);
finally
OmniLock.Release;
end; // try/finally
AStream := TIdMultipartFormDataStream.Create;
with Stream.AddFile('file_name', FileName, 'application/octet-stream') do
begin
HeaderCharset := 'utf-8';
HeaderEncoding := '8';
end; // with
IdHTTP.Post('https://www.domain.com/post.php', AStream);
AStream.Free;
end;
Mas isso não funciona! Estou recebendo essa exceção ao chamar AddCookies ()
O projeto MyEXE.exe levantou a classe de exceção EAccessViolation com a mensagem 'Violação de acesso no endereço 00000000. Leitura do endereço 00000000'.
Eu também tentei usar assign (), ie.
TheCookieManager.CookieCollection.Assign(GlobalCookieManager.CookieCollection);
Mas eu ainda recebo a mesma exceção, geralmente aqui:
TIdCookieManager.GenerateClientCookies()
Alguém sabe como consertar isso?