带有Indy的全局线程安全cookie管理器

带有Indy的全局线程安全cookie管理器

本文介绍了带有Indy的全局线程安全cookie管理器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

My Delphi 2010 app uploads stuff using multi-threading, uploaded data is POSTed to a PHP/web application which requires login, so I need to use a shared/global cookies manager (I'm using Indy10 Revision 4743) since TIdCookieManager is not thread-safe :(

此外,服务器端,会话ID每5分钟自动生成一次,所以我必须使全局和本地Cookie管理器保持同步。

Also, server side, session id is automatically re-generated every 5 minutes, so I must keep both the global & local cookie managers in sync.

我的代码如下:

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()

But it doesn't work! I'm getting this exception when calling AddCookies()

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

I also tried using assign(), ie.

 TheCookieManager.CookieCollection.Assign(GlobalCookieManager.CookieCollection);

但我仍然遇到相同的例外,通常在这里:

But I still get the same exception, usually here:

 TIdCookieManager.GenerateClientCookies()

任何人都知道

推荐答案

响应评论:

如果您的错误是读取地址00000000 时发生访问冲突,这有一个非常具体的含义。这意味着您正在尝试使用 nil 的对象进行操作。

If your error is an Access Violation with Read of address 00000000, that's got a very specific meaning. It means you're trying to do something with an object that's nil.

当您获得该功能时,请转到调试器。如果错误发生在您所说的错误发生上,那么几乎可以肯定 Self FRWLock 是此时。检查两个变量,找出尚未构造的变量,然后将您引向解决方案。

When you get that, break to the debugger. If the error's taking place on the line you said it's happening on, then it's almost certain that either Self or FRWLock is nil at this point. Check both variables and figure out which one hasn't been constructed yet, and that'll point you to the solution.

这篇关于带有Indy的全局线程安全cookie管理器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 14:49