Search code examples
delphiindy10idhttp

Is TIdHTTP threadsafe?


I'm using TIdHTTP in my class to handle web APIs (TWebAPI). Since it might happen that this class is used in a TIdHTTPServer.OnCommandGet event handler, I need to make sure that TWebAPIis thread safe.

Do I need to wrap a PUT/GET/POST inside a TMultiReadExclusiveWriteSynchronizer?

EDIT: Code-Sample

TWebAPI

TWebAPI=class(TObject)
 FSocket:TidHTTP;
end;

procedure TWebAPI.Send;
Var
 Response:TSTringStream;
begin
 FSocket.Get(fURL,Response);
end;

Main Program

TMain=class(TForm)
 Server:TidHTTPServer;
 WebAPI:TWebAPI;
end;

procedure TMain.ServerCommandGet(....)
begin
 WebAPI.Send;
end;

So my WebAPI would be used in different threads on each command the server gets. SHould I use the CriticalSection in TMain, or implement it in TWebAPI like this?

TWebAPI=class(TObject)
 FSocket:TidHTTP;
 FLock:TCriticalSection;
end;

procedure TWebAPI.Send;
Var
 Response:TSTringStream;
begin
 FLock.Aquire;
 try
   FSocket.Get(fURL,Response);
 finally
   FLock.Release;
 end;
end;

Solution

  • A single TIdHTTP could be protected by a TCriticalSection or TMonitor. There is no R/W involved, so don't use TMultiReadExclusiveWriteSynchronizer - just a mutex/lock. But if you use a single TIdHTTP you will need a mutex/lock, so all HTTP calls will be serialized, which may be not a good idea on a multi-threaded server.

    I would maintain one connection per thread, or write a connection pool. Perhaps just a given TIdHTTP each time may not be too bad. At least it will be safe and there will be room for improvement later on. Reopening a TCP/HTTP connection is quick in practice.