This commit is contained in:
Алексей Заблоцкий 2023-10-19 13:08:34 +03:00
parent 2df92e04a1
commit f6fb6db5d7
15 changed files with 125 additions and 97 deletions

2
.gitignore vendored
View File

@ -12,7 +12,7 @@
*.o *.o
*.or *.or
*.a *.a
*.log
# Lazarus autogenerated files (duplicated info) # Lazarus autogenerated files (duplicated info)
*.rst *.rst
*.rsj *.rsj

Binary file not shown.

View File

@ -5,7 +5,7 @@ unit cgi_daemon;
interface interface
uses uses
Classes, SysUtils, DaemonApp, ConnectionsDmUnit; Classes, SysUtils, DaemonApp, ConnectionsDmUnit,eventlog;
type type
TLMSReportCGI=class; TLMSReportCGI=class;
@ -14,6 +14,7 @@ type
TDaemonThread=class(TThread) TDaemonThread=class(TThread)
fOwner: TLMSReportCGI; fOwner: TLMSReportCGI;
fData: TConnectionsDM; fData: TConnectionsDM;
fLogger: TEventLog;
procedure Execute;override; procedure Execute;override;
function sleepMin(n: integer): boolean; function sleepMin(n: integer): boolean;
constructor Create(AOwner: TLMSReportCGI); constructor Create(AOwner: TLMSReportCGI);
@ -36,7 +37,8 @@ var
LMSReportCGI: TLMSReportCGI; LMSReportCGI: TLMSReportCGI;
implementation implementation
uses
LazLogger;
procedure RegisterDaemon; procedure RegisterDaemon;
begin begin
RegisterDaemonClass(TLMSReportCGI) RegisterDaemonClass(TLMSReportCGI)
@ -48,6 +50,14 @@ end;
procedure TLMSReportCGI.DataModuleCreate(Sender: TObject); procedure TLMSReportCGI.DataModuleCreate(Sender: TObject);
begin begin
//{$IFDEF WINDOWS}
self.Logger.Active:=false;
self.Logger.AppendContent:=true;
self.Logger.LogType := ltFile;
self.Logger.FileName := format('%s/server.log',[extractfilepath(paramstr(0))]);
self.Logger.Active:=true;
//{$ENDIF}
self.logger.Info('TLMSReportCGI.DataModuleCreate');
workThread := TDaemonThread.create(self); workThread := TDaemonThread.create(self);
end; end;
@ -58,13 +68,15 @@ end;
procedure TLMSReportCGI.DataModuleStart(Sender: TCustomDaemon; var OK: Boolean); procedure TLMSReportCGI.DataModuleStart(Sender: TCustomDaemon; var OK: Boolean);
begin begin
logger.Info('start daemon thread');
workThread.Start; workThread.Start;
logger.Info('daemon thread started');
OK := true; OK := true;
end; end;
procedure TLMSReportCGI.DataModuleStop(Sender: TCustomDaemon; var OK: Boolean); procedure TLMSReportCGI.DataModuleStop(Sender: TCustomDaemon; var OK: Boolean);
begin begin
debugln('stop daemon thread');
workThread.Terminate; workThread.Terminate;
end; end;
@ -72,13 +84,19 @@ end;
procedure TDaemonThread.Execute; procedure TDaemonThread.Execute;
begin begin
fData := TConnectionsDM.Create(nil); flogger.Info('TDaemonThread.Execute');
fData := TConnectionsDM.CreateWithLog(fLogger);
try try
fData.logger := fLogger;
fData.log(self,'logging');
flogger.Info('TDaemonThread.Execute.1');
fData.Start; fData.Start;
flogger.Info('TDaemonThread.Execute.2');
while not terminated do while not terminated do
begin begin
if sleepMin(2) then if sleepMin(2) then
fData.Idle(self); fData.Idle(self);
flogger.Info('TDaemonThread.Idle');
end; end;
fData.Stop; fData.Stop;
finally finally
@ -102,6 +120,7 @@ constructor TDaemonThread.Create(AOwner: TLMSReportCGI);
begin begin
inherited Create(true); inherited Create(true);
fOwner:=AOwner; fOwner:=AOwner;
fLogger:=AOwner.Logger;
end; end;

View File

@ -48,6 +48,7 @@ type
procedure log(Sender: TObject; msg: string); procedure log(Sender: TObject; msg: string);
procedure LogError(Sender: TObject; e: Exception; msg: string); procedure LogError(Sender: TObject; e: Exception; msg: string);
procedure ExecuteSQL(ASQL: string); procedure ExecuteSQL(ASQL: string);
constructor CreateWithLogger(ALogger: TLogger);
end; end;
var var
@ -62,9 +63,9 @@ uses
procedure TNIDBDM.DataModuleCreate(Sender: TObject); procedure TNIDBDM.DataModuleCreate(Sender: TObject);
begin begin
log(self,'connecting'); log(sender,'TnnzConnection.Create');
fcon := TnnzConnection.Create(self); fcon := TnnzConnection.Create(self);
log(sender,'TnnzConnection.Create.ok');
end; end;
@ -359,5 +360,12 @@ begin
connection.ExecuteSQL(ASQL); connection.ExecuteSQL(ASQL);
end; end;
constructor TNIDBDM.CreateWithLogger(ALogger: TLogger);
begin
fLogger := ALogger;
log(nil,'TNIDBDM.Create');
inherited Create(nil);
end;
end. end.

View File

@ -5,8 +5,8 @@ unit ConnectionsDmUnit;
interface interface
uses uses
Classes, Contnrs, SysUtils, types, process, cgiDM, reportDMUnit, LNet, Classes, Contnrs, SysUtils, types, process, cgiDM, reportDMUnit, LNet,eventlog,
lnetbase,tcpserver, tcpthreadhelper, DCPsha1, extTypes,syncobjs, baseconnection; lnetbase,tcpserver, tcpthreadhelper, DCPsha1, extTypes,syncobjs, baseconnection,LazLoggerBase,LazLogger;
type type
@ -32,7 +32,7 @@ type
fDataPort: integer; fDataPort: integer;
fDataBase: string; fDataBase: string;
fServicePort: integer; fServicePort: integer;
fLogger: TEventLog;
fTimeOut: integer; fTimeOut: integer;
LogLock: TCriticalSection; LogLock: TCriticalSection;
fRunning: boolean; fRunning: boolean;
@ -51,6 +51,7 @@ type
property DataHost: string read fDataHost; property DataHost: string read fDataHost;
property DataPort: integer read fDataPort; property DataPort: integer read fDataPort;
property DataBase: string read fDataBase; property DataBase: string read fDataBase;
property Logger: TEventLog read fLogger write fLogger;
procedure Log(Sender: TObject; msg: string); procedure Log(Sender: TObject; msg: string);
procedure Start; procedure Start;
procedure Stop; procedure Stop;
@ -59,7 +60,7 @@ type
function ProcessRequest(Sender: TMainThread; function ProcessRequest(Sender: TMainThread;
const CommandID:DWORD; const Param:QWord; const ACommand: string; const Fields: TStrings; const iParams: TParamArray; const Data: TStream; const CommandID:DWORD; const Param:QWord; const ACommand: string; const Fields: TStrings; const iParams: TParamArray; const Data: TStream;
out Code: DWORD; out RetValue: QWord; out Answer: string; out rValues: TStrings; out iValues: TParamArray; out ByteData: TStream ): boolean; out Code: DWORD; out RetValue: QWord; out Answer: string; out rValues: TStrings; out iValues: TParamArray; out ByteData: TStream ): boolean;
constructor CreateWithLog(ALogger: TEventLog);
end; end;
var var
@ -77,13 +78,21 @@ uses
procedure TConnectionsDM.DataModuleCreate(Sender: TObject); procedure TConnectionsDM.DataModuleCreate(Sender: TObject);
begin begin
MainCon := TNIDBDM.Create(nil); log(sender,'datamodulecreate-0');
MainCon.logger:=@log; fRunning := false;
log(sender,'datamodulecreate.1');
LogLock := TCriticalSection.Create; LogLock := TCriticalSection.Create;
conList := TList.Create; conList := TList.Create;
log(sender,'datamodulecreate.2');
MainCon := TNIDBDM.CreateWithLogger(@log);
log(sender,'datamodulecreate.3');
MainCon.logger:=@log;
LoadConfig; LoadConfig;
fRunning := false; log(sender,'datamodulecreate.4');
input := TServerMainThread.Create(@log,fServicePort,@ProcessRequest); input := TServerMainThread.Create(@log,fServicePort,@ProcessRequest);
log(sender,'datamodulecreate.ok');
end; end;
procedure TConnectionsDM.DataModuleDestroy(Sender: TObject); procedure TConnectionsDM.DataModuleDestroy(Sender: TObject);
@ -236,7 +245,7 @@ begin
if ACommand='login' then if ACommand='login' then
begin begin
UserName :=Fields.Values['user']; UserName :=Fields.Values['user'];
if ProcessLogin(UserName,EncryptText(Fields.Values['password']),UserID) then if ProcessLogin(UserName,EncryptText(Fields.Values['password'],Hash),UserID) then
begin begin
con := NewConnection; con := NewConnection;
con.User:=UserName; con.User:=UserName;
@ -336,6 +345,12 @@ begin
end; end;
constructor TConnectionsDM.CreateWithLog(ALogger: TEventLog);
begin
fLogger:=Alogger;
inherited Create(nil);
end;
function TConnectionsDM.ProcessLogin(UserName, UserPassword: string; out UserID: integer): boolean; function TConnectionsDM.ProcessLogin(UserName, UserPassword: string; out UserID: integer): boolean;
var var
ASQL: string; ASQL: string;
@ -482,28 +497,16 @@ procedure TConnectionsDM.Log(Sender: TObject; msg: string);
var var
f: TextFile; f: TextFile;
begin begin
if not assigned(fLogger) then exit;
try
try // assignefile(fLogFolder
if fLogFolder='' then exit;
LogLock.Enter;
try
AssignFile(f, fLogFolder);
if fileexists(fLogFolder) then
append(f)
else
rewrite(f);
if Sender is TComponent then if Sender is TComponent then
writeln(f,DateTimeToStr(NOW()),#09,Sender.ClassName,'-',(Sender as TComponent).Name, #09, Msg) flogger.Debug(DateTimeToStr(NOW())+#09+Sender.ClassName+'-'+(Sender as TComponent).Name+#09+Msg)
else if Assigned(Sender) then else if Assigned(Sender) then
writeln(f,DateTimeToStr(NOW()),#09,Sender.ClassName, #09, Msg) flogger.Debug(DateTimeToStr(NOW())+#09+Sender.ClassName+ #09+ Msg)
else else
writeln(f,DateTimeToStr(NOW()),#09, #09, Msg); flogger.Debug(DateTimeToStr(NOW())+#09+ #09+ Msg);
closeFile(f);
finally
logLock.Leave;
end;
except on e: Exception do except on e: Exception do
raise; raise;
end; end;

Binary file not shown.

View File

@ -4,4 +4,4 @@ port=7079
database=lms database=lms
[PARAMS] [PARAMS]
port=6543 port=6543
log=D:\PROJECTS\LAZARUS\LMS\out\server.log log=/var/log/nintegra/cgireport.log

BIN
lmsreport Executable file

Binary file not shown.

View File

@ -21,18 +21,7 @@ begin
RequireDerivedFormResource:=True; RequireDerivedFormResource:=True;
Application.Scaled:=True; Application.Scaled:=True;
Application.Initialize; Application.Initialize;
if paramstr(1)='console' then
begin
Application.CreateForm(TCGIServerGUI, CGIServerGUI); Application.CreateForm(TCGIServerGUI, CGIServerGUI);
Application.Run; Application.Run;
end
else
begin
Application.CreateForm(TConnectionsDM,ConnectionsDM);
ConnectionsDM.start;
while ConnectionsDM.running do
sleep(1000);
end;
end. end.

View File

@ -8,7 +8,7 @@ object CGIServerGUI: TCGIServerGUI
ClientWidth = 870 ClientWidth = 870
OnCreate = FormCreate OnCreate = FormCreate
OnDestroy = FormDestroy OnDestroy = FormDestroy
LCLVersion = '2.2.4.0' LCLVersion = '2.2.0.4'
object Panel1: TPanel object Panel1: TPanel
Left = 0 Left = 0
Height = 50 Height = 50
@ -45,14 +45,14 @@ object CGIServerGUI: TCGIServerGUI
Width = 368 Width = 368
Align = alLeft Align = alLeft
Caption = 'Запрос' Caption = 'Запрос'
ClientHeight = 239 ClientHeight = 240
ClientWidth = 364 ClientWidth = 366
TabOrder = 1 TabOrder = 1
object Keys: TMemo object Keys: TMemo
Left = 0 Left = 0
Height = 216 Height = 210
Top = 23 Top = 30
Width = 364 Width = 366
Align = alClient Align = alClient
Lines.Strings = ( Lines.Strings = (
'user=nnz' 'user=nnz'
@ -62,11 +62,11 @@ object CGIServerGUI: TCGIServerGUI
end end
object edtRequest: TComboBox object edtRequest: TComboBox
Left = 0 Left = 0
Height = 23 Height = 30
Top = 0 Top = 0
Width = 364 Width = 366
Align = alTop Align = alTop
ItemHeight = 15 ItemHeight = 0
ItemIndex = 3 ItemIndex = 3
Items.Strings = ( Items.Strings = (
'version' 'version'
@ -91,40 +91,41 @@ object CGIServerGUI: TCGIServerGUI
Width = 497 Width = 497
Align = alClient Align = alClient
Caption = 'Ответ' Caption = 'Ответ'
ClientHeight = 239 ClientHeight = 240
ClientWidth = 493 ClientWidth = 495
TabOrder = 2 TabOrder = 2
object edtAnswer: TEdit object edtAnswer: TEdit
Left = 0 Left = 0
Height = 23 Height = 30
Top = 25 Top = 25
Width = 493 Width = 495
Align = alTop Align = alTop
OnDblClick = edtAnswerDblClick OnDblClick = edtAnswerDblClick
TabOrder = 0 TabOrder = 0
end end
object retValues: TMemo object retValues: TMemo
Left = 0 Left = 0
Height = 88 Height = 75
Top = 71 Top = 85
Width = 493 Width = 495
Align = alClient Align = alClient
TabOrder = 1 TabOrder = 1
end end
object intValues: TListBox object intValues: TListBox
Left = 0 Left = 0
Height = 80 Height = 80
Top = 159 Top = 160
Width = 493 Width = 495
Align = alBottom Align = alBottom
ItemHeight = 0 ItemHeight = 0
TabOrder = 2 TabOrder = 2
TopIndex = -1
end end
object edtQValue: TEdit object edtQValue: TEdit
Left = 0 Left = 0
Height = 23 Height = 30
Top = 48 Top = 55
Width = 493 Width = 495
Align = alTop Align = alTop
TabOrder = 3 TabOrder = 3
end end
@ -132,7 +133,7 @@ object CGIServerGUI: TCGIServerGUI
Left = 0 Left = 0
Height = 25 Height = 25
Top = 0 Top = 0
Width = 493 Width = 495
Align = alTop Align = alTop
TabOrder = 4 TabOrder = 4
end end

View File

@ -69,12 +69,13 @@ begin
ConnectionsDM := Server; ConnectionsDM := Server;
cmdDone := true; cmdDone := true;
started := false; started := false;
SendButton.Enabled := false; SendButton.Enabled := Paramstr(1)='client';
StartButton.Enabled := not SendButton.Enabled;
end; end;
procedure TCGIServerGUI.SendButtonClick(Sender: TObject); procedure TCGIServerGUI.SendButtonClick(Sender: TObject);
begin begin
if not started then exit; if not started and StartButton.enabled then exit;
client := TClientMainThread.Create(edtRequest.Text,Keys.Lines,@Server.log,'localhost',6543,@onAnswer); client := TClientMainThread.Create(edtRequest.Text,Keys.Lines,@Server.log,'localhost',6543,@onAnswer);
LogQuery(0,edtRequest.Text,Keys.Lines,0,0,[]); LogQuery(0,edtRequest.Text,Keys.Lines,0,0,[]);
cmdDone := false; cmdDone := false;

View File

@ -60,6 +60,7 @@ end;
procedure TClientMainThread.execute; procedure TClientMainThread.execute;
begin begin
doStart;
log(self,'start main thread'); log(self,'start main thread');
Connect.Connect(Host,Port); Connect.Connect(Host,Port);
while not terminated do while not terminated do

View File

@ -60,6 +60,7 @@ procedure TServerMainThread.execute;
var var
n: integer; n: integer;
begin begin
doStart;
log(self,'start main thread'); log(self,'start main thread');
Connect.Listen(Port); Connect.Listen(Port);
n := 0; n := 0;

View File

@ -85,10 +85,12 @@ type
fclients: TList; fclients: TList;
flogger: TLogger; flogger: TLogger;
fThreadClass: TConnectionThreadClass; fThreadClass: TConnectionThreadClass;
fStarted:boolean;
function getThread(index: TLSocket): TConnectionThread; function getThread(index: TLSocket): TConnectionThread;
procedure TerminateClients; procedure TerminateClients;
protected protected
procedure Log(Sender:TObject; msg: string); procedure Log(Sender:TObject; msg: string);
procedure doStart; virtual;
public public
property Port: integer read fPort; property Port: integer read fPort;
property Connect: TLTCP read fCon; property Connect: TLTCP read fCon;
@ -100,7 +102,7 @@ type
procedure Accept(aSocket: TLSocket); procedure Accept(aSocket: TLSocket);
procedure doDisconnect(aSocket: TLSocket); procedure doDisconnect(aSocket: TLSocket);
procedure doConnect(aSocket: TLSocket); procedure doConnect(aSocket: TLSocket);
procedure doTerminate;override; procedure TerminatedSet;override;
procedure NetError(const msg: string; aSocket: TLSocket); procedure NetError(const msg: string; aSocket: TLSocket);
constructor Create(AThreadClass: TConnectionThreadClass; ALogger: TLogger; APort: integer); constructor Create(AThreadClass: TConnectionThreadClass; ALogger: TLogger; APort: integer);
destructor Destroy; override; destructor Destroy; override;
@ -148,8 +150,7 @@ begin
log(self,GuidToString(clt.ID)); log(self,GuidToString(clt.ID));
clt.Terminate; clt.Terminate;
clt.WaitFor; clt.WaitFor;
clt.Free; clt.free;
except on e: Exception do except on e: Exception do
begin begin
log(self, '!!ERROR Destroy ' + e.Message); log(self, '!!ERROR Destroy ' + e.Message);
@ -166,6 +167,11 @@ begin
fLogger(Sender,Msg); fLogger(Sender,Msg);
end; end;
procedure TMainThread.doStart;
begin
fStarted := true;
end;
procedure TMainThread.RemoveClient(clt: TConnectionThread); procedure TMainThread.RemoveClient(clt: TConnectionThread);
begin begin
fclients.Remove(clt); fclients.Remove(clt);
@ -221,8 +227,6 @@ begin
if clt.terminated then exit; if clt.terminated then exit;
log(self,format('disconnected %s on %d ',[GUIDToString(clt.ID), aSocket.Handle])); log(self,format('disconnected %s on %d ',[GUIDToString(clt.ID), aSocket.Handle]));
clt.Terminate; clt.Terminate;
clt.WaitFor;
clt.free;
fclients.remove(clt); fclients.remove(clt);
except on e: Exception do except on e: Exception do
@ -245,9 +249,10 @@ begin
clt.Start; clt.Start;
end; end;
procedure TMainThread.doTerminate; procedure TMainThread.TerminatedSet;
begin begin
inherited doTerminate(); inherited TerminatedSet();
if fStarted then
TerminateClients; TerminateClients;
end; end;
@ -266,6 +271,7 @@ constructor TMainThread.Create(AThreadClass: TConnectionThreadClass;
ALogger: TLogger; APort: integer); ALogger: TLogger; APort: integer);
begin begin
inherited Create(true); inherited Create(true);
fStarted := false;
fThreadClass:=AThreadClass; fThreadClass:=AThreadClass;
fCon := TLTcp.Create(nil); fCon := TLTcp.Create(nil);
fclients := TList.Create; fclients := TList.Create;
@ -970,6 +976,7 @@ var
i,d1,d2 : integer; i,d1,d2 : integer;
begin begin
inherited Create(true); inherited Create(true);
//FreeOnTerminate:=true;
fCache := TRoundBuffer.Create(10000); fCache := TRoundBuffer.Create(10000);
fSocket := ASocket; fSocket := ASocket;
fOwner := AOwner; fOwner := AOwner;
@ -980,10 +987,8 @@ end;
destructor TConnectionThread.Destroy; destructor TConnectionThread.Destroy;
begin begin
log('Destroy');
fCache.Free; fCache.Free;
fOwner.removeClient(self); fOwner.removeClient(self);
log('Destroy2');
inherited Destroy; inherited Destroy;
end; end;
@ -1018,14 +1023,14 @@ begin
end; end;
end; end;
Cache.Close; Cache.Close;
Socket.Disconnect(); //Socket.Disconnect();
log('terminated');
end; end;
procedure TConnectionThread.TerminatedSet; procedure TConnectionThread.TerminatedSet;
begin begin
log('terminate required'); log('terminate required');
Cache.Close; Cache.Close;
fOwner.removeClient(self);
end; end;
{ TClientThread } { TClientThread }

View File

@ -1,41 +1,41 @@
unit xpAccessUnit; unit xpAccessUnit;
{$H+} {$H+}
interface interface
uses
function EncryptText(const AText: String) : String; DCPcrypt2;
function MySQLPassword(const AText: Ansistring) : Ansistring; function EncryptText(const AText: String; aHash: TDCP_hash) : String;
function MySQLPassword(const AText: Ansistring; aHash: TDCP_hash) : Ansistring;
implementation implementation
uses uses
SysUtils, SysUtils,
Variants, DCPsha1, DCPdes, Variants;
ConnectionsDmUnit;
function DecryptText(const AText: string) : string; function DecryptText(const AText: string) : string;
begin begin
Result := AText; Result := AText;
end; end;
function EncryptText(const AText: String) : String; function EncryptText(const AText: String; aHash: TDCP_hash): String;
begin begin
Result := String(MySQLPassword(AnsiString(StringReplace(AText, '\', '\\', [rfReplaceAll, rfIgnoreCase])))); Result := String(MySQLPassword(AnsiString(StringReplace(AText, '\', '\\', [rfReplaceAll, rfIgnoreCase])),aHash));
end; end;
function MySQLPassword(const AText: Ansistring) : Ansistring; function MySQLPassword(const AText: Ansistring; aHash: TDCP_hash): Ansistring;
var var
Digest: packed array[0..19] of byte; Digest: packed array[0..19] of byte;
i: integer; i: integer;
begin begin
Result := '*'; Result := '*';
ConnectionsDM.Hash.Init; aHash.Init;
ConnectionsDM.Hash.UpdateStr(AText); aHash.UpdateStr(AText);
ConnectionsDM.Hash.Final(Digest); aHash.Final(Digest);
ConnectionsDM.Hash.Burn; aHash.Burn;
ConnectionsDM.Hash.Init; aHash.Init;
ConnectionsDM.Hash.Update(Digest,20); aHash.Update(Digest,20);
ConnectionsDM.Hash.Final(Digest); aHash.Final(Digest);
ConnectionsDM.Hash.Burn; aHash.Burn;
for i:= 0 to 19 do for i:= 0 to 19 do
Result := Result + AnsiString(IntToHex(Digest[i], 2)); Result := Result + AnsiString(IntToHex(Digest[i], 2));
end; end;