BSOne.SFC/eCrmHE/EXE_eCrmHomeEdition/Thread/ThdSendFiles.pas

351 lines
10 KiB
Plaintext

{*******************************************************}
{ }
{ ThdSendFiles }
{ }
{ Copyright (C) 2022 kku }
{ }
{*******************************************************}
unit ThdSendFiles;
interface
uses
Tocsg.Thread, System.SysUtils, System.Classes, Winapi.Windows,
IdHTTP, IdSSLOpenSSL, IdIOHandler;
type
TThdSendFilesFromDir = class(TTgThread)
protected
HTTP_: TIdHTTP;
SSL_: TIdSSLIOHandlerSocketOpenSSL;
sTgDir_,
sTaskId_: String;
bIncSubDir_: Boolean;
procedure Execute; override;
public
Constructor Create(sTgDir: String; bIncSubDir: Boolean);
Destructor Destroy; override;
property WorkState: TTgThreadState read GetWorkState;
end;
implementation
uses
Tocsg.Files, Tocsg.Exception, Tocsg.Safe, ManagerService, IdMultipartFormData,
Tocsg.Path, Tocsg.DateTime, superobject, ManagerModel, Tocsg.Strings,
Condition, GlobalDefine;
{ TThdSendFiles }
Constructor TThdSendFilesFromDir.Create(sTgDir: String; bIncSubDir: Boolean);
procedure InitHttp;
begin
SSL_ := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
SSL_.SSLOptions.Method := sslvSSLv23;
SSL_.SSLOptions.SSLVersions := [sslvTLSv1_2, sslvTLSv1_1, sslvTLSv1];
HTTP_ := TIdHTTP.Create(nil);
HTTP_.IOHandler := SSL_;
with HTTP_ do
begin
{
HandleRedirects := true;
Request.Clear;
Request.UserAgent := 'Mozilla/5.0';
Request.ContentType := 'application/xml';
Request.AcceptCharSet := 'UTF-8'; //'application/json; charset=utf-8';
Request.Connection := 'Keep-Alive';
HTTPOptions := HTTP_.HTTPOptions + [hoForceEncodeParams];
ConnectTimeout := 2000;
ReadTimeout := 2000;
}
HandleRedirects := true;
Request.Clear;
Request.UserAgent := 'Mozilla/5.0';
Request.ContentType := 'application/xml';
// Request.Accept := 'application/json; charset=utf-8';
// Request.Charset := 'utf-8';
Request.AcceptCharSet := 'UTF-8'; //'application/json; charset=utf-8';
// Request.CacheControl := 'no-store';
// Request.Connection := 'Keep-Alive';
// Request.CustomHeaders.Values['Keep-Alive'] := 'timeout=300, max=100';
Request.Connection := 'close';
HTTPOptions := HTTPOptions - [hoKeepOrigProtocol];
HTTPOptions := HTTP_.HTTPOptions + [hoForceEncodeParams];
ConnectTimeout := 2000;
ReadTimeout := 2000;
end;
end;
begin
Inherited Create;
sTgDir_ := sTgDir;
bIncSubDir_ := bIncSubDir;
InitHttp;
end;
Destructor TThdSendFilesFromDir.Destroy;
begin
FreeAndNil(HTTP_);
FreeANDNil(SSL_);
Inherited;
end;
procedure TThdSendFilesFromDir.Execute;
var
sDestInfoUrl,
sDestFileUrl,
sBoundary: String;
msResp: TMemoryStream;
ss: TStringStream;
nSendCnt,
nSendSuccessCnt: Integer;
CollectKind: TFileCollectKind;
KwdList: TStringList;
procedure SendEventLog(sStatus: String);
var
O: ISuperObject;
begin
try
O := SO;
O.S['MODEL_ID'] := gMgSvc.AgentModel.AgentId;
O.S['TOCSG_LA_IFNAME'] := URI_USER_ACTION;
O.S['TOCSG_LA_ID'] := gMgSvc.AgentModel.AgentId;
O.S['TOCSG_LA_EMPID'] := gMgSvc.EmpNo;
O.S['TOCSG_LA_CODE'] := SYSEVT_FILE_COLLECT;
O.S['TOCSG_LA_DATA'] := Format('FileCnt:%d|FileSuccess:%d|Idx:%s|Status:%s',
[nSendCnt, nSendSuccessCnt, sTaskId_, sStatus]);
if IsUseHostNameOnly then
O.S['TOCSG_LA_HOSTNAME'] := gMgSvc.ComName
else
O.S['TOCSG_LA_HOSTNAME'] := gMgSvc.UserName;
O.S['TOCSG_LA_LASTCONNDATE'] := FormatDateTime('yyyy-mm-dd hh:nn:ss', Now);
O.S['TOCSG_LA_MACADDR'] := gMgSvc.NicService.GetIP;
O.S['TOCSG_LA_REMOTEIP'] := gMgSvc.NicService.GetMAC;
ss.Clear;
ss.WriteString(O.AsString);
HTTP_.Request.CustomHeaders.Values['requestType'] := '123119';
HTTP_.Request.ContentType := '';
HTTP_.Post(sDestInfoUrl, ss);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. SendEventLog()');
end;
end;
function SendFile(sPath: String): Boolean;
var
sExt,
sDpName,
sFName: String;
Params: TIdMultiPartFormDataStream;
llSize: LONGLONG;
O: ISuperObject;
begin
Result := false;
try
if not FileExists(sPath) then
begin
_Trace('Fail .. Not found file, Path=%s', [sPath]);
exit;
end;
llSize := GetFileSize_path(sPath);
if llSize > 52428800{50MB} then
begin
_Trace('Ignore .. SendFile(), LargeSize=%d .. Path=%s', [llSize, sPath]);
exit;
end;
sFName := ExtractFileName(sPath);
O := SO;
O.S['KEY_AGENT_ID'] := gMgSvc.AgentModel.AgentId;
O.S['KEY_HOSTNAME'] := gMgSvc.UserName;
O.S['KEY_EMP_ID'] := gMgSvc.EmpNo;
O.S['KEY_FILEPATH'] := ExtractFilePath(sPath);
O.S['KEY_FILENAME'] := sFName;
// O.S['KEY_FILEGUARD'] := 'true';
O.S['KEY_IDX'] := sTaskId_;
O.S['KEY_COLLECTTIME'] := FormatDateTime('YYYY-MM-DD HH_NN_SS', Now);
ss.Clear;
ss.WriteString(O.AsString);
HTTP_.Request.CustomHeaders.Values['requestType'] := '123124';
HTTP_.Request.ContentType := 'application/xml';
HTTP_.Post(sDestInfoUrl, ss);
if HTTP_.ResponseCode <> 200 then
begin
_Trace('Fail .. SendFileInfo(), Path=%s', [sPath]);
exit;
end;
sExt := GetFileExt(sFName);
if sExt = '' then
sExt := 'unknown';
sDpName := StringReplace(sPath, sTgDir_, '', [rfReplaceAll]);
if sDpName <> '' then
sDpName := StringReplace(sDpName, '\', '-;T;_', [rfReplaceAll])
else
sDpName := sFName;
// sDpName := Format('%s-TOCSG_kku-%s', [sTaskId_, sDpName]);
sDpName := Format('%s-TOCSG_%s', [sTaskId_, sDpName]);
HTTP_.Request.CustomHeaders.Values['requestType'] := '';
HTTP_.Request.ContentType := Format('multipart/form-data; boundary=%s; charset=utf-8', [sBoundary]);
Guard(Params, TIdMultiPartFormDataStream.Create);
with Params.AddFile(sDpName,
sPath, Format('application/%s', [sExt])) do
begin
ContentTransfer := '';
HeaderEncoding := '8'; //8bit
HeaderCharSet := 'utf-8';
Charset := 'utf-8';
end;
Params.Position := 0;
msResp.Clear;
HTTP_.Post(sDestFileUrl, Params, msResp);
Result := HTTP_.ResponseCode = 200;
if Result then
_Trace('파일 전송 성공 .. Path="%s"', [sPath], 2)
else
_Trace('파일 전송 실패 .. Path="%s"', [sPath], 2);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. SendFile()');
end;
end;
procedure ExtrFilesFromDir(sDir: String; aList: TStrings);
var
wfd: TWin32FindData;
hSc: THandle;
sChk,
sPath: String;
i: Integer;
begin
sDir := IncludeTrailingPathDelimiter(sDir);
sPath := sDir + '*.*';
hSc := FindFirstFile(PChar(sPath), wfd);
if hSc = INVALID_HANDLE_VALUE then
exit;
try
Repeat
if (String(wfd.cFileName) <> '.') and (String(wfd.cFileName) <> '..') then
if ((wfd.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) <> 0) then
begin
if CollectKind = fckFolderIncSub then
ExtrFilesFromDir(sDir + wfd.cFileName, aList);
end else begin
if CollectKind = fckFolderFKwd then
begin
sChk := UpperCase(wfd.cFileName);
for i := 0 to KwdList.Count - 1 do
begin
if Pos(KwdList[0], sChk) > 0 then
begin
aList.Add(sDir + wfd.cFileName);
break;
end;
end;
end else
aList.Add(sDir + wfd.cFileName);
end;
Until not FindNextFile(hSc, wfd);
finally
WinApi.Windows.FindClose(hSc);
end;
end;
var
FList: TStringList;
i: Integer;
begin
try
CollectKind := gMgSvc.PrefModel.FileCollectKind;
Guard(KwdList, TStringList.Create);
if CollectKind = fckFolderFKwd then
SplitString(UpperCase(gMgSvc.PrefModel.TgFileCollectKwd), '|', KwdList);
Guard(FList, TStringList.Create);
if FileExists(sTgDir_) then
begin
// 대상이 단일 파일일 수 있다 22_1107 13:48:43 kku
FList.Add(sTgDir_);
end else begin
sTgDir_ := IncludeTrailingPathDelimiter(sTgDir_);
if not DirectoryExists(sTgDir_) then
begin
_Trace('Fail .. Not found dir, Dir=%s', [sTgDir_]);
SetWorkState(tsFail);
exit;
end;
ExtrFilesFromDir(sTgDir_, FList);
end;
nSendCnt := FList.Count;
nSendSuccessCnt := 0;
if nSendCnt = 0 then
begin
_Trace('Fail .. Not found file, Dir=%s', [sTgDir_]);
SetWorkState(tsFail);
exit;
end;
sTaskId_ := FormatDateTime('hhnnss', Now) + StringReplace(gMgSvc.UserName, '\', '', [rfReplaceAll]);
if Length(sTaskId_) > 24 then
SetLength(sTaskId_, 24);
SetWorkState(tsWorking);
sDestInfoUrl := gMgSvc.DestServerUrl;
sDestFileUrl := StringReplace(gMgSvc.DestServerUrl, 'agentLogRequest.do', 'agentFileCollect.do', [rfReplaceAll]);
sDestFileUrl := StringReplace(sDestFileUrl, 'agentLogRequests.do', 'agentFileCollect.do', [rfReplaceAll]);
sBoundary := Format('%X', [GetLocalIncUtcMin * 6000]);
// HTTP_.Request.ContentType := Format('multipart/form-data; boundary=%s; charset=utf-8', [sBoundary]);
Guard(ss, TStringStream.Create('', TEncoding.UTF8));
SendEventLog('Start');
Guard(msResp, TMemoryStream.Create);
for i := 0 to FList.Count - 1 do
begin
if Terminated or GetWorkStop then
begin
_Trace('Stop .. send file, %d / %d', [i, FList.Count]);
SendEventLog('Fail');
SetWorkState(tsStop);
exit;
end;
if SendFile(FList[i]) then
Inc(nSendSuccessCnt);
end;
SendEventLog('Complete');
SetWorkState(tsCompleted);
_Trace('Completed .. Collect files from folder="%s"', [sTgDir_], 1);
except
on E: Exception do
begin
SetWorkState(tsFail);
ETgException.TraceException(Self, E, 'Fail .. Execute()');
end;
end;
end;
end.