|
@@ -63,9 +63,12 @@ Type
|
|
TFPHTTPConnection = Class(TObject)
|
|
TFPHTTPConnection = Class(TObject)
|
|
private
|
|
private
|
|
Class var _ConnectionCount : {$IFDEF CPU64}QWord{$ELSE}Cardinal{$ENDIF};
|
|
Class var _ConnectionCount : {$IFDEF CPU64}QWord{$ELSE}Cardinal{$ENDIF};
|
|
|
|
+ procedure ParseStartLine(Request: TFPHTTPConnectionRequest;
|
|
|
|
+ AStartLine: String);
|
|
private
|
|
private
|
|
FBusy: Boolean;
|
|
FBusy: Boolean;
|
|
FConnectionID: String;
|
|
FConnectionID: String;
|
|
|
|
+ FEmptyDetected: Boolean;
|
|
FIsUpgraded: Boolean;
|
|
FIsUpgraded: Boolean;
|
|
FOnRequestError: TRequestErrorHandler;
|
|
FOnRequestError: TRequestErrorHandler;
|
|
FOnUnexpectedError: TRequestErrorHandler;
|
|
FOnUnexpectedError: TRequestErrorHandler;
|
|
@@ -107,6 +110,8 @@ Type
|
|
Function RequestPending : Boolean;
|
|
Function RequestPending : Boolean;
|
|
// True if we're handling a request. Needed to be able to schedule properly.
|
|
// True if we're handling a request. Needed to be able to schedule properly.
|
|
Property Busy : Boolean Read FBusy;
|
|
Property Busy : Boolean Read FBusy;
|
|
|
|
+ // If empty detected, we should not proceed
|
|
|
|
+ Property EmptyDetected : Boolean Read FEmptyDetected;
|
|
// The server supports HTTP 1.1 connection: keep-alive
|
|
// The server supports HTTP 1.1 connection: keep-alive
|
|
Property KeepConnections : Boolean read GetKeepConnections;
|
|
Property KeepConnections : Boolean read GetKeepConnections;
|
|
// Idle time-out for keep-alive: after how many ms should the connection fire the OnKeepConnectionIdle event
|
|
// Idle time-out for keep-alive: after how many ms should the connection fire the OnKeepConnectionIdle event
|
|
@@ -296,6 +301,10 @@ Type
|
|
{ TConnectionList }
|
|
{ TConnectionList }
|
|
|
|
|
|
|
|
|
|
|
|
+ THTTPLogEvent = Procedure (aSender : TObject; aType: TEventType; Const Msg : String) of object;
|
|
|
|
+ // Events in the lifetime of a request that are logged
|
|
|
|
+ THTTPLogMoment = (hlmStartSocket,hlmCloseSocket,hlmConnect,hlmNoHTTPProtocol, hlmEmptyRequest, hlmRequestStart,hlmHeaders,hlmRequestDone,hlmUpgrade,hlmDisconnect,hlmError);
|
|
|
|
+ THTTPLogMoments = set of THTTPLogMoment;
|
|
|
|
|
|
TFPCustomHttpServer = Class(TComponent)
|
|
TFPCustomHttpServer = Class(TComponent)
|
|
Private
|
|
Private
|
|
@@ -307,10 +316,12 @@ Type
|
|
FKeepConnections: Boolean;
|
|
FKeepConnections: Boolean;
|
|
FKeepConnectionIdleTimeout: Integer;
|
|
FKeepConnectionIdleTimeout: Integer;
|
|
FKeepConnectionTimeout: Integer;
|
|
FKeepConnectionTimeout: Integer;
|
|
|
|
+ FLogMoments: THTTPLogMoments;
|
|
FOnAcceptIdle: TNotifyEvent;
|
|
FOnAcceptIdle: TNotifyEvent;
|
|
FOnKeepConnectionIdle: TNotifyEvent;
|
|
FOnKeepConnectionIdle: TNotifyEvent;
|
|
FOnAllowConnect: TConnectQuery;
|
|
FOnAllowConnect: TConnectQuery;
|
|
FOnGetSocketHandler: TGetSocketHandlerEvent;
|
|
FOnGetSocketHandler: TGetSocketHandlerEvent;
|
|
|
|
+ FOnLog: THTTPLogEvent;
|
|
FOnRequest: THTTPServerRequestHandler;
|
|
FOnRequest: THTTPServerRequestHandler;
|
|
FOnRequestError: TRequestErrorHandler;
|
|
FOnRequestError: TRequestErrorHandler;
|
|
FOnUnexpectedError: TRequestErrorHandler;
|
|
FOnUnexpectedError: TRequestErrorHandler;
|
|
@@ -346,6 +357,11 @@ Type
|
|
procedure SetupSocket;
|
|
procedure SetupSocket;
|
|
procedure SetupConnectionHandler;
|
|
procedure SetupConnectionHandler;
|
|
Protected
|
|
Protected
|
|
|
|
+ // Should given event type be logged ?
|
|
|
|
+ function CanLog(aMoment: THTTPLogMoment): Boolean; inline;
|
|
|
|
+ Procedure DoLog(aType : TEventType; const Msg : String); overload;
|
|
|
|
+ procedure DoLog(aMoment: THTTPLogMoment; const Msg: String); overload;
|
|
|
|
+ Procedure DoLog(aMoment : THTTPLogMoment; const Fmt : String; Const Args : Array of const); overload;
|
|
Function CheckUpgrade(aConnection : TFPHTTPConnection; aRequest : TFPHTTPConnectionRequest) : Boolean;
|
|
Function CheckUpgrade(aConnection : TFPHTTPConnection; aRequest : TFPHTTPConnectionRequest) : Boolean;
|
|
// Override this to create Descendent
|
|
// Override this to create Descendent
|
|
Function CreateUpgradeHandlerList : TUpgradeHandlerList;
|
|
Function CreateUpgradeHandlerList : TUpgradeHandlerList;
|
|
@@ -397,7 +413,15 @@ Type
|
|
Property UpdateHandlers : TUpgradeHandlerList Read GetUpdateHandlers;
|
|
Property UpdateHandlers : TUpgradeHandlerList Read GetUpdateHandlers;
|
|
// Has update handlers
|
|
// Has update handlers
|
|
Property HasUpdateHandlers : Boolean Read GetHasUpdateHandlers;
|
|
Property HasUpdateHandlers : Boolean Read GetHasUpdateHandlers;
|
|
|
|
+ Public
|
|
|
|
+ Type
|
|
|
|
+ TLogMomentEventTypes = Array [THTTPLogMoment] of TEventType;
|
|
|
|
+ Class var
|
|
|
|
+ // How to report certain events
|
|
|
|
+ LogMomentEventTypes : TLogMomentEventTypes;
|
|
|
|
+
|
|
public
|
|
public
|
|
|
|
+ class constructor init;
|
|
Constructor Create(AOwner : TComponent); override;
|
|
Constructor Create(AOwner : TComponent); override;
|
|
Destructor Destroy; override;
|
|
Destructor Destroy; override;
|
|
Function RegisterUpdateHandler(Const aName : string; OnCheck : THandlesUpgradeEvent; OnUpgrade : TUpgradeConnectionEvent) : TUpgradeHandlerItem;
|
|
Function RegisterUpdateHandler(Const aName : string; OnCheck : THandlesUpgradeEvent; OnUpgrade : TUpgradeConnectionEvent) : TUpgradeHandlerItem;
|
|
@@ -448,10 +472,14 @@ Type
|
|
Property CertificateData : TCertificateData Read FCertificateData Write SetCertificateData;
|
|
Property CertificateData : TCertificateData Read FCertificateData Write SetCertificateData;
|
|
// Set to true if you want to use SSL
|
|
// Set to true if you want to use SSL
|
|
Property UseSSL : Boolean Read FUseSSL Write FUseSSL;
|
|
Property UseSSL : Boolean Read FUseSSL Write FUseSSL;
|
|
|
|
+ // Set this to filter events
|
|
|
|
+ Property LogMoments : THTTPLogMoments Read FLogMoments Write FLogMoments;
|
|
// Called to create socket handler. If not set, or Nil is returned, a standard socket handler is created.
|
|
// Called to create socket handler. If not set, or Nil is returned, a standard socket handler is created.
|
|
Property OnGetSocketHandler : TGetSocketHandlerEvent Read FOnGetSocketHandler Write FOnGetSocketHandler;
|
|
Property OnGetSocketHandler : TGetSocketHandlerEvent Read FOnGetSocketHandler Write FOnGetSocketHandler;
|
|
// Called after create socket handler was created, with the created socket handler.
|
|
// Called after create socket handler was created, with the created socket handler.
|
|
Property AfterSocketHandlerCreate : TSocketHandlerCreatedEvent Read FAfterSocketHandlerCreated Write FAfterSocketHandlerCreated;
|
|
Property AfterSocketHandlerCreate : TSocketHandlerCreatedEvent Read FAfterSocketHandlerCreated Write FAfterSocketHandlerCreated;
|
|
|
|
+ // Called to log events
|
|
|
|
+ Property OnLog : THTTPLogEvent Read FOnLog Write FOnLog;
|
|
end;
|
|
end;
|
|
|
|
|
|
TFPHttpServer = Class(TFPCustomHttpServer)
|
|
TFPHttpServer = Class(TFPCustomHttpServer)
|
|
@@ -472,22 +500,38 @@ Type
|
|
Property KeepConnectionTimeout;
|
|
Property KeepConnectionTimeout;
|
|
Property OnKeepConnectionIdle;
|
|
Property OnKeepConnectionIdle;
|
|
Property OnUnexpectedError;
|
|
Property OnUnexpectedError;
|
|
|
|
+ Property LogMoments;
|
|
|
|
+ Property OnLog;
|
|
end;
|
|
end;
|
|
|
|
|
|
EHTTPServer = Class(EHTTP);
|
|
EHTTPServer = Class(EHTTP);
|
|
|
|
|
|
Function GetStatusCode (ACode: Integer) : String; deprecated 'Use GetHTTPStatusText from unit httpprotocol';
|
|
Function GetStatusCode (ACode: Integer) : String; deprecated 'Use GetHTTPStatusText from unit httpprotocol';
|
|
|
|
|
|
|
|
+Const
|
|
|
|
+ AllLogMoments = [Low(THTTPLogMoment)..High(THTTPLogMoment)];
|
|
|
|
+
|
|
implementation
|
|
implementation
|
|
|
|
|
|
|
|
|
|
resourcestring
|
|
resourcestring
|
|
SErrSocketActive = 'Operation not allowed while server is active';
|
|
SErrSocketActive = 'Operation not allowed while server is active';
|
|
SErrReadingSocket = 'Error reading data from the socket';
|
|
SErrReadingSocket = 'Error reading data from the socket';
|
|
- SErrMissingProtocol = 'Missing HTTP protocol version in request';
|
|
|
|
|
|
+ SErrMissingProtocol = 'Missing HTTP protocol version in request "%s"';
|
|
SErrDuplicateUpgradeHandler = 'Duplicate upgrade handler';
|
|
SErrDuplicateUpgradeHandler = 'Duplicate upgrade handler';
|
|
|
|
+ SUpgradingConnection = 'connection "%s" is upgraded to %s for request: %s';
|
|
|
|
+ SErrAcceptingNewConnection = 'Accepting new connection (%s) from %s';
|
|
|
|
+ SErrorDuringRequest = 'Exception %s during request handling: %s';
|
|
|
|
+ SStartSocket = 'Creating socket on port %d';
|
|
|
|
+ SClosingConnection = 'Closing connection (%s) to %s';
|
|
|
|
+ SStopSocket = 'Closing socket on port %d';
|
|
|
|
+ SRequestDone = 'Finished handling request %s';
|
|
|
|
+ SRequestStart = 'Start handling request %s';
|
|
|
|
+ SErrLogMissingProtocol = 'Missing HTTP protocol version in first line "%s" for request';
|
|
|
|
+ SWarnEmptyRequest = 'Empty request detected.';
|
|
|
|
|
|
{ TFPHTTPConnectionRequest }
|
|
{ TFPHTTPConnectionRequest }
|
|
|
|
+
|
|
Function GetStatusCode (ACode: Integer) : String;
|
|
Function GetStatusCode (ACode: Integer) : String;
|
|
|
|
|
|
begin
|
|
begin
|
|
@@ -932,13 +976,17 @@ begin
|
|
except
|
|
except
|
|
On E : exception do
|
|
On E : exception do
|
|
HandleUnexpectedError(E);
|
|
HandleUnexpectedError(E);
|
|
- end;
|
|
|
|
|
|
+ end
|
|
|
|
+ else if Assigned(Server) and Server.CanLog(hlmError) then
|
|
|
|
+ Server.DoLog(hlmError,SErrorDuringRequest,[E.ClassName,E.Message]);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TFPHTTPConnection.HandleUnexpectedError(E: Exception);
|
|
procedure TFPHTTPConnection.HandleUnexpectedError(E: Exception);
|
|
begin
|
|
begin
|
|
If Assigned(FOnUnexpectedError) then
|
|
If Assigned(FOnUnexpectedError) then
|
|
- FOnUnexpectedError(Self,E);
|
|
|
|
|
|
+ FOnUnexpectedError(Self,E)
|
|
|
|
+ else if Assigned(Server) and Server.CanLog(hlmError) then
|
|
|
|
+ Server.DoLog(hlmError,SErrorDuringRequest,[E.ClassName,E.Message]);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TFPHTTPConnection.SetupSocket;
|
|
procedure TFPHTTPConnection.SetupSocket;
|
|
@@ -955,7 +1003,8 @@ begin
|
|
FBusy:=True;
|
|
FBusy:=True;
|
|
end;
|
|
end;
|
|
|
|
|
|
-Procedure TFPHTTPConnection.InterPretHeader(ARequest : TFPHTTPConnectionRequest; Const AHeader : String);
|
|
|
|
|
|
+procedure TFPHTTPConnection.InterPretHeader(ARequest: TFPHTTPConnectionRequest;
|
|
|
|
+ const AHeader: String);
|
|
|
|
|
|
Var
|
|
Var
|
|
P : Integer;
|
|
P : Integer;
|
|
@@ -977,7 +1026,7 @@ begin
|
|
ARequest.SetFieldByName(N,V);
|
|
ARequest.SetFieldByName(N,V);
|
|
end;
|
|
end;
|
|
|
|
|
|
-procedure ParseStartLine(Request : TFPHTTPConnectionRequest; AStartLine : String);
|
|
|
|
|
|
+procedure TFPHTTPConnection.ParseStartLine(Request : TFPHTTPConnectionRequest; AStartLine : String);
|
|
|
|
|
|
Function GetNextWord(Var S : String) : string;
|
|
Function GetNextWord(Var S : String) : string;
|
|
|
|
|
|
@@ -1011,13 +1060,20 @@ begin
|
|
S:='';
|
|
S:='';
|
|
Request.PathInfo:=S;
|
|
Request.PathInfo:=S;
|
|
S:=GetNextWord(AStartLine);
|
|
S:=GetNextWord(AStartLine);
|
|
|
|
+ If Assigned(Server) and Server.CanLog(hlmRequestStart) then
|
|
|
|
+ Server.DoLog(hlmRequestStart,SRequestStart,[Request.ToString]);
|
|
If (S<>'') and (Pos('HTTP/',S)<>1) then
|
|
If (S<>'') and (Pos('HTTP/',S)<>1) then
|
|
- Raise EHTTPServer.CreateHelp(SErrMissingProtocol,400);
|
|
|
|
|
|
+ begin
|
|
|
|
+ If Assigned(Server) and Server.CanLog(hlmNoHTTPProtocol) then
|
|
|
|
+ Server.DoLog(hlmNoHTTPProtocol,SErrLogMissingProtocol,[aStartLine,Request.ToString]);
|
|
|
|
+ Raise EHTTPServer.CreateFmtHelp(SErrMissingProtocol,[AStartLine],400);
|
|
|
|
+ end;
|
|
Delete(S,1,5);
|
|
Delete(S,1,5);
|
|
Request.ProtocolVersion:=trim(S);
|
|
Request.ProtocolVersion:=trim(S);
|
|
end;
|
|
end;
|
|
|
|
|
|
-Procedure TFPHTTPConnection.ReadRequestContent(ARequest : TFPHTTPConnectionRequest);
|
|
|
|
|
|
+procedure TFPHTTPConnection.ReadRequestContent(
|
|
|
|
+ ARequest: TFPHTTPConnectionRequest);
|
|
|
|
|
|
Var
|
|
Var
|
|
P,L,R : integer;
|
|
P,L,R : integer;
|
|
@@ -1060,11 +1116,14 @@ function TFPHTTPConnection.ReadRequestHeaders: TFPHTTPConnectionRequest;
|
|
Var
|
|
Var
|
|
StartLine,S : String;
|
|
StartLine,S : String;
|
|
begin
|
|
begin
|
|
|
|
+ Result:=Nil;
|
|
|
|
+ StartLine:=ReadString;
|
|
|
|
+ if StartLine='' then
|
|
|
|
+ exit;
|
|
Result:=Server.CreateRequest;
|
|
Result:=Server.CreateRequest;
|
|
try
|
|
try
|
|
Server.InitRequest(Result);
|
|
Server.InitRequest(Result);
|
|
Result.FConnection:=Self;
|
|
Result.FConnection:=Self;
|
|
- StartLine:=ReadString;
|
|
|
|
ParseStartLine(Result,StartLine);
|
|
ParseStartLine(Result,StartLine);
|
|
Repeat
|
|
Repeat
|
|
S:=ReadString;
|
|
S:=ReadString;
|
|
@@ -1081,7 +1140,7 @@ end;
|
|
|
|
|
|
function TFPHTTPConnection.AllowNewRequest: Boolean;
|
|
function TFPHTTPConnection.AllowNewRequest: Boolean;
|
|
begin
|
|
begin
|
|
- Result:=not (Busy or IsUpgraded);
|
|
|
|
|
|
+ Result:=not (Busy or IsUpgraded or EmptyDetected);
|
|
Result:=Result and KeepConnections and KeepAlive and (Socket.LastError=0) ;
|
|
Result:=Result and KeepConnections and KeepAlive and (Socket.LastError=0) ;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -1090,7 +1149,8 @@ begin
|
|
Result:=(Not IsUpgraded) and Socket.CanRead(KeepConnectionIdleTimeout);
|
|
Result:=(Not IsUpgraded) and Socket.CanRead(KeepConnectionIdleTimeout);
|
|
end;
|
|
end;
|
|
|
|
|
|
-constructor TFPHTTPConnection.Create(AServer: TFPCustomHttpServer; ASocket: TSocketStream);
|
|
|
|
|
|
+constructor TFPHTTPConnection.Create(AServer: TFPCustomHTTPServer;
|
|
|
|
+ ASocket: TSocketStream);
|
|
begin
|
|
begin
|
|
FIsUpgraded:=False;
|
|
FIsUpgraded:=False;
|
|
FIsSocketSetup:=False;
|
|
FIsSocketSetup:=False;
|
|
@@ -1101,11 +1161,14 @@ end;
|
|
|
|
|
|
destructor TFPHTTPConnection.Destroy;
|
|
destructor TFPHTTPConnection.Destroy;
|
|
begin
|
|
begin
|
|
|
|
+ If Assigned(FServer) and FServer.CanLog(hlmDisConnect) then
|
|
|
|
+ FServer.DoLog(hlmDisconnect,SClosingConnection,[Self.ConnectionID,HostAddrToStr(FSocket.RemoteAddress.sin_addr)]);
|
|
FreeAndNil(FSocket);
|
|
FreeAndNil(FSocket);
|
|
|
|
+
|
|
Inherited;
|
|
Inherited;
|
|
end;
|
|
end;
|
|
|
|
|
|
-Function TFPHTTPConnection.GetLookupHostNames : Boolean;
|
|
|
|
|
|
+function TFPHTTPConnection.GetLookupHostNames: Boolean;
|
|
|
|
|
|
begin
|
|
begin
|
|
if Assigned(FServer) then
|
|
if Assigned(FServer) then
|
|
@@ -1139,7 +1202,17 @@ begin
|
|
// Read headers.
|
|
// Read headers.
|
|
Resp:=Nil;
|
|
Resp:=Nil;
|
|
Req:=ReadRequestHeaders;
|
|
Req:=ReadRequestHeaders;
|
|
|
|
+ If Req=Nil then
|
|
|
|
+ begin
|
|
|
|
+ If Assigned(Server) and Server.CanLog(hlmEmptyRequest) then
|
|
|
|
+ Server.DoLog(hlmEmptyRequest,SWarnEmptyRequest);
|
|
|
|
+ FKeepAlive:=False;
|
|
|
|
+ FEmptyDetected:=True;
|
|
|
|
+ exit;
|
|
|
|
+ end;
|
|
try
|
|
try
|
|
|
|
+ If Assigned(Server) and Server.CanLog(hlmHeaders) then
|
|
|
|
+ Server.DoLog(hlmHeaders,Req.ToString);
|
|
//set port
|
|
//set port
|
|
Req.ServerPort := Server.Port;
|
|
Req.ServerPort := Server.Port;
|
|
// Read content, if any
|
|
// Read content, if any
|
|
@@ -1173,6 +1246,8 @@ begin
|
|
Server.HandleRequest(Req,Resp);
|
|
Server.HandleRequest(Req,Resp);
|
|
if Assigned(Resp) and (not Resp.ContentSent) then
|
|
if Assigned(Resp) and (not Resp.ContentSent) then
|
|
Resp.SendContent;
|
|
Resp.SendContent;
|
|
|
|
+ If Assigned(Server) and Server.CanLog(hlmRequestDone) then
|
|
|
|
+ Server.DoLog(hlmRequestDone,SRequestDone,[Resp.ToString]);
|
|
Finally
|
|
Finally
|
|
FreeAndNil(Resp);
|
|
FreeAndNil(Resp);
|
|
FreeAndNil(Req);
|
|
FreeAndNil(Req);
|
|
@@ -1277,6 +1352,8 @@ end;
|
|
|
|
|
|
procedure TFPCustomHttpServer.HandleRequestError(Sender: TObject; E: Exception);
|
|
procedure TFPCustomHttpServer.HandleRequestError(Sender: TObject; E: Exception);
|
|
begin
|
|
begin
|
|
|
|
+ if CanLog(hlmError) then
|
|
|
|
+ DoLog(hlmError,SErrorDuringRequest,[E.ClassName,E.Message]);
|
|
If Assigned(FOnRequestError) then
|
|
If Assigned(FOnRequestError) then
|
|
try
|
|
try
|
|
FOnRequestError(Sender,E);
|
|
FOnRequestError(Sender,E);
|
|
@@ -1366,6 +1443,8 @@ end;
|
|
|
|
|
|
procedure TFPCustomHttpServer.StopServerSocket;
|
|
procedure TFPCustomHttpServer.StopServerSocket;
|
|
begin
|
|
begin
|
|
|
|
+ if CanLog(hlmCloseSocket) then
|
|
|
|
+ DoLog(hlmCloseSocket,SStopSocket,[Port]);
|
|
FServer.StopAccepting(False);
|
|
FServer.StopAccepting(False);
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -1501,6 +1580,8 @@ begin
|
|
Con.FServer:=Self;
|
|
Con.FServer:=Self;
|
|
Con.OnRequestError:=@HandleRequestError;
|
|
Con.OnRequestError:=@HandleRequestError;
|
|
Con.OnUnexpectedError:=@HandleUnexpectedError;
|
|
Con.OnUnexpectedError:=@HandleUnexpectedError;
|
|
|
|
+ If CanLog(hlmConnect) then
|
|
|
|
+ DoLog(hlmConnect,SErrAcceptingNewConnection,[Con.ConnectionID, HostAddrToStr(Data.RemoteAddress.sin_addr)]);
|
|
FConnectionHandler.HandleConnection(Con);
|
|
FConnectionHandler.HandleConnection(Con);
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -1518,6 +1599,32 @@ begin
|
|
FConnectionHandler:=CreateConnectionHandler();
|
|
FConnectionHandler:=CreateConnectionHandler();
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+
|
|
|
|
+function TFPCustomHttpServer.CanLog(aMoment: THTTPLogMoment): Boolean;
|
|
|
|
+begin
|
|
|
|
+ Result:=aMoment in FLogMoments;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TFPCustomHttpServer.DoLog(aType: TEventType; const Msg: String);
|
|
|
|
+begin
|
|
|
|
+ if Assigned(FOnLog) then
|
|
|
|
+ FOnLog(Self,aType,Msg);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TFPCustomHttpServer.DoLog(aMoment: THTTPLogMoment; const Msg: String);
|
|
|
|
+begin
|
|
|
|
+ If CanLog(aMoment) then
|
|
|
|
+ DoLog(LogMomentEventTypes[aMoment],Msg)
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TFPCustomHttpServer.DoLog(aMoment: THTTPLogMoment; const Fmt: String;
|
|
|
|
+ const Args: array of const);
|
|
|
|
+begin
|
|
|
|
+ if CanLog(aMoment) then
|
|
|
|
+ DoLog(aMoment,Format(Fmt,Args));
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+
|
|
function TFPCustomHttpServer.CheckUpgrade(aConnection: TFPHTTPConnection; aRequest: TFPHTTPConnectionRequest): Boolean;
|
|
function TFPCustomHttpServer.CheckUpgrade(aConnection: TFPHTTPConnection; aRequest: TFPHTTPConnectionRequest): Boolean;
|
|
|
|
|
|
Var
|
|
Var
|
|
@@ -1542,7 +1649,11 @@ begin
|
|
Inc(I);
|
|
Inc(I);
|
|
end;
|
|
end;
|
|
If Result then
|
|
If Result then
|
|
|
|
+ begin
|
|
|
|
+ if CanLog(hlmUpgrade) then
|
|
|
|
+ DoLog(hlmUpgrade,SUpgradingConnection,[aConnection.ConnectionID,aRequest.GetHeader(hhUpgrade),aRequest.ToString]);
|
|
Handler.OnUpgrade(aConnection,aRequest);
|
|
Handler.OnUpgrade(aConnection,aRequest);
|
|
|
|
+ end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -1553,10 +1664,22 @@ end;
|
|
|
|
|
|
procedure TFPCustomHttpServer.HandleUnexpectedError(Sender: TObject; E: Exception);
|
|
procedure TFPCustomHttpServer.HandleUnexpectedError(Sender: TObject; E: Exception);
|
|
begin
|
|
begin
|
|
|
|
+ if CanLog(hlmError) then
|
|
|
|
+ DoLog(hlmError,SErrorDuringRequest,[E.ClassName,E.Message]);
|
|
If Assigned(FOnUnexpectedError) then
|
|
If Assigned(FOnUnexpectedError) then
|
|
FOnUnexpectedError(Sender,E);
|
|
FOnUnexpectedError(Sender,E);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+class constructor TFPCustomHttpServer.init;
|
|
|
|
+
|
|
|
|
+Const
|
|
|
|
+ aDefaults : TLogMomentEventTypes =
|
|
|
|
+ (etInfo,etInfo,etInfo,etDebug,etWarning,etInfo,etInfo,etInfo,etInfo,etInfo,etError) ;
|
|
|
|
+
|
|
|
|
+begin
|
|
|
|
+ LogMomentEventTypes:=aDefaults;
|
|
|
|
+end;
|
|
|
|
+
|
|
procedure TFPCustomHttpServer.CreateServerSocket;
|
|
procedure TFPCustomHttpServer.CreateServerSocket;
|
|
|
|
|
|
begin
|
|
begin
|
|
@@ -1575,6 +1698,8 @@ end;
|
|
|
|
|
|
procedure TFPCustomHttpServer.StartServerSocket;
|
|
procedure TFPCustomHttpServer.StartServerSocket;
|
|
begin
|
|
begin
|
|
|
|
+ if CanLog(hlmStartSocket) then
|
|
|
|
+ DoLog(hlmStartSocket,SStartSocket,[Port]);
|
|
FServer.Bind;
|
|
FServer.Bind;
|
|
FServer.Listen;
|
|
FServer.Listen;
|
|
FServer.StartAccepting;
|
|
FServer.StartAccepting;
|