Skip to content

Instantly share code, notes, and snippets.

@corneliusdavid
Last active May 11, 2022 04:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save corneliusdavid/29ccaa18325ba0cdbb56cef9adf72184 to your computer and use it in GitHub Desktop.
Save corneliusdavid/29ccaa18325ba0cdbb56cef9adf72184 to your computer and use it in GitHub Desktop.
Delphi procedure to report application usage by building a parameterized URL and calling a remote PHP script that updates a MySQL database.
procedure ReportAppUsage;
{ send a bunch of information out to a PHP script to remotely log application usage }
function EncodeURIComponent(const ASrc: string): UTF8String;
{ from excellent blog: https://marc.durdin.net/2012/07/indy-tiduri-pathencode-urlencode-and-paramsencode-and-more/ }
const
HexMap: UTF8String = '0123456789ABCDEF';
function IsSafeChar(ch: Integer): Boolean;
begin
if (ch >= 48) and (ch <= 57) then Result := True // 0-9
else if (ch >= 65) and (ch <= 90) then Result := True // A-Z
else if (ch >= 97) and (ch <= 122) then Result := True // a-z
else if (ch = 33) then Result := True // !
else if (ch >= 39) and (ch <= 42) then Result := True // '()*
else if (ch >= 45) and (ch <= 46) then Result := True // -.
else if (ch = 95) then Result := True // _
else if (ch = 126) then Result := True // ~
else Result := False;
end;
var
I, J: Integer;
ASrcUTF8: UTF8String;
begin
Result := ''; {Do not Localize}
ASrcUTF8 := UTF8Encode(ASrc);
// UTF8Encode call not strictly necessary but
// prevents implicit conversion warning
I := 1; J := 1;
SetLength(Result, Length(ASrcUTF8) * 3); // space to %xx encode every byte
while I <= Length(ASrcUTF8) do
begin
if IsSafeChar(Ord(ASrcUTF8[I])) then
begin
Result[J] := ASrcUTF8[I];
Inc(J);
end
else
begin
Result[J] := '%';
Result[J+1] := HexMap[(Ord(ASrcUTF8[I]) shr 4) + 1];
Result[J+2] := HexMap[(Ord(ASrcUTF8[I]) and 15) + 1];
Inc(J,3);
end;
Inc(I);
end;
SetLength(Result, J-1);
end;
function AddParam(const FirstParam: Boolean; const InfoID, InfoValue: string): string;
begin
Result := InfoID + '=' + EncodeURIComponent(InfoValue);
if FirstParam then
Result := '?' + Result
else
Result := '&' + Result;
end;
function AddDateTimeParam(const InfoID: string; const DTValue: TDateTime): string;
var
XSDateTime: TXSDateTime;
begin
XSDateTime := TXSDateTime.Create;
XSDateTime.AsDateTime := DTValue;
// assumes it's not the first parameter
Result := '&' + InfoID + '=' + XSDateTime.NativeToXS
end;
const
BASE_URL = 'https://MyWebsite.com/apprun/ApplicationUse.php';
YES_NO_STRS: array[Boolean] of string = ('NO', 'YES');
var
AppData: string;
IdHTTPAppLog: TIdHTTP;
IdSSLIOHandler: TIdSSLIOHandlerSocketOpenSSL;
begin
try
AppData :=
AddParam(True, 'CompName', AppCompanyName) +
AddParam(False, 'CompCity', AppCompanyCity) +
AddParam(False, 'CompState', AppCompanyCity) +
AddParam(False, 'AppVer', FloatToStrF(AppVersion, ffFixed, 8, 4)) +
AddParam(False, 'Activated', YES_NO_STRS[AppIsActivated]) +
AddDateTimeParam('AppExpiration', AppExpirationDate);
// add whatever other parameters you need to record; adjust PHP script and MySQL database appropriately
IdHTTPAppLog := TIdHTTP.Create;
IdSSLIOHandler := TIdSSLIOHandlerSocketOpenSSL.Create;
try
IdSSLIOHandler.SSLOptions.Method := sslvSSLv23;
IdSSLIOHandler.SSLOptions.Mode := sslmClient;
IdSSLIOHandler.SSLOptions.SSLVersions := [sslvTLSv1_1, sslvTLSv1_2];
IdHTTPAppLog.IOHandler := IdSSLIOHandler;
IdHTTPAppLog.HTTPOptions := [hoForceEncodeParams];
IdHTTPAppLog.Get(BASE_URL + AppData);
finally
IdHTTPAppLog.Free;
IdSSLIOHandler.Free;
end;
except
// ignore any possible errors
end;
end;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment