unit uHTTPServerCommandGet;
{< This unit contains methods that called on idHTTPServer.IdHTTPServerCommandGet Event
To make code more short structured and visible
}

interface

uses

  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, IdBaseComponent, IdComponent, IdCustomTCPServer, IdCustomHTTPServer,
  IdHTTPServer, Vcl.StdCtrls,System.json,System.NetEncoding,System.IOUtils, System.Types,

  HTTPApp,
  IdMultipartFormData, IdContext,
  uDivideAndGatherFileServer,uCreateUniqueNameServer,


  uDecodePOstRequest, IdServerIOHandler, IdSSL, IdSSLOpenSSL,
  IdSSLOpenSSLHeaders, IdTCPConnection, IdTCPClient, IdHTTP


  ;

  //myUnits
//  uDataBaseUnitServer


//  ;


type
  THTTPServerCommandGet = class(TDataModule)
    IdHTTPKeep2Share: TIdHTTP;
  private

//    FDataBaseUnitServer:TDataBaseUnitServer;

    function IsAuthorizationOk(PostParams: TStringList): boolean;
    procedure AddFileToDB(ARelativeDir, AFileName: string; AidUser: Integer);



    {Gather File From Chunks}


    { Private declarations }
  public
    { Public declarations }


    constructor Create(AOwner:TComponent); override;

    {checks if file on Server}
    procedure IsFileOnServer(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
      AResponseInfo: TIdHTTPResponseInfo);


    procedure ReceiveFile(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
  AResponseInfo: TIdHTTPResponseInfo);

  procedure ReceiveFileWithoutLog(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
      AResponseInfo: TIdHTTPResponseInfo);


    procedure AddFileToDBResponse(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);

    procedure ReceiveFileAndChangeName(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
    AResponseInfo: TIdHTTPResponseInfo);



   procedure CheckChunksIntegrity(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
      AResponseInfo: TIdHTTPResponseInfo);


   procedure CreateDirOnServer(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
      AResponseInfo: TIdHTTPResponseInfo);

   procedure DeleteDirOnServer(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
      AResponseInfo: TIdHTTPResponseInfo);

   procedure DeleteFileOnServer(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
      AResponseInfo: TIdHTTPResponseInfo);


    procedure DeleteFoldersAndFilesOnServerWithDataBase(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
      AResponseInfo: TIdHTTPResponseInfo);

  procedure DeleteTempFileOnServer(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
      AResponseInfo: TIdHTTPResponseInfo);


   procedure ReceiveChunksInfo(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
      AResponseInfo: TIdHTTPResponseInfo;var ChunksInfoString:string);

  { checks if file on Server }
  function IsFileOnServerByURI(uri: string; var filepath:string; IsWebPage:boolean; var WebPageContent:string): Boolean;

  procedure GatherFileFromChunks(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);

  procedure SendFile2Keep2Share(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
      AResponseInfo: TIdHTTPResponseInfo);


  end;

//var
//  HTTPServerCommandGet: THTTPServerCommandGet;

implementation

{%CLASSGROUP 'Vcl.Controls.TControl'}

{$R *.dfm}

uses uHTTPServer_Main;

var fHTTPServer_UnitVar:TfHTTPServer;


constructor THTTPServerCommandGet.Create(AOwner: TComponent);
begin
  inherited;

 if (AOwner is TfHTTPServer) then
 fHTTPServer_UnitVar:=(AOwner as TfHTTPServer);

  IdHTTPKeep2Share.Response.KeepAlive:=false;

  IdHTTPKeep2Share.ConnectTimeout:=5*60000; // 5 minutes for big files
  IdHTTPKeep2Share.ReadTimeout:=5*60000;  // 5 minutes for big files


//  FDataBaseUnitServer:=TDataBaseUnitServer.Create(Self);

end;



function THTTPServerCommandGet.IsAuthorizationOk(PostParams:TStringList):boolean;
begin

Result:=false;

   if (PostParams.Values['Login']='SomeLogin')
   and (PostParams.Values['Password']='SomePassword') then

Result:=true else

 raise Exception.Create('Authorization not Ok');




end;




function THTTPServerCommandGet.IsFileOnServerByURI
(uri: string; var filepath:string; IsWebPage:boolean; var WebPageContent:string): Boolean;

var
    AppPath:String;

    uriWinSlash: string;
    Extension: string;

    WebPageContentSL:TStringList;

begin

 Result:=false;

 WebPageContentSL:=TStringList.Create;

