|
@@ -119,6 +119,7 @@ Type
|
|
FServerBanner: string;
|
|
FServerBanner: string;
|
|
FLookupHostNames,
|
|
FLookupHostNames,
|
|
FThreaded: Boolean;
|
|
FThreaded: Boolean;
|
|
|
|
+ FConnectionCount : Integer;
|
|
function GetActive: Boolean;
|
|
function GetActive: Boolean;
|
|
procedure SetActive(const AValue: Boolean);
|
|
procedure SetActive(const AValue: Boolean);
|
|
procedure SetOnAllowConnect(const AValue: TConnectQuery);
|
|
procedure SetOnAllowConnect(const AValue: TConnectQuery);
|
|
@@ -126,13 +127,15 @@ Type
|
|
procedure SetQueueSize(const AValue: Word);
|
|
procedure SetQueueSize(const AValue: Word);
|
|
procedure SetThreaded(const AValue: Boolean);
|
|
procedure SetThreaded(const AValue: Boolean);
|
|
procedure SetupSocket;
|
|
procedure SetupSocket;
|
|
- procedure StartServerSocket;
|
|
|
|
|
|
+ procedure WaitForRequests;
|
|
Protected
|
|
Protected
|
|
// Override these to create descendents of the request/response instead.
|
|
// Override these to create descendents of the request/response instead.
|
|
Function CreateRequest : TFPHTTPConnectionRequest; virtual;
|
|
Function CreateRequest : TFPHTTPConnectionRequest; virtual;
|
|
Function CreateResponse(ARequest : TFPHTTPConnectionRequest) : TFPHTTPConnectionResponse; virtual;
|
|
Function CreateResponse(ARequest : TFPHTTPConnectionRequest) : TFPHTTPConnectionResponse; virtual;
|
|
Procedure InitRequest(ARequest : TFPHTTPConnectionRequest); virtual;
|
|
Procedure InitRequest(ARequest : TFPHTTPConnectionRequest); virtual;
|
|
Procedure InitResponse(AResponse : TFPHTTPConnectionResponse); virtual;
|
|
Procedure InitResponse(AResponse : TFPHTTPConnectionResponse); virtual;
|
|
|
|
+ // Called on accept errors
|
|
|
|
+ procedure DoAcceptError(Sender: TObject; ASocket: Longint; E: Exception; var ErrorAction: TAcceptErrorAction);
|
|
// Create a connection handling object.
|
|
// Create a connection handling object.
|
|
function CreateConnection(Data : TSocketStream) : TFPHTTPConnection; virtual;
|
|
function CreateConnection(Data : TSocketStream) : TFPHTTPConnection; virtual;
|
|
// Create a connection handling thread.
|
|
// Create a connection handling thread.
|
|
@@ -143,13 +146,19 @@ Type
|
|
Procedure DoConnect(Sender : TObject; Data : TSocketStream); virtual;
|
|
Procedure DoConnect(Sender : TObject; Data : TSocketStream); virtual;
|
|
// Create and configure TInetServer
|
|
// Create and configure TInetServer
|
|
Procedure CreateServerSocket; virtual;
|
|
Procedure CreateServerSocket; virtual;
|
|
- // Stop and free TInetServer
|
|
|
|
|
|
+ // Start server socket
|
|
|
|
+ procedure StartServerSocket; virtual;
|
|
|
|
+ // Stop server stocket
|
|
|
|
+ procedure StopServerSocket; virtual;
|
|
|
|
+ // free server socket instance
|
|
Procedure FreeServerSocket; virtual;
|
|
Procedure FreeServerSocket; virtual;
|
|
// Handle request. This calls OnRequest. It can be overridden by descendants to provide standard handling.
|
|
// Handle request. This calls OnRequest. It can be overridden by descendants to provide standard handling.
|
|
procedure HandleRequest(Var ARequest: TFPHTTPConnectionRequest;
|
|
procedure HandleRequest(Var ARequest: TFPHTTPConnectionRequest;
|
|
Var AResponse : TFPHTTPConnectionResponse); virtual;
|
|
Var AResponse : TFPHTTPConnectionResponse); virtual;
|
|
// Called when a connection encounters an unexpected error. Will call OnRequestError when set.
|
|
// Called when a connection encounters an unexpected error. Will call OnRequestError when set.
|
|
procedure HandleRequestError(Sender: TObject; E: Exception); virtual;
|
|
procedure HandleRequestError(Sender: TObject; E: Exception); virtual;
|
|
|
|
+ // Connection count
|
|
|
|
+ Property ConnectionCount : Integer Read FConnectionCount;
|
|
public
|
|
public
|
|
Constructor Create(AOwner : TComponent); override;
|
|
Constructor Create(AOwner : TComponent); override;
|
|
Destructor Destroy; override;
|
|
Destructor Destroy; override;
|
|
@@ -542,10 +551,14 @@ constructor TFPHTTPConnection.Create(AServer: TFPCustomHttpServer; ASocket: TSoc
|
|
begin
|
|
begin
|
|
FSocket:=ASocket;
|
|
FSocket:=ASocket;
|
|
FServer:=AServer;
|
|
FServer:=AServer;
|
|
|
|
+ If Assigned(FServer) then
|
|
|
|
+ InterLockedIncrement(FServer.FConnectionCount)
|
|
end;
|
|
end;
|
|
|
|
|
|
destructor TFPHTTPConnection.Destroy;
|
|
destructor TFPHTTPConnection.Destroy;
|
|
begin
|
|
begin
|
|
|
|
+ If Assigned(FServer) then
|
|
|
|
+ InterLockedDecrement(FServer.FConnectionCount);
|
|
FreeAndNil(FSocket);
|
|
FreeAndNil(FSocket);
|
|
Inherited;
|
|
Inherited;
|
|
end;
|
|
end;
|
|
@@ -634,6 +647,15 @@ begin
|
|
end
|
|
end
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+procedure TFPCustomHttpServer.DoAcceptError(Sender: TObject; ASocket: Longint;
|
|
|
|
+ E: Exception; var ErrorAction: TAcceptErrorAction);
|
|
|
|
+begin
|
|
|
|
+ If Not Active then
|
|
|
|
+ ErrorAction:=AEAStop
|
|
|
|
+ else
|
|
|
|
+ ErrorAction:=AEARaise
|
|
|
|
+end;
|
|
|
|
+
|
|
function TFPCustomHttpServer.GetActive: Boolean;
|
|
function TFPCustomHttpServer.GetActive: Boolean;
|
|
begin
|
|
begin
|
|
if (csDesigning in ComponentState) then
|
|
if (csDesigning in ComponentState) then
|
|
@@ -642,6 +664,11 @@ begin
|
|
Result:=Assigned(FServer);
|
|
Result:=Assigned(FServer);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+procedure TFPCustomHttpServer.StopServerSocket;
|
|
|
|
+begin
|
|
|
|
+ FServer.StopAccepting(True);
|
|
|
|
+end;
|
|
|
|
+
|
|
procedure TFPCustomHttpServer.SetActive(const AValue: Boolean);
|
|
procedure TFPCustomHttpServer.SetActive(const AValue: Boolean);
|
|
begin
|
|
begin
|
|
If AValue=GetActive then exit;
|
|
If AValue=GetActive then exit;
|
|
@@ -652,9 +679,10 @@ begin
|
|
CreateServerSocket;
|
|
CreateServerSocket;
|
|
SetupSocket;
|
|
SetupSocket;
|
|
StartServerSocket;
|
|
StartServerSocket;
|
|
|
|
+ FreeServerSocket;
|
|
end
|
|
end
|
|
else
|
|
else
|
|
- FreeServerSocket;
|
|
|
|
|
|
+ StopServerSocket;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TFPCustomHttpServer.SetOnAllowConnect(const AValue: TConnectQuery);
|
|
procedure TFPCustomHttpServer.SetOnAllowConnect(const AValue: TConnectQuery);
|
|
@@ -758,6 +786,7 @@ begin
|
|
FServer.MaxConnections:=-1;
|
|
FServer.MaxConnections:=-1;
|
|
FServer.OnConnectQuery:=OnAllowConnect;
|
|
FServer.OnConnectQuery:=OnAllowConnect;
|
|
FServer.OnConnect:=@DOConnect;
|
|
FServer.OnConnect:=@DOConnect;
|
|
|
|
+ FServer.OnAcceptError:=@DoAcceptError;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TFPCustomHttpServer.StartServerSocket;
|
|
procedure TFPCustomHttpServer.StartServerSocket;
|
|
@@ -769,7 +798,6 @@ end;
|
|
|
|
|
|
procedure TFPCustomHttpServer.FreeServerSocket;
|
|
procedure TFPCustomHttpServer.FreeServerSocket;
|
|
begin
|
|
begin
|
|
- FServer.StopAccepting;
|
|
|
|
FreeAndNil(FServer);
|
|
FreeAndNil(FServer);
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -788,9 +816,29 @@ begin
|
|
FServerBanner := 'Freepascal';
|
|
FServerBanner := 'Freepascal';
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+Procedure TFPCustomHttpServer.WaitForRequests;
|
|
|
|
+
|
|
|
|
+Var
|
|
|
|
+ FLastCount,ACount : Integer;
|
|
|
|
+
|
|
|
|
+begin
|
|
|
|
+ ACount:=0;
|
|
|
|
+ FLastCount:=FConnectionCount;
|
|
|
|
+ While (FConnectionCount>0) and (ACount<10) do
|
|
|
|
+ begin
|
|
|
|
+ Sleep(100);
|
|
|
|
+ if (FConnectionCount=FLastCount) then
|
|
|
|
+ Dec(ACount)
|
|
|
|
+ else
|
|
|
|
+ FLastCount:=FConnectionCount;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
destructor TFPCustomHttpServer.Destroy;
|
|
destructor TFPCustomHttpServer.Destroy;
|
|
begin
|
|
begin
|
|
Active:=False;
|
|
Active:=False;
|
|
|
|
+ if Threaded and (FConnectionCount>0) then
|
|
|
|
+ WaitForRequests;
|
|
inherited Destroy;
|
|
inherited Destroy;
|
|
end;
|
|
end;
|
|
|
|
|