gpt4 book ai didi

multithreading - Indy 的全局、线程安全、cookie 管理器

转载 作者:行者123 更新时间:2023-12-02 00:35:46 25 4
gpt4 key购买 nike

我的 Delphi 2010 应用程序使用多线程上传内容,上传的数据被发布到需要登录的 PHP/Web 应用程序,因此我需要使用共享/全局 cookie 管理器(我正在使用 Indy10 修订版 4743 ) 因为 TIdCookieManager 不是线程安全的:(

此外,服务器端 session ID 每 5 分钟自动重新生成一次,因此我必须保持全局和本地 cookie 管理器同步。

我的代码如下所示:

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;

但是这不起作用!我在调用 AddCookies() 时遇到此异常

Project MyEXE.exe raised exception class EAccessViolation with message 'Access violation at address 00000000. Read of address 00000000'.

我也尝试过使用 allocate(),即。

 TheCookieManager.CookieCollection.Assign(GlobalCookieManager.CookieCollection);

但我仍然遇到同样的异常,通常在这里:

 TIdCookieManager.GenerateClientCookies()

有人知道如何解决这个问题吗?

最佳答案

不要对 OnNewCookie 事件使用匿名过程。使用普通的类方法代替:

procedure TUploadThread.NewCookie(ASender: TObject; ACookie : TIdCookie; var VAccept : Boolean);
var
LCookie: TIdCookie;
begin
LCookie := TIdCookieClass(ACookie.ClassType).Create;
LCookie.Assign(ACookie);
OmniLock.Acquire;
try
GlobalCookieManager.CookieCollection.AddCookie(LCookie, TIdHTTP(TIdCookieManager(ASender).Owner).URL);
finally
OmniLock.Release;
end;
VAccept := True;
end;

或者:

procedure TUploadThread.NewCookie(ASender: TObject; ACookie : TIdCookie; var VAccept : Boolean);
begin
OmniLock.Acquire;
try
GlobalCookieManager.CookieCollection.AddServerCookie(ACookie.ServerCookie, TIdHTTP(TIdCookieManager(ASender).Owner).URL);
finally
OmniLock.Release;
end;
VAccept := True;
end;

然后像这样使用它:

procedure TUploadThread.Upload(FileName : String); 
var
IdHTTP : TIdHTTP;
TheSSL : TIdSSLIOHandlerSocketOpenSSL;
TheCompressor : TIdCompressorZLib;
TheCookieManager : TIdCookieManager;
TheStream : TIdMultipartFormDataStream;
begin
IdHTTP := TIdHTTP.Create(nil);
try
...
TheCookieManager := TIdCookieManager.Create(IdHTTP);
TheCookieManager.OnNewCookie := NewCookie;

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;

TheStream := TIdMultipartFormDataStream.Create;
try
with TheStream.AddFile('file_name', FileName, 'application/octet-stream') do
begin
HeaderCharset := 'utf-8';
HeaderEncoding := '8';
end;

IdHTTP.Post('https://www.domain.com/post.php', TheStream);
finally
TheStream.Free;
end;
finally
IdHTTP.Free;
end;
end;

关于multithreading - Indy 的全局、线程安全、cookie 管理器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10439511/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com