//----------- we have URI, lets build normal windows dir

    AppPath:=ExtractFilePath(Application.ExeName);

    uriWinSlash:=StringReplace(uri,'//','',[rfReplaceAll]);
    uriWinSlash:=StringReplace(uriWinSlash,'/','\',[rfReplaceAll]);

    filepath:=AppPath+uriWinSlash;

    if TFile.Exists(filepath) then

     begin

      Extension:=ExtractFileExt(filepath);

        if (Extension='.html') or (Extension='.html') then

            begin
            IsWebPage:=true;

            WebPageContentSL.LoadFromFile(filepath);
            WebPageContent:=WebPageContentSL.Text;

            end;


     Result:=true;
        end;




      FreeAndNil(WebPageContentSL);
end;








procedure THTTPServerCommandGet.ReceiveFile(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
  AResponseInfo: TIdHTTPResponseInfo);

  var PostParams:TStringList;
      DecodePostRequest: TDecodePostRequest;
      dir:string;


      FS:TFileStream;

      AppPath:string;
      logFilePath: string;



       iCounterPerSec: TLargeInteger;
       C1, C2: TLargeInteger;
       ContentSL:TStringList;

       FileNameOnServer:string;
  EncodedFileNameOnServer: string;

begin

//
  QueryPerformanceFrequency(iCounterPerSec);
  QueryPerformanceCounter(C1);

//Create
PostParams:=TStringList.Create;
DecodePostRequest:=TDecodePostRequest.Create(fHTTPServer_UnitVar);
ContentSL:=TStringList.Create;

AppPath:=ExtractFilePath(Application.ExeName);





   try

   //Main work

   PostParams.Clear;
   DecodePostRequest.DecodePostParamsAnsi(AContext,ARequestInfo,AResponseInfo,PostParams);

   dir:=PostParams.Values['dirOnServer']; // dir appears from params
   FileNameOnServer:=PostParams.Values['FileNameOnServer'];

   FileNameOnServer:=TNetEncoding.URL.Decode(FileNameOnServer);


   if IsAuthorizationOk(PostParams) then
   begin

       if FileNameOnServer<>'' then
         begin

         //EncodedFileNameOnServer:=TNetEncoding.URL.Encode(FileNameOnServer);

         logFilePath:=AppPath+dir+'\temp\'+FileNameOnServer+'_UploadlogServer.txt';

         ContentSL.add('                                ');
         ContentSL.add('---ServerSide---');
         ContentSL.add('                                ');

         DecodePostRequest.ReceiveFile(AContext,ARequestInfo,AResponseInfo,dir,FileNameOnServer)
         end

       else

         begin
         logFilePath:=AppPath+dir+'UploadlogServer.txt';

         ContentSL.add('                                ');
         ContentSL.add('---ServerSide---');
         ContentSL.add('                                ');


         DecodePostRequest.ReceiveFile(AContext,ARequestInfo,AResponseInfo,dir);

         end;






          //Saving to log

        if TFile.Exists(logFilePath) then
        ContentSL.LoadFromFile(logFilePath);
        QueryPerformanceCounter(C2);

      ContentSL.add(
      'Receive File on Server = '+FormatFloat('0.0000', (C2 - C1) / iCounterPerSec) + ' sec.'
             );
      ContentSL.SaveToFile(logFilePath);

     AResponseInfo.ContentText := 'ok';
     AResponseInfo.WriteContent;

   end;






   finally


   //Free
   FreeAndNil(DecodePostRequest);
   FreeAndNil(PostParams);
   FreeAndNil(ContentSL);
   end;


end;




procedure THTTPServerCommandGet.ReceiveFileWithoutLog(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
  AResponseInfo: TIdHTTPResponseInfo);

  var PostParams:TStringList;
      DecodePostRequest: TDecodePostRequest;
      dir:string;


      AppPath:string;
      logFilePath: string;
      FileNameOnServer:string;
      UniqueFileNameOnServer:string;

  NamesInDirSDA: TStringDynArray;
  NamesInDirSL: TStringList;
  i: Integer;
  Outputfilepath:string;
  difference:Integer;
  StringWithoutExtension:String;
  Extension:String;
  ReldirOnServer: String;
  idUserString: string;
  AbsDirs: TStringList;
  RelDirs: TStringList;
  idParentForFile:integer;
  RelFilePath: String;
  FileNameToInsert: String;
  AbsPath: String;

  fileSize:Int64;

begin



//Create
PostParams:=TStringList.Create;
DecodePostRequest:=TDecodePostRequest.Create(fHTTPServer_UnitVar);
AppPath:=ExtractFilePath(Application.ExeName);

      AbsDirs:=TStringList.Create;
      RelDirs:=TStringList.Create;



   try

   //Main work

   PostParams.Clear;
   DecodePostRequest.DecodePostParamsAnsi(AContext,ARequestInfo,AResponseInfo,PostParams);

   dir:=PostParams.Values['dirOnServer']; // dir appears from params
   FileNameOnServer:=(PostParams.Values['FileNameOnServer']);
   idUserString:=TNetEncoding.URL.Decode(PostParams.Values['AidUsersString']);

   FileNameOnServer:=TNetEncoding.URL.Decode(FileNameOnServer);


   //CreateUniqueFileName if needed
    NamesInDirSDA:=TDirectory.GetFiles(AppPath+dir);
    NamesInDirSL:=TStringList.Create;

    for i := 0 to High(NamesInDirSDA) do
    NamesInDirSL.Add(
    ExtractFileName(NamesInDirSDA[i])
    );

    UniqueFileNameOnServer:=
    TCreateUniqueNameServer.CreateUniqueNameAddingNumber(NamesInDirSL,FileNameOnServer);

    Outputfilepath:=AppPath+dir+'/'+UniqueFileNameOnServer;


              // check length of the string
          if Outputfilepath.Length>255 then
          begin

          //try to shorten
          difference:=Outputfilepath.Length-255+5; // for example 20 symbols


              if (difference>0) and (UniqueFileNameOnServer.Length>Difference) then begin

              StringWithoutExtension:=TCreateUniqueNameServer.GetStringWithoutExtension(UniqueFileNameOnServer,Extension);

              StringWithoutExtension:=StringWithoutExtension.Substring(0,StringWithoutExtension.Length-difference);

              UniqueFileNameOnServer:=
                  TCreateUniqueNameServer.CreateUniqueNameAddingNumber(NamesInDirSL,StringWithoutExtension+'.'+Extension);

              //Outputfilepath:=AppServerPath+AOutputDir+'\'+UniqueFileNameOnServer;

              end;

          end;



       try


           if IsAuthorizationOk(PostParams) then
           begin

               if FileNameOnServer<>'' then

                 DecodePostRequest.ReceiveFile(AContext,ARequestInfo,AResponseInfo,dir,UniqueFileNameOnServer)
               else
                 DecodePostRequest.ReceiveFile(AContext,ARequestInfo,AResponseInfo,dir);


                 AddFileToDB(dir,UniqueFileNameOnServer,idUserString.ToInteger);

            {
                 // Save in DataBase

             RelFilePath:=dir+'\'+UniqueFileNameOnServer;

              with fHTTPServer_UnitVar.AddFoldersAndFilesToDB do begin

                // Writing Folders to DB
                GetFoldersFromRelDir(dir,AbsDirs,RelDirs);
                AddFoldersToDB(AbsDirs,RelDirs,idParentForFile,idUserString.ToInteger());
                GetInfoAboutFile(RelFilePath,FileNameToInsert,fileSize,AbsPath);

                RelFilePath:=StringReplace(RelFilePath,'\','/',[rfReplaceAll]);
                RelFilePath:='/'+RelFilePath;

                    InsertFolderOrFileToDB(

                      False,// is folder
                      idParentForFile,
                      UniqueFileNameOnServer,

                      idUserString.ToInteger(),
                      fileSize,
                      RelFilePath,
                      AbsPath

                      );

              // Save in DataBase
              end;

           }



             AResponseInfo.ContentText := 'ok';
             AResponseInfo.WriteContent;

           end;



       except

       on E:Exception do

       begin
       AResponseInfo.ContentText := 'Error during receiving file without log '+E.Message;
       AResponseInfo.WriteContent;
       raise Exception.Create('Error during receiving file without log');
       end;




   end;



   finally


   //Free
   FreeAndNil(DecodePostRequest);
   FreeAndNil(PostParams);
   FreeAndNil(NamesInDirSL);

   FreeAndNil(AbsDirs);
   FreeAndNil(RelDirs);

   end;


end;


procedure THTTPServerCommandGet.AddFileToDB(ARelativeDir:string; AFileName:string; AidUser:Integer);
var
  RelFilePath: String;
  AbsDirs: TStringList;
  RelDirs: TStringList;
  idParentForFile: integer;
  FileNameToInsert: String;
  AbsPath: String;
  fileSize:Int64;
begin
//

try
AbsDirs:=TStringList.Create;
RelDirs:=TStringList.Create;


                 // Save in DataBase

             RelFilePath:=ARelativeDir+'\'+AFileName;

              with fHTTPServer_UnitVar.AddFoldersAndFilesToDB do begin

                // Writing Folders to DB
                GetFoldersFromRelDir(RelFilePath,AbsDirs,RelDirs);
                AddFoldersToDB(AbsDirs,RelDirs,idParentForFile,AidUser);
                GetInfoAboutFile(RelFilePath,FileNameToInsert,fileSize,AbsPath);

                RelFilePath:=StringReplace(RelFilePath,'\','/',[rfReplaceAll]);
                RelFilePath:='/'+RelFilePath;

                    InsertFolderOrFileToDB(

                      False,// is folder
                      idParentForFile,
                      AFileName,

                      AidUser,
                      fileSize,
                      RelFilePath,
                      AbsPath

                      );

              // Save in DataBase
              end;




finally

FreeAndNil(AbsDirs);
FreeAndNil(RelDirs);


end;





end;



{Receiving one file on Server}
procedure THTTPServerCommandGet.ReceiveFileAndChangeName(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
  AResponseInfo: TIdHTTPResponseInfo);

  var PostParams:TStringList;
      DecodePostRequest: TDecodePostRequest;
      dir:string;


      FS:TFileStream;

      AppPath:string;
      logFilePath: string;



       iCounterPerSec: TLargeInteger;
       C1, C2: TLargeInteger;
       ContentSL:TStringList;

       FileNameOnServer:string;

begin

//
  QueryPerformanceFrequency(iCounterPerSec);
  QueryPerformanceCounter(C1);

//Create
PostParams:=TStringList.Create;
DecodePostRequest:=TDecodePostRequest.Create(fHTTPServer_UnitVar);
ContentSL:=TStringList.Create;

AppPath:=ExtractFilePath(Application.ExeName);





   try

   //Main work
   PostParams.Clear;
   DecodePostRequest.DecodePostParamsAnsi(AContext,ARequestInfo,AResponseInfo,PostParams);

   dir:=PostParams.Values['dirOnServer']; // dir appears from params
   FileNameOnServer:=PostParams.Values['FileNameOnServer'];

   logFilePath:=AppPath+dir+'daylogServer.txt';


   if IsAuthorizationOk(PostParams) then
   DecodePostRequest.ReceiveFile(AContext,ARequestInfo,AResponseInfo,dir,FileNameOnServer);

     AResponseInfo.ContentText := 'ok';
     AResponseInfo.WriteContent;


          //Saving to log

        if TFile.Exists(logFilePath) then
        ContentSL.LoadFromFile(logFilePath);
        QueryPerformanceCounter(C2);

      ContentSL.add(
      'ReceiveFile (Chunk) = '+FormatFloat('0.0000', (C2 - C1) / iCounterPerSec) + ' sec.'
             );
      ContentSL.SaveToFile(logFilePath);



   finally


   //Free
   FreeAndNil(DecodePostRequest);
   FreeAndNil(PostParams);
   FreeAndNil(ContentSL);
   end;


end;







procedure THTTPServerCommandGet.GatherFileFromChunks(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
  AResponseInfo: TIdHTTPResponseInfo);

  var PostParams:TStringList;
      DecodePostRequest: TDecodePostRequest;
      dir:string;
      DivideAndGatherFileServer:TDivideAndGatherFileServer;


      ChunksDir: string;
      OutPutDir: string;
      OutPutFileName: string;
      ResponseInfo:string;
      idUserString:string;


      FS:TFileStream;

      AppPath:string;
      logFilePath: string;

       iCounterPerSec: TLargeInteger;
       C1, C2: TLargeInteger;
       ContentSL:TStringList;
  RelFilePath: string;


begin

//
  QueryPerformanceFrequency(iCounterPerSec);
  QueryPerformanceCounter(C1);

//Create
PostParams:=TStringList.Create;
DecodePostRequest:=TDecodePostRequest.Create(fHTTPServer_UnitVar);
DivideAndGatherFileServer:=TDivideAndGatherFileServer.Create(Self);

ContentSL:=TStringList.Create;
AppPath:=ExtractFilePath(Application.ExeName);



   try

   //Main work
   PostParams.Clear;
   DecodePostRequest.DecodePostParamsAnsi(AContext,ARequestInfo,AResponseInfo,PostParams);


   if IsAuthorizationOk(PostParams) then
    begin


       ChunksDir:=PostParams.Values['AChunksDir'];
       OutPutDir:=PostParams.Values['AOutPutDir'];
       OutPutFileName:=TNetEncoding.URL.Decode( PostParams.Values['AOutPutFileName'] );
       idUserString:=PostParams.Values['AidUserString'];

       logFilePath:=AppPath+ChunksDir+'UploadlogServer.txt';

       DivideAndGatherFileServer.GatherFileFromChunks(ChunksDir,OutPutDir,OutPutFileName);





       AddFileToDB(OutPutDir,OutPutFileName,idUserString.ToInteger);

     {
             // Save in DataBase

             RelFilePath:=OutPutDir+'\'+UniqueFileNameOnServer;

              with fHTTPServer_UnitVar.AddFoldersAndFilesToDB do begin

                // Writing Folders to DB
                GetFoldersFromRelDir(OutPutDir,AbsDirs,RelDirs);
                AddFoldersToDB(AbsDirs,RelDirs,idParentForFile,idUserString.ToInteger());
                GetInfoAboutFile(RelFilePath,FileNameToInsert,fileSize,AbsPath);

                RelFilePath:=StringReplace(RelFilePath,'\','/',[rfReplaceAll]);
                RelFilePath:='/'+RelFilePath;

                    InsertFolderOrFileToDB(

                      False,// is folder
                      idParentForFile,
                      UniqueFileNameOnServer,

                      idUserString.ToInteger(),
                      fileSize,
                      RelFilePath,
                      AbsPath

                      );

              // Save in DataBase
              end;

    }










       AResponseInfo.ContentText:='ok';
       AResponseInfo.WriteContent;


                //Saving to log

        if TFile.Exists(logFilePath) then ContentSL.LoadFromFile(logFilePath);
        QueryPerformanceCounter(C2);

      ContentSL.add(
      'GatherFileFromChunks = '+FormatFloat('0.0000', (C2 - C1) / iCounterPerSec) + ' sec.'
             );
      ContentSL.SaveToFile(logFilePath);


     end;


   finally


   //Free
   FreeAndNil(DecodePostRequest);
   FreeAndNil(PostParams);
   FreeAndNil(DivideAndGatherFileServer);
   FreeAndNil(ContentSL);
   end;


end;





procedure THTTPServerCommandGet.SendFile2Keep2Share(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
  AResponseInfo: TIdHTTPResponseInfo);

  var PostParams:TStringList;
      DecodePostRequest: TDecodePostRequest;
      dir:string;
      DivideAndGatherFileServer:TDivideAndGatherFileServer;


      dirOnServer: string;
      FileNameOnServer: string;

      ResponseInfo:string;



      FS:TFileStream;

      AppPath:string;
      logFilePath: string;

       iCounterPerSec: TLargeInteger;
       C1, C2: TLargeInteger;
       ContentSL:TStringList;
       Filepath:string;
       RealativePathForPHPScript:string;

       ServerResponse:string;

       idHTTPLocal:TIdHTTP;

begin

idHTTPLocal:=TIdHTTP.Create(Self);

//
  QueryPerformanceFrequency(iCounterPerSec);
  QueryPerformanceCounter(C1);

//Create
PostParams:=TStringList.Create;
DecodePostRequest:=TDecodePostRequest.Create(fHTTPServer_UnitVar);

AppPath:=ExtractFilePath(Application.ExeName);



   try

   //Main work
   PostParams.Clear;
   DecodePostRequest.DecodePostParamsAnsi(AContext,ARequestInfo,AResponseInfo,PostParams);


   if IsAuthorizationOk(PostParams) then
    begin


       dirOnServer:=PostParams.Values['dirOnServer'];
       FileNameOnServer:=PostParams.Values['FileNameOnServer'];

       //SendRequest to Keep2Share
//       ShowMessage('dirOnServer='+dirOnServer+#13#10+'FileNameOnServer='+FileNameOnServer);
//       ShowMessage('FileNameOnServer='+FileNameOnServer);



      Filepath:=AppPAth+dirOnServer+'\'+FileNameOnServer;

      RealativePathForPHPScript:=dirOnServer+'\'+FileNameOnServer;

     // preparing filepath for php script
     RealativePathForPHPScript:=
     StringReplace(RealativePathForPHPScript,'\','/',[rfReplaceAll]);
//     ShowMessage(RealativePathForPHPScript);

     //PostParams.Add('filepath=license.txt');

     PostParams.Add('filepath='+RealativePathForPHPScript);

    // fHTTPServer_UnitVar.MemoTest.Lines.Add(RealativePathForPHPScript);



     ServerResponse:=
//     fHTTPServer_UnitVar.IdHTTP.Post( 'http://panteleevstas.ru/Keep2Share_Upload.php',PostParams);
       IdHTTPLocal.Post( 'http://panteleevstas.ru/Keep2Share_Upload.php',PostParams);

     fHTTPServer_UnitVar.MemoTest.Lines.Add(ServerResponse);


       AResponseInfo.ContentText:=ServerResponse;//'ok';
       AResponseInfo.WriteContent;



     {
                //Saving to log

        if TFile.Exists(logFilePath) then ContentSL.LoadFromFile(logFilePath);
        QueryPerformanceCounter(C2);

      ContentSL.add(
      'GatherFileFromChunks = '+FormatFloat('0.0000', (C2 - C1) / iCounterPerSec) + ' sec.'
             );
      ContentSL.SaveToFile(logFilePath);
     }

     end;


   finally


   //Free

   // in any case deleting file
   TFile.Delete(Filepath);

   FreeAndNil(DecodePostRequest);
   FreeAndNil(PostParams);
   FreeAndNil(idHTTPLocal);
   end;


end;






procedure THTTPServerCommandGet.CheckChunksIntegrity(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
  AResponseInfo: TIdHTTPResponseInfo);

  var PostParams:TStringList;
      DecodePostRequest: TDecodePostRequest;


      dirOnServer: string;
      OutPutDir: string;
      OutPutFileName: string;
  AppPath: string;
  ChunksInfoFileName: string;
  JSONObject:TJSONObject;
  JsonString: string;
  i: Integer;

  ChunksToBeUploaded:TStringList;

begin

//Create
PostParams:=TStringList.Create;
DecodePostRequest:=TDecodePostRequest.Create(fHTTPServer_UnitVar);
ChunksToBeUploaded:=TStringList.Create;


   try

   //Main work
   PostParams.Clear;
   DecodePostRequest.DecodePostParamsAnsi(AContext,ARequestInfo,AResponseInfo,PostParams);


   if IsAuthorizationOk(PostParams) then
    begin

     dirOnServer:=PostParams.Values['dirOnServer'];
     dirOnServer:=TNetEncoding.URL.Decode(dirOnServer);

     ChunksInfoFileName:=PostParams.Values['ChunksInfoFileName'];

     //-----------1 working with ChunksInfo.txt

     AppPath:=ExtractFilePath(Application.ExeName);

     if TFile.Exists(AppPath+dirOnServer+ChunksInfoFileName) then
      begin

        JsonString:=TFile.ReadAllText(AppPath+dirOnServer+ChunksInfoFileName);

        // Reading json file here

      //  JSONObject:=TJSONObject.Create;
        JSONObject:=TJSONObject.ParseJSONValue(JsonString) as TJSONObject;

        for i := 0 to JSONObject.Count-1  do begin

          if JSONObject.Pairs[i].JsonString.Value.Contains('{chunk=') then
          ChunksToBeUploaded.Add(JSONObject.Pairs[i].JsonString.Value);


        end;

        FreeAndNil(JSONObject);

        //Checking if all files uploaded in that dir



        for i := 0 to ChunksToBeUploaded.Count-1 do
          begin

          if not TFile.Exists(AppPath+dirOnServer+ChunksToBeUploaded[i]) then

           begin

           AResponseInfo.ContentText:='not ok. File '+AppPath+dirOnServer+ChunksToBeUploaded[i]+' not on Server';
           AResponseInfo.WriteContent;

           raise Exception.Create('Error Message');


           end;

          end;


        AResponseInfo.ContentText:='ok'; // on every check we think that all ok
        AResponseInfo.WriteContent;


      end else

      AResponseInfo.ContentText:='not ok. File '+AppPath+dirOnServer+ChunksInfoFileName+' not on Server';
      AResponseInfo.WriteContent;

     end;


   finally


   //Free
   FreeAndNil(DecodePostRequest);
   FreeAndNil(PostParams);
   FreeAndNil(ChunksToBeUploaded);
   end;


end;




procedure THTTPServerCommandGet.IsFileOnServer(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
  AResponseInfo: TIdHTTPResponseInfo);

  var PostParams:TStringList;
      DecodePostRequest: TDecodePostRequest;



  AppPath: string;
  FileName: string;
  dirOnServer: string;
  AbsRootDir: string;
  SDAResult: TStringDynArray;
  SplittedString: TArray<String>;
  idUserString: string;
  RelDir:string;

begin

//Create
PostParams:=TStringList.Create;
DecodePostRequest:=TDecodePostRequest.Create(fHTTPServer_UnitVar);



   try

   //Main work
   PostParams.Clear;
   DecodePostRequest.DecodePostParamsAnsi(AContext,ARequestInfo,AResponseInfo,PostParams);


   if IsAuthorizationOk(PostParams) then
    begin

     dirOnServer:=PostParams.Values['dirOnServer'];
     FileName:=PostParams.Values['FileName'];
     FileName:=TNetEncoding.URL.Decode(FileName);

     idUserString:=PostParams.Values['idUser'];

     SplittedString:=dirOnServer.Split(['\']);



        AResponseInfo.ContentText:='ok'; // on every check we think that all ok
        AResponseInfo.WriteContent;


     //-----------Checking if File on Server

     AppPath:=ExtractFilePath(Application.ExeName);
     AbsRootDir:=AppPath+SplittedString[0];

     if TFile.Exists(AppPath+dirOnServer+'\'+FileName) then
      begin

      AResponseInfo.ContentText:='ok';
      AResponseInfo.WriteContent;

                        {
                      //Synchronizing with DataBase
                             // Example of dir that we give to following funciton
                //C:\DELPHI\MyStudyProjects\373_PS_HTTPClient_Dev\HTTPServer\Win32\Debug\public

                           fHTTPServer_UnitVar.DataBaseUnitServer.SynchronizeDirWithDataBase(
                           AbsRootDir,
                           RelDir,
                           SDAResult,
                           -1,
                           idUserString.ToInteger()
                           );
                        }

      end else

      AResponseInfo.ContentText:='not ok. File '+AppPath+dirOnServer+'\'+FileName+' not on Server';
      AResponseInfo.WriteContent;

     end;


   finally


   //Free
   FreeAndNil(DecodePostRequest);
   FreeAndNil(PostParams);
   end;


end;






procedure THTTPServerCommandGet.AddFileToDBResponse(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
  AResponseInfo: TIdHTTPResponseInfo);

  var PostParams:TStringList;
      DecodePostRequest: TDecodePostRequest;

      ReldirOnServer:String;
      RelFilePath:String;



      FileName:String;
      AppPath:String;
      idUserString:string;

      AbsDirs:TStringList;
      RelDirs:TStringList;

      AbsPath:String;

      idParentForFile:Integer;
      FileNameToInsert:String;
      fileSize:Int64;


begin

  //Create
  PostParams:=TStringList.Create;
  DecodePostRequest:=TDecodePostRequest.Create(fHTTPServer_UnitVar);


      AbsDirs:=TStringList.Create;
      RelDirs:=TStringList.Create;



   try



         //Main work
         PostParams.Clear;
         DecodePostRequest.DecodePostParamsAnsi(AContext,ARequestInfo,AResponseInfo,PostParams);


         if IsAuthorizationOk(PostParams) then
          begin

           // Getting Post Params
           ReldirOnServer:=TNetEncoding.URL.Decode( PostParams.Values['AdirOnServer'] );
           FileName:=TNetEncoding.URL.Decode (PostParams.Values['AFileName']);
           idUserString:=TNetEncoding.URL.Decode(PostParams.Values['AidUsersString']);


           RelFilePath:=ReldirOnServer+'\'+FileName;

           // Writing Folders to DB

              with fHTTPServer_UnitVar.AddFoldersAndFilesToDB do begin

                GetFoldersFromRelDir(ReldirOnServer,AbsDirs,RelDirs);
                AddFoldersToDB(AbsDirs,RelDirs,idParentForFile,idUserString.ToInteger());
                GetInfoAboutFile(RelFilePath,FileNameToInsert,fileSize,AbsPath);

                RelFilePath:=StringReplace(RelFilePath,'\','/',[rfReplaceAll]);
                RelFilePath:='/'+RelFilePath;

                    InsertFolderOrFileToDB(

                      False,// is folder
                      idParentForFile,
                      FileName,

                      idUserString.ToInteger(),
                      fileSize,
                      RelFilePath,
                      AbsPath

                      );


                AResponseInfo.ContentText:='ok';
                AResponseInfo.WriteContent;


              end;



          end;




   finally


   //Free
   FreeAndNil(DecodePostRequest);
   FreeAndNil(PostParams);


      AbsDirs.Free;
      RelDirs.Free;



   end;


end;






procedure THTTPServerCommandGet.ReceiveChunksInfo(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
  AResponseInfo: TIdHTTPResponseInfo; var ChunksInfoString:string);

  var PostParams:TStringList;
      DecodePostRequest: TDecodePostRequest;
      dir:string;
      dirOnServer: string;
      ChunksInfoSL:TStringList;

       iCounterPerSec: TLargeInteger;
       C1, C2: TLargeInteger;

      ContentSL:TStringList;

       FS:TFileStream;

       AppPath:string;
       logFilePath: string;


begin

//Create
PostParams:=TStringList.Create;
DecodePostRequest:=TDecodePostRequest.Create(fHTTPServer_UnitVar);
ChunksInfoSL:=TStringList.Create;
ContentSL:=TStringList.Create;



AppPath:=ExtractFilePath(Application.ExeName);

//
  QueryPerformanceFrequency(iCounterPerSec);
  QueryPerformanceCounter(C1);


   try

   //Main work
   PostParams.Clear;
   DecodePostRequest.DecodePostParamsAnsi(AContext,ARequestInfo,AResponseInfo,PostParams);


   if IsAuthorizationOk(PostParams) then

     begin

     dirOnServer:=PostParams.Values['AchunksDirOnServer'];

     logFilePath:=AppPath+dirOnServer+'UploadlogServer.txt';


     //Creating dir

     if not TDirectory.Exists(AppPath+dirOnServer) then
     TDirectory.CreateDirectory(AppPath+dirOnServer);


     //Creating log file
     if not TFile.Exists(logFilePath) then


      FS:=TFile.Create(logFilePath)
      else ContentSL.LoadFromFile(logFilePath);
      FreeAndNil(FS);


     DecodePostRequest.ReceiveFile(AContext,ARequestInfo,AResponseInfo,dirOnServer); // Error Handling Ok

     AResponseInfo.ContentText := 'ok';
     AResponseInfo.WriteContent;


        //Saving to log

        if TFile.Exists(logFilePath) then
        ContentSL.LoadFromFile(logFilePath);
        QueryPerformanceCounter(C2);

      ContentSL.Add('                             ');
      ContentSL.Add('---ServerSide---');

      ContentSL.Add(
      'ReceiveChunksInfo = '+FormatFloat('0.0000', (C2 - C1) / iCounterPerSec) + ' sec.'
       );
      ContentSL.SaveToFile(logFilePath);



     end;


   finally


   //Free
   FreeAndNil(DecodePostRequest);
   FreeAndNil(PostParams);
   FreeAndNil(ChunksInfoSL);







   FreeAndNil(ContentSL); // must be here

   end;





end;



{CreateDirOnServer}
procedure THTTPServerCommandGet.CreateDirOnServer(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
  AResponseInfo: TIdHTTPResponseInfo);

  var PostParams:TStringList;
      DecodePostRequest: TDecodePostRequest;
      AbsoluteDir:string;
  ErrorMessage: string;
  RelativeDir: string;
  CuttedRelativeDir:string;
  SplittedString: TArray<String>;
  SDAResult:TStringDynArray;
  AbsRootDir:string;

begin

//Create
PostParams:=TStringList.Create;
DecodePostRequest:=TDecodePostRequest.Create(fHTTPServer_UnitVar);

   try

   //Main work
   PostParams.Clear;
   DecodePostRequest.DecodePostParamsAnsi(AContext,ARequestInfo,AResponseInfo,PostParams);

   if IsAuthorizationOk(PostParams) then begin


    // Preparing dir to Create
     AbsoluteDir:= ExtractFileDir(Application.ExeName);
     AbsoluteDir:=AbsoluteDir+'\'+TNetEncoding.URL.Decode(PostParams.Values['DirectoryToCreate']);

     RelativeDir:=TNetEncoding.URL.Decode(PostParams.Values['DirectoryToCreate']);

     SplittedString:=RelativeDir.Split(['\']);
     CuttedRelativeDir:=SplittedString[0];

     AbsRootDir:=ExtractFileDir(Application.ExeName)+'\'+CuttedRelativeDir;

      if Length(AbsoluteDir)>MAX_PATH then // 255 or 260

      begin


         ErrorMessage:='dir '+AbsoluteDir+' too long - try shorten it';

         AResponseInfo.ContentText:=ErrorMessage;

         AResponseInfo.WriteContent;

         raise Exception.Create(ErrorMessage);


         
      end;








          try

               //Creating dir
             if not TDirectory.Exists(AbsoluteDir) then  TDirectory.CreateDirectory(AbsoluteDir);

             //Writing to DataBase Relative dir

             // Example of dir that we give to following funciton
//C:\DELPHI\MyStudyProjects\373_PS_HTTPClient_Dev\HTTPServer\Win32\Debug\public
           //  FDataBaseUnitServer.WriteDirToDataBase(RelativeDir);
{
           FDataBaseUnitServer.SynchronizeDirWithDataBase(
           AbsRootDir,
           SDAResult,
           -1
           );
}
        except

            on E:Exception do begin

            AResponseInfo.ContentText:='Server Error '+'Class='+E.ClassName+
            ' / Message='+E.Message;//   'testing ok';
            AResponseInfo.WriteContent;

            raise Exception.Create('Server Error '+'Class='+E.ClassName+
            ' / Message='+E.Message);

            end;


        //AResponseInfo.ContentText:='testing ok2';
        //AResponseInfo.WriteContent; // this will not show testing ok2!

        end;



        AResponseInfo.ContentText:='ok';
        AResponseInfo.WriteContent;


   end;


   finally


   //Free
   FreeAndNil(DecodePostRequest);
   FreeAndNil(PostParams);

   end;





end;


//-----------------------------------------------------------

{DeleteDirOnServer}
procedure THTTPServerCommandGet.DeleteDirOnServer(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
  AResponseInfo: TIdHTTPResponseInfo);

  var PostParams:TStringList;
      DecodePostRequest: TDecodePostRequest;
      dir:string;

begin

//Create
PostParams:=TStringList.Create;
DecodePostRequest:=TDecodePostRequest.Create(fHTTPServer_UnitVar);

   try

   //Main work
   PostParams.Clear;
   DecodePostRequest.DecodePostParamsAnsi(AContext,ARequestInfo,AResponseInfo,PostParams);

   if IsAuthorizationOk(PostParams) then begin


    // Preparing dir to Create
     dir:= ExtractFileDir(Application.ExeName);
     dir:=dir+'\'+PostParams.Values['DirectoryToDelete'];

//     try


         try
         if TDirectory.Exists(dir) then TDirectory.Delete(dir,true);
         except

         on E:Exception do
            begin

              raise Exception.Create(' Exception Raised = '+'Class='+E.ClassName
                    +#13#1+#13#10+'  Message='+E.Message);


                       AResponseInfo.ContentText := E.Message;
                       AResponseInfo.WriteContent;
            end;
            
         
         end;
         

         AResponseInfo.ContentText:='ok';
         AResponseInfo.WriteContent;


   end;


   finally


   //Free
   FreeAndNil(DecodePostRequest);
   FreeAndNil(PostParams);

   end;





end;



procedure THTTPServerCommandGet.DeleteFileOnServer(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
  AResponseInfo: TIdHTTPResponseInfo);

  var PostParams:TStringList;
      DecodePostRequest: TDecodePostRequest;
      Filepath:string;
      AppPath:string;

begin

//Create
PostParams:=TStringList.Create;
DecodePostRequest:=TDecodePostRequest.Create(fHTTPServer_UnitVar);

   try

   //Main work
   PostParams.Clear;
   DecodePostRequest.DecodePostParamsAnsi(AContext,ARequestInfo,AResponseInfo,PostParams);

   if IsAuthorizationOk(PostParams) then begin


    // Preparing dir to Create
     AppPath:= ExtractFileDir(Application.ExeName);
     Filepath:=AppPath+'\'+PostParams.Values['Filepath'];

//     try


         try

         if TFile.Exists(Filepath) then TFile.Delete(Filepath);


         except

         on E:Exception do
            begin

              raise Exception.Create(' Exception Raised = '+'Class='+E.ClassName
                    +#13#1+#13#10+'  Message='+E.Message);


                       AResponseInfo.ContentText := E.Message;
                       AResponseInfo.WriteContent;
            end;


         end;


         AResponseInfo.ContentText:='ok';
         AResponseInfo.WriteContent;


   end;


   finally


   //Free
   FreeAndNil(DecodePostRequest);
   FreeAndNil(PostParams);

   end;



end;





procedure THTTPServerCommandGet.DeleteFoldersAndFilesOnServerWithDataBase(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
  AResponseInfo: TIdHTTPResponseInfo);

  var PostParams:TStringList;
      DecodePostRequest: TDecodePostRequest;

      AIDValuesJSONString:string;
      JSONObjectAfter:TJSONObject;

      IDListToDelete:TStringList;
  i: Integer;
  NewValue: string;

begin

 // to change it

//Create
PostParams:=TStringList.Create;
DecodePostRequest:=TDecodePostRequest.Create(fHTTPServer_UnitVar);
IDListToDelete:=TStringList.Create;

   try

   //Main work
   PostParams.Clear;
   DecodePostRequest.DecodePostParamsAnsi(AContext,ARequestInfo,AResponseInfo,PostParams);

   if IsAuthorizationOk(PostParams) then begin



     AIDValuesJSONString:=PostParams.Values['AIDValuesJSONString'];

     JSONObjectAfter:=TJSONObject.ParseJSONValue(AIDValuesJSONString) as TJSONObject;


   //  encodedFilename:=TNetEncoding.URL.Encode(filename);



//     try


         try

         // do something here...

         for i := 0 to JSONObjectAfter.Count-1  do
          begin

           NewValue:=JSONObjectAfter.Pairs[i].JsonValue.ToString;

           NewValue:=StringReplace(NewValue,'"','',[rfReplaceAll]); // Excluding " sign

           IDListToDelete.Add( NewValue );

          end;


         // deleting Elements
         fHTTPServer_UnitVar.DeleteServer.Delete(IDListToDelete);


         except

         on E:Exception do
            begin

              raise Exception.Create(' Exception Raised = '+'Class='+E.ClassName
                    +#13#1+#13#10+'  Message='+E.Message);


                       AResponseInfo.ContentText := E.Message;
                       AResponseInfo.WriteContent;
            end;


         end;


         AResponseInfo.ContentText:='ok';
         AResponseInfo.WriteContent;


   end;


   finally


   //Free
   FreeAndNil(DecodePostRequest);
   FreeAndNil(PostParams);
   FreeAndNil(IDListToDelete);
   FreeAndNil(JSONObjectAfter);

   end;



end;




procedure THTTPServerCommandGet.DeleteTempFileOnServer(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
  AResponseInfo: TIdHTTPResponseInfo);

  var PostParams:TStringList;
      DecodePostRequest: TDecodePostRequest;
      Filepath:string;
      AppPath:string;
  dir: string;
  filename: string;
  encodedFilename: string;

begin

//Create
PostParams:=TStringList.Create;
DecodePostRequest:=TDecodePostRequest.Create(fHTTPServer_UnitVar);

   try

   //Main work
   PostParams.Clear;
   DecodePostRequest.DecodePostParamsAnsi(AContext,ARequestInfo,AResponseInfo,PostParams);

   if IsAuthorizationOk(PostParams) then begin


    // Preparing dir to Create
     AppPath:= ExtractFilePath(Application.ExeName);
     dir:=PostParams.Values['dir'];
     filename:=PostParams.Values['filename'];

   //  encodedFilename:=TNetEncoding.URL.Encode(filename);

     Filepath:=AppPath+dir+filename+'_UploadlogServer.txt';

//     try


         try

         if TFile.Exists(Filepath) then TFile.Delete(Filepath);


         except

         on E:Exception do
            begin

              raise Exception.Create(' Exception Raised = '+'Class='+E.ClassName
                    +#13#1+#13#10+'  Message='+E.Message);


                       AResponseInfo.ContentText := E.Message;
                       AResponseInfo.WriteContent;
            end;


         end;


         AResponseInfo.ContentText:='ok';
         AResponseInfo.WriteContent;


   end;


   finally


   //Free
   FreeAndNil(DecodePostRequest);
   FreeAndNil(PostParams);

   end;



end;




end.
