2013-10-30 00:48:23 +01:00
|
|
|
unit MVCFramework.Commons;
|
|
|
|
|
|
|
|
interface
|
|
|
|
|
|
|
|
uses
|
|
|
|
System.SysUtils,
|
|
|
|
Generics.Collections;
|
|
|
|
|
|
|
|
type
|
|
|
|
TMVCMimeType = class sealed
|
|
|
|
public const
|
|
|
|
APPLICATION_JSON = 'application/json';
|
|
|
|
TEXT_HTML = 'text/html';
|
|
|
|
TEXT_PLAIN = 'text/plain';
|
|
|
|
TEXT_XML = 'text/xml';
|
|
|
|
TEXT_CSS = 'text/css';
|
|
|
|
TEXT_JAVASCRIPT = 'text/javascript';
|
|
|
|
IMAGE_JPEG = 'image/jpeg';
|
|
|
|
IMAGE_PNG = 'image/x-png';
|
|
|
|
TEXT_CACHEMANIFEST = 'text/cache-manifest';
|
|
|
|
APPLICATION_OCTETSTREAM = 'application/octet-stream';
|
|
|
|
TEXT_EVENTSTREAM = 'text/event-stream';
|
|
|
|
end;
|
|
|
|
|
2014-04-04 16:39:37 +02:00
|
|
|
TMVCConstants = class sealed
|
|
|
|
public const
|
|
|
|
SESSION_TOKEN_NAME = 'dtsessionid';
|
2014-06-27 15:30:39 +02:00
|
|
|
DEFAULT_CONTENT_CHARSET = 'UTF-8';
|
2014-04-04 16:39:37 +02:00
|
|
|
DEFAULT_CONTENT_TYPE = TMVCMimeType.APPLICATION_JSON;
|
|
|
|
end;
|
|
|
|
|
2013-10-30 00:48:23 +01:00
|
|
|
EMVCException = class(Exception)
|
|
|
|
private
|
2013-11-08 23:10:25 +01:00
|
|
|
FHTTPErrorCode: UInt16;
|
2013-10-30 00:48:23 +01:00
|
|
|
FApplicationErrorCode: UInt16;
|
|
|
|
procedure SetDetailedMessage(const Value: string);
|
|
|
|
|
|
|
|
strict protected
|
|
|
|
FDetailedMessage: string;
|
|
|
|
|
|
|
|
public
|
2014-04-16 22:52:25 +02:00
|
|
|
constructor Create(const Msg: string); overload; virtual;
|
2013-10-30 00:48:23 +01:00
|
|
|
constructor Create(const Msg: string; const DetailedMessage: string;
|
2014-04-16 22:52:25 +02:00
|
|
|
const ApplicationErrorCode: UInt16; const HTTPErrorCode: UInt16 = 500);
|
|
|
|
overload; virtual;
|
2013-10-30 00:48:23 +01:00
|
|
|
constructor CreateFmt(const Msg: string; const Args: array of const);
|
|
|
|
property HTTPErrorCode: UInt16 read FHTTPErrorCode;
|
|
|
|
property DetailedMessage: string read FDetailedMessage
|
|
|
|
write SetDetailedMessage;
|
2014-04-16 22:52:25 +02:00
|
|
|
property ApplicationErrorCode: UInt16 read FApplicationErrorCode
|
|
|
|
write FApplicationErrorCode;
|
2013-10-30 00:48:23 +01:00
|
|
|
end;
|
|
|
|
|
|
|
|
EMVCSessionExpiredException = class(EMVCException)
|
|
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
EMVCConfigException = class(EMVCException)
|
|
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
EMVCFrameworkView = class(EMVCException)
|
|
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
TMVCRequestParamsTable = class(TDictionary<string, string>)
|
|
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
TMVCDataObjects = class(TObjectDictionary<string, TObject>)
|
|
|
|
constructor Create;
|
|
|
|
end;
|
|
|
|
|
|
|
|
TMVCConfig = class sealed
|
|
|
|
private
|
|
|
|
FConfig: TDictionary<string, string>;
|
|
|
|
function GetValue(AIndex: string): string;
|
|
|
|
procedure SetValue(AIndex: string; const Value: string);
|
|
|
|
|
|
|
|
public
|
|
|
|
constructor Create;
|
|
|
|
destructor Destroy; override;
|
|
|
|
property Value[AIndex: string]: string read GetValue
|
|
|
|
write SetValue; default;
|
|
|
|
function ToString: string; override;
|
2013-11-08 23:10:25 +01:00
|
|
|
procedure SaveToFile(const AFileName: String);
|
|
|
|
procedure LoadFromFile(const AFileName: String);
|
2013-10-30 00:48:23 +01:00
|
|
|
end;
|
|
|
|
|
2013-11-08 23:10:25 +01:00
|
|
|
{$SCOPEDENUMS ON}
|
|
|
|
|
2013-10-30 00:48:23 +01:00
|
|
|
type
|
|
|
|
THttpMethod = (GET, POST, PUT, DELETE, HEAD);
|
|
|
|
|
|
|
|
function AppPath: string;
|
|
|
|
function IsReservedOrPrivateIP(const IP: string): boolean;
|
|
|
|
function IP2Long(IP: string): UInt32;
|
|
|
|
|
2014-04-01 00:02:31 +02:00
|
|
|
var
|
|
|
|
Lock: TObject;
|
|
|
|
|
2013-10-30 00:48:23 +01:00
|
|
|
implementation
|
|
|
|
|
|
|
|
uses
|
|
|
|
System.IOUtils,
|
|
|
|
idGlobal,
|
2014-04-16 22:52:25 +02:00
|
|
|
System.StrUtils,
|
|
|
|
uGlobalVars
|
2014-09-05 12:47:40 +02:00
|
|
|
{$IF CompilerVersion < 27 }
|
2014-04-16 22:52:25 +02:00
|
|
|
, Data.DBXJSON
|
|
|
|
{$ELSE}
|
|
|
|
, System.JSON
|
|
|
|
{$IFEND};
|
2013-10-30 00:48:23 +01:00
|
|
|
|
|
|
|
const
|
2014-04-16 22:52:25 +02:00
|
|
|
ReservedIPs: array [1 .. 11] of array [1 .. 2] of string =
|
|
|
|
(('0.0.0.0', '0.255.255.255'), ('10.0.0.0', '10.255.255.255'),
|
|
|
|
('127.0.0.0', '127.255.255.255'), ('169.254.0.0', '169.254.255.255'),
|
|
|
|
('172.16.0.0', '172.31.255.255'), ('192.0.2.0', '192.0.2.255'),
|
|
|
|
('192.88.99.0', '192.88.99.255'), ('192.168.0.0', '192.168.255.255'),
|
|
|
|
('198.18.0.0', '198.19.255.255'), ('224.0.0.0', '239.255.255.255'),
|
|
|
|
('240.0.0.0', '255.255.255.255'));
|
2013-10-30 00:48:23 +01:00
|
|
|
|
|
|
|
function IP2Long(IP: string): UInt32;
|
|
|
|
begin
|
|
|
|
Result := idGlobal.IPv4ToDWord(IP);
|
|
|
|
end;
|
|
|
|
|
|
|
|
function IsReservedOrPrivateIP(const IP: string): boolean;
|
|
|
|
var
|
2013-11-08 23:10:25 +01:00
|
|
|
i: Integer;
|
2013-10-30 00:48:23 +01:00
|
|
|
IntIP: Cardinal;
|
|
|
|
begin
|
|
|
|
Result := False;
|
|
|
|
IntIP := IP2Long(IP);
|
|
|
|
for i := low(ReservedIPs) to high(ReservedIPs) do
|
|
|
|
begin
|
2014-04-16 22:52:25 +02:00
|
|
|
if (IntIP >= IP2Long(ReservedIPs[i][1])) and
|
|
|
|
(IntIP <= IP2Long(ReservedIPs[i][2])) then
|
2013-10-30 00:48:23 +01:00
|
|
|
begin
|
|
|
|
Exit(True)
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function AppPath: string;
|
|
|
|
begin
|
2014-04-16 22:52:25 +02:00
|
|
|
Result := gAppPath; // TPath.GetDirectoryName(GetModuleName(HInstance));
|
2013-10-30 00:48:23 +01:00
|
|
|
end;
|
|
|
|
|
|
|
|
{ TMVCDataObjects }
|
|
|
|
|
|
|
|
constructor TMVCDataObjects.Create;
|
|
|
|
begin
|
|
|
|
inherited Create([doOwnsValues]);
|
|
|
|
end;
|
|
|
|
|
|
|
|
{ TMVCConfig }
|
|
|
|
|
|
|
|
constructor TMVCConfig.Create;
|
|
|
|
begin
|
|
|
|
inherited;
|
|
|
|
FConfig := TDictionary<string, string>.Create;
|
|
|
|
end;
|
|
|
|
|
|
|
|
destructor TMVCConfig.Destroy;
|
|
|
|
begin
|
|
|
|
FConfig.Free;
|
|
|
|
inherited;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TMVCConfig.GetValue(AIndex: string): string;
|
|
|
|
begin
|
|
|
|
if FConfig.ContainsKey(AIndex) then
|
|
|
|
Result := FConfig.Items[AIndex]
|
|
|
|
else
|
|
|
|
raise EMVCConfigException.CreateFmt('Invalid config key [%s]', [AIndex]);
|
|
|
|
end;
|
|
|
|
|
2013-11-08 23:10:25 +01:00
|
|
|
procedure TMVCConfig.LoadFromFile(const AFileName: String);
|
|
|
|
var
|
|
|
|
S: string;
|
|
|
|
jobj: TJSONObject;
|
|
|
|
p: TJSONPair;
|
2014-04-16 22:52:25 +02:00
|
|
|
JSON: TJSONValue;
|
2013-11-08 23:10:25 +01:00
|
|
|
i: Integer;
|
|
|
|
begin
|
|
|
|
S := TFile.ReadAllText(AFileName);
|
2014-04-16 22:52:25 +02:00
|
|
|
JSON := TJSONObject.ParseJSONValue(S);
|
|
|
|
if Assigned(JSON) then
|
2013-11-08 23:10:25 +01:00
|
|
|
begin
|
2014-04-16 22:52:25 +02:00
|
|
|
if JSON is TJSONObject then
|
2013-11-08 23:10:25 +01:00
|
|
|
begin
|
2014-04-16 22:52:25 +02:00
|
|
|
jobj := TJSONObject(JSON);
|
2013-11-08 23:10:25 +01:00
|
|
|
for i := 0 to jobj.Size - 1 do
|
|
|
|
begin
|
|
|
|
p := jobj.GET(i);
|
|
|
|
FConfig.AddOrSetValue(p.JsonString.Value, p.JsonValue.Value);
|
|
|
|
end
|
|
|
|
end
|
|
|
|
else
|
2014-04-16 22:52:25 +02:00
|
|
|
raise EMVCConfigException.Create('DMVCFramework configuration file [' +
|
|
|
|
AFileName + '] does not contain a valid JSONObject');
|
2013-11-08 23:10:25 +01:00
|
|
|
end
|
|
|
|
else
|
2014-04-16 22:52:25 +02:00
|
|
|
raise EMVCConfigException.Create
|
|
|
|
('Cannot load DMVCFramework configuration file [' + AFileName + ']');
|
2013-11-08 23:10:25 +01:00
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TMVCConfig.SaveToFile(const AFileName: String);
|
|
|
|
begin
|
|
|
|
TFile.WriteAllText(AFileName, ToString, TEncoding.ASCII);
|
|
|
|
end;
|
|
|
|
|
2013-10-30 00:48:23 +01:00
|
|
|
procedure TMVCConfig.SetValue(AIndex: string; const Value: string);
|
|
|
|
begin
|
|
|
|
FConfig.AddOrSetValue(AIndex, Value);
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TMVCConfig.ToString: string;
|
|
|
|
var
|
|
|
|
k: string;
|
2014-04-16 22:52:25 +02:00
|
|
|
JSON: TJSONObject;
|
2013-10-30 00:48:23 +01:00
|
|
|
begin
|
2014-04-16 22:52:25 +02:00
|
|
|
JSON := TJSONObject.Create;
|
2013-11-08 23:10:25 +01:00
|
|
|
try
|
|
|
|
for k in FConfig.Keys do
|
2014-04-16 22:52:25 +02:00
|
|
|
JSON.AddPair(k, FConfig[k]);
|
|
|
|
Result := JSON.ToString;
|
2013-11-08 23:10:25 +01:00
|
|
|
finally
|
2014-04-16 22:52:25 +02:00
|
|
|
JSON.Free;
|
2013-10-30 00:48:23 +01:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
{ EMVCException }
|
|
|
|
|
|
|
|
constructor EMVCException.Create(const Msg: string);
|
|
|
|
begin
|
|
|
|
inherited Create(Msg);
|
|
|
|
FHTTPErrorCode := 500;
|
|
|
|
FDetailedMessage := 'N.A.';
|
|
|
|
FApplicationErrorCode := 0;
|
|
|
|
end;
|
|
|
|
|
|
|
|
constructor EMVCException.Create(const Msg, DetailedMessage: string;
|
2014-04-16 22:52:25 +02:00
|
|
|
const ApplicationErrorCode: UInt16; const HTTPErrorCode: UInt16);
|
2013-10-30 00:48:23 +01:00
|
|
|
begin
|
|
|
|
Create(Msg);
|
|
|
|
FHTTPErrorCode := HTTPErrorCode;
|
|
|
|
FApplicationErrorCode := ApplicationErrorCode;
|
|
|
|
FDetailedMessage := DetailedMessage;
|
|
|
|
end;
|
|
|
|
|
|
|
|
constructor EMVCException.CreateFmt(const Msg: string;
|
|
|
|
const Args: array of const);
|
|
|
|
begin
|
|
|
|
inherited;
|
|
|
|
FHTTPErrorCode := 500;
|
|
|
|
FDetailedMessage := 'N.A.';
|
|
|
|
FApplicationErrorCode := 0;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure EMVCException.SetDetailedMessage(const Value: string);
|
|
|
|
begin
|
|
|
|
FDetailedMessage := Value;
|
|
|
|
end;
|
|
|
|
|
2014-04-01 00:02:31 +02:00
|
|
|
initialization
|
|
|
|
|
|
|
|
Lock := TObject.Create;
|
|
|
|
|
|
|
|
finalization
|
|
|
|
|
|
|
|
FreeAndNil(Lock);
|
|
|
|
|
2013-10-30 00:48:23 +01:00
|
|
|
end.
|