Globalny, bezpieczny wątek, menedżer plików cookie z Indy
Moja aplikacja Delphi 2010 przesyła materiały za pomocą wielowątkowości, przesłane dane POSTed do aplikacji PHP / web, która wymaga logowania, więc muszę użyć współdzielonego / globalnego menedżera plików cookie (używamIndy10 Revision 4743) ponieważ TIdCookieManager nie jest bezpieczny dla wątków :(
Również po stronie serwera identyfikator sesji jest automatycznie generowany co 5 minut, więc jamusi zachowaj synchronizację globalnych i lokalnych menedżerów plików cookie.
Mój kod wygląda tak:
<code>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; </code>
Ale to nie działa! Otrzymuję ten wyjątek podczas wywoływania AddCookies ()
Project MyEXE.exe podniósł klasę wyjątków EAccessViolation z komunikatem „Naruszenie dostępu pod adresem 00000000. Odczyt adresu 00000000”.
Próbowałem też użyć assign (), tj.
<code> TheCookieManager.CookieCollection.Assign(GlobalCookieManager.CookieCollection); </code>
Ale nadal mam ten sam wyjątek, zwykle tutaj:
<code> TIdCookieManager.GenerateClientCookies() </code>
Ktoś wie, jak to naprawić?