mirror of
https://github.com/danieleteti/delphimvcframework.git
synced 2024-11-15 07:45:54 +01:00
JSON-RPC named parameters support
This commit is contained in:
parent
c9e3525b2a
commit
ddc5f4d97d
144
README.md
144
README.md
@ -278,17 +278,16 @@ end;
|
|||||||
>ObjectDict is the suggested way to renders data. However, the other ones are still there and works as usual.
|
>ObjectDict is the suggested way to renders data. However, the other ones are still there and works as usual.
|
||||||
|
|
||||||
- New! Added SQLGenerator and RQL compiler for PostgreSQL, SQLite and MSSQLServer (in addition to MySQL, MariaDB, Firebird and Interbase)
|
- New! Added SQLGenerator and RQL compiler for PostgreSQL, SQLite and MSSQLServer (in addition to MySQL, MariaDB, Firebird and Interbase)
|
||||||
- New! *MVCNameAs* attribute got the param `Fixed` (default: false). If Fixed is true, then the name is not processed by the `MVCNameCase` attribute assigned to the owner type.
|
- New! *MVCNameAs* attribute got the param `Fixed` (default: false). If `Fixed` is true, then the name is not processed by the `MVCNameCase` attribute assigned to the owner type.
|
||||||
- New! Added support for interfaces serialization - now it is possible to serialize Spring4D collections (thanks to [João Antônio Duarte](https://github.com/joaoduarte19))
|
- New! Added support for interfaces serialization - now it is possible to serialize Spring4D collections (thanks to [João Antônio Duarte](https://github.com/joaoduarte19))
|
||||||
- New! Added support for Spring4D Nullable Types - check (thanks to [João Antônio Duarte](https://github.com/joaoduarte19))
|
- New! Added support for Spring4D Nullable Types - check (thanks to [João Antônio Duarte](https://github.com/joaoduarte19))
|
||||||
- New! Added `OnRouterLog` event to log custom information for each request (thanks to [Andrea Ciotti](https://github.com/andreaciotti) for the first implementation and its PR)
|
- New! Added `OnRouterLog` event to log custom information for each request (thanks to [Andrea Ciotti](https://github.com/andreaciotti) for the first implementation and its PR)
|
||||||
- New! Optionally load system controllers (those who provide `/describeserver.info`, `/describeplatform.info` and `/serverconfig.info` system actions) setting `Config[TMVCConfigKey.LoadSystemControllers] := 'false';` in the configuration block.
|
- New! Optionally load system controllers (those who provide `/describeserver.info`, `/describeplatform.info` and `/serverconfig.info` system actions) setting `Config[TMVCConfigKey.LoadSystemControllers] := 'false';` in the configuration block.
|
||||||
- Added `TMVCJSONRPCExecutor.ConfigHTTPClient` to fully customize the inner `THTTPClient` (e.g. `ConnectionTimeout`, `ResponseTimeout` and so on)
|
|
||||||
- Improved! Now the router consider `Accept:*/*` compatible for every `MVCProduces` values
|
- Improved! Now the router consider `Accept:*/*` compatible for every `MVCProduces` values
|
||||||
- Improved! Greatly improved support for [HATEOAS](https://en.wikipedia.org/wiki/HATEOAS) in renders. Check `TRenderSampleController.GetPeople_AsObjectList_HATEOS` and all the others actions end with `HATEOS` in `renders.dproj` sample)
|
- Improved! Greatly improved support for [HATEOAS](https://en.wikipedia.org/wiki/HATEOAS) in renders. Check `TRenderSampleController.GetPeople_AsObjectList_HATEOS` and all the others actions end with `HATEOS` in `renders.dproj` sample)
|
||||||
|
|
||||||
```delphi
|
```delphi
|
||||||
//Now is really easy to add "_links" property automatically for each collection element while rendering
|
//Now is really easy to add "links" property automatically for each collection element while rendering
|
||||||
Render<TPerson>(People, True,
|
Render<TPerson>(People, True,
|
||||||
procedure(const APerson: TPerson; const Links: IMVCLinks)
|
procedure(const APerson: TPerson; const Links: IMVCLinks)
|
||||||
begin
|
begin
|
||||||
@ -369,24 +368,6 @@ end;
|
|||||||
|
|
||||||
- Improved! Exceptions rendering while using MIME types different to `application/json`.
|
- Improved! Exceptions rendering while using MIME types different to `application/json`.
|
||||||
|
|
||||||
- Improved! JSONRPC Automatic Object Publishing can not invoke inherited methods if not explicitly defined with `MVCInheritable` attribute.
|
|
||||||
|
|
||||||
- New! JSONRPC Hooks for published objects
|
|
||||||
|
|
||||||
```delphi
|
|
||||||
//Called before as soon as the HTTP arrives
|
|
||||||
procedure TMyPublishedObject.OnBeforeRouting(const JSON: TJDOJsonObject);
|
|
||||||
|
|
||||||
//Called before the invoked method
|
|
||||||
procedure TMyPublishedObject.OnBeforeCall(const JSONRequest: TJDOJsonObject);
|
|
||||||
|
|
||||||
//Called just before to send response to the client
|
|
||||||
procedure TMyPublishedObject.OnBeforeSendResponse(const JSONResponse: TJDOJsonObject);
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- SSL Server support for `TMVCListener` (Thanks to [Sven Harazim](https://github.com/landrix))
|
- SSL Server support for `TMVCListener` (Thanks to [Sven Harazim](https://github.com/landrix))
|
||||||
|
|
||||||
- Improved! Datasets serialization speed improvement. In some case the performance [improves of 2 order of magnitude](https://github.com/danieleteti/delphimvcframework/issues/205#issuecomment-479513158). (Thanks to https://github.com/pedrooliveira01)
|
- Improved! Datasets serialization speed improvement. In some case the performance [improves of 2 order of magnitude](https://github.com/danieleteti/delphimvcframework/issues/205#issuecomment-479513158). (Thanks to https://github.com/pedrooliveira01)
|
||||||
@ -397,8 +378,6 @@ end;
|
|||||||
|
|
||||||
- New! `TMVCActiveRecord` can handle non autogenerated primary key.
|
- New! `TMVCActiveRecord` can handle non autogenerated primary key.
|
||||||
|
|
||||||
- New! Calling `<jsonrpcendpoint>/describe` returns the methods list available for that endpoint.
|
|
||||||
|
|
||||||
- New! Experimental (alpha stage) support for Android servers!
|
- New! Experimental (alpha stage) support for Android servers!
|
||||||
|
|
||||||
- New! Added support for `X-HTTP-Method-Override` to work behind corporate firewalls.
|
- New! Added support for `X-HTTP-Method-Override` to work behind corporate firewalls.
|
||||||
@ -479,55 +458,69 @@ end;
|
|||||||
|
|
||||||
- New! The **MVCAREntitiesGenerator** can optionally register all the generated entities also in the `ActiveRecordMappingRegistry` (Thanks to [Fabrizio Bitti](https://twitter.com/fabriziobitti) from [bit Time Software](http://www.bittime.it))
|
- New! The **MVCAREntitiesGenerator** can optionally register all the generated entities also in the `ActiveRecordMappingRegistry` (Thanks to [Fabrizio Bitti](https://twitter.com/fabriziobitti) from [bit Time Software](http://www.bittime.it))
|
||||||
|
|
||||||
- Fixed! [issue38](https://github.com/danieleteti/delphimvcframework/issues/38)
|
- **JSON-RPC Improvements**
|
||||||
|
|
||||||
- Fixed! [issue184](https://github.com/danieleteti/delphimvcframework/issues/184)
|
- New! Added `TMVCJSONRPCExecutor.ConfigHTTPClient` to fully customize the inner `THTTPClient` (e.g. `ConnectionTimeout`, `ResponseTimeout` and so on)
|
||||||
|
|
||||||
- Fixed! [issue278](https://github.com/danieleteti/delphimvcframework/issues/278)
|
- Improved! JSONRPC Automatic Object Publishing can not invoke inherited methods if not explicitly defined with `MVCInheritable` attribute.
|
||||||
|
|
||||||
- Fixed! [issue164](https://github.com/danieleteti/delphimvcframework/issues/164)
|
- New! Calling `<jsonrpcendpoint>/describe` returns the methods list available for that endpoint.
|
||||||
|
|
||||||
- Fixed! [issue182](https://github.com/danieleteti/delphimvcframework/issues/182)
|
- New! Full support for named parameters in JSON-RPC call (server and client)
|
||||||
|
|
||||||
- Fixed! [issue232](https://github.com/danieleteti/delphimvcframework/issues/232) (Thanks to [João Antônio Duarte](https://github.com/joaoduarte19))
|
- Positional parameters example
|
||||||
|
|
||||||
- Fixed! [issue289](https://github.com/danieleteti/delphimvcframework/issues/289) (Thanks to [João Antônio Duarte](https://github.com/joaoduarte19))
|
```delphi
|
||||||
|
procedure TMainForm.btnSubtractClick(Sender: TObject);
|
||||||
|
var
|
||||||
|
lReq: IJSONRPCRequest;
|
||||||
|
lResp: IJSONRPCResponse;
|
||||||
|
begin
|
||||||
|
lReq := TJSONRPCRequest.Create;
|
||||||
|
lReq.Method := 'subtract';
|
||||||
|
lReq.RequestID := Random(1000);
|
||||||
|
lReq.Params.Add(StrToInt(edtValue1.Text));
|
||||||
|
lReq.Params.Add(StrToInt(edtValue2.Text));
|
||||||
|
lResp := FExecutor.ExecuteRequest(lReq);
|
||||||
|
edtResult.Text := lResp.Result.AsInteger.ToString;
|
||||||
|
end;
|
||||||
|
```
|
||||||
|
|
||||||
- Fixed! [issue291](https://github.com/danieleteti/delphimvcframework/issues/291) (Thanks to [João Antônio Duarte](https://github.com/joaoduarte19))
|
- Named parameters example
|
||||||
|
|
||||||
- Fixed! [issue305](https://github.com/danieleteti/delphimvcframework/issues/305) (Thanks to [João Antônio Duarte](https://github.com/joaoduarte19))
|
```delphi
|
||||||
|
procedure TMainForm.btnSubtractWithNamedParamsClick(Sender: TObject);
|
||||||
|
var
|
||||||
|
lReq: IJSONRPCRequest;
|
||||||
|
lResp: IJSONRPCResponse;
|
||||||
|
begin
|
||||||
|
lReq := TJSONRPCRequest.Create;
|
||||||
|
lReq.Method := 'subtract';
|
||||||
|
lReq.RequestID := Random(1000);
|
||||||
|
lReq.Params.AddByName('Value1', StrToInt(Edit1.Text));
|
||||||
|
lReq.Params.AddByName('Value2', StrToInt(Edit2.Text));
|
||||||
|
lResp := FExecutor.ExecuteRequest(lReq);
|
||||||
|
Edit3.Text := lResp.Result.AsInteger.ToString;
|
||||||
|
end;
|
||||||
|
```
|
||||||
|
|
||||||
- Fixed! [issue312](https://github.com/danieleteti/delphimvcframework/issues/312)
|
- Check [official JSONRPC 2.0 documentation](https://www.jsonrpc.org/specification#examples) for more examples.
|
||||||
|
|
||||||
- Fixed! [issue330](https://github.com/danieleteti/delphimvcframework/issues/330)
|
- New! JSONRPC Hooks for published objects
|
||||||
|
|
||||||
- Fixed! [issue333](https://github.com/danieleteti/delphimvcframework/issues/333)
|
```delphi
|
||||||
|
//Called before as soon as the HTTP arrives
|
||||||
|
procedure TMyPublishedObject.OnBeforeRouting(const JSON: TJDOJsonObject);
|
||||||
|
|
||||||
|
//Called before the invoked method
|
||||||
|
procedure TMyPublishedObject.OnBeforeCall(const JSONRequest: TJDOJsonObject);
|
||||||
|
|
||||||
|
//Called just before to send response to the client
|
||||||
|
procedure TMyPublishedObject.OnBeforeSendResponse(const JSONResponse: TJDOJsonObject);
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
- Fixed! [issue334](https://github.com/danieleteti/delphimvcframework/issues/334)
|
|
||||||
|
|
||||||
- Fixed! [issue336](https://github.com/danieleteti/delphimvcframework/issues/336)
|
|
||||||
|
|
||||||
- Fixed! [issue337](https://github.com/danieleteti/delphimvcframework/issues/337)
|
|
||||||
|
|
||||||
- Fixed! [issue338](https://github.com/danieleteti/delphimvcframework/issues/338)
|
|
||||||
|
|
||||||
- Fixed! [issue345](https://github.com/danieleteti/delphimvcframework/issues/345)
|
|
||||||
|
|
||||||
- Fixed! [issue349](https://github.com/danieleteti/delphimvcframework/issues/349)
|
|
||||||
|
|
||||||
- Fixed! [issue350](https://github.com/danieleteti/delphimvcframework/issues/350)
|
|
||||||
|
|
||||||
- Fixed! [issue355](https://github.com/danieleteti/delphimvcframework/issues/355)
|
|
||||||
|
|
||||||
- Fixed! [issue356](https://github.com/danieleteti/delphimvcframework/issues/356)
|
|
||||||
|
|
||||||
- Fixed! [issue362](https://github.com/danieleteti/delphimvcframework/issues/362)
|
|
||||||
|
|
||||||
- Fixed! [issue363](https://github.com/danieleteti/delphimvcframework/issues/363)
|
|
||||||
|
|
||||||
- Fixed! [issue364](https://github.com/danieleteti/delphimvcframework/issues/364) (Thanks to [João Antônio Duarte](https://github.com/joaoduarte19))
|
|
||||||
|
|
||||||
- Fixed! [issue366](https://github.com/danieleteti/delphimvcframework/issues/366)
|
|
||||||
|
|
||||||
- **Breaking Change!** In `MVCActiveRecord` attribute `MVCPrimaryKey` has been removed and merged with `MVCTableField`, so now `TMVCActiveRecordFieldOption` is a set of `foPrimaryKey`, `foAutoGenerated`, `foTransient` (check `activerecord_showcase.dproj` sample).
|
- **Breaking Change!** In `MVCActiveRecord` attribute `MVCPrimaryKey` has been removed and merged with `MVCTableField`, so now `TMVCActiveRecordFieldOption` is a set of `foPrimaryKey`, `foAutoGenerated`, `foTransient` (check `activerecord_showcase.dproj` sample).
|
||||||
|
|
||||||
@ -535,8 +528,6 @@ end;
|
|||||||
|
|
||||||
- **Deprecated!** `TDataSetHolder` is deprecated! Use the shining new `ObjectDict(boolean)` instead.
|
- **Deprecated!** `TDataSetHolder` is deprecated! Use the shining new `ObjectDict(boolean)` instead.
|
||||||
|
|
||||||
- Fixed! Has been patched a serious security bug affecting deployment configurations which uses internal WebServer to serve static files (do not affect all Apache, IIS or proxied deployments). Thanks to **Stephan Munz** to have discovered it. *Update to dmvcframework-3.2-RC5+ is required for all such kind of deployments.*
|
|
||||||
|
|
||||||
- Added ability to serialize/deserialize types enumerated by an array of mapped values (Thanks to [João Antônio Duarte](https://github.com/joaoduarte19))
|
- Added ability to serialize/deserialize types enumerated by an array of mapped values (Thanks to [João Antônio Duarte](https://github.com/joaoduarte19))
|
||||||
|
|
||||||
```delphi
|
```delphi
|
||||||
@ -581,6 +572,35 @@ end;
|
|||||||
|Delphi 10.1 Berlin| `packages\d101\dmvcframework_group.groupproj`|
|
|Delphi 10.1 Berlin| `packages\d101\dmvcframework_group.groupproj`|
|
||||||
|Delphi 10.0 Seattle| `packages\d100\dmvcframework_group.groupproj`|
|
|Delphi 10.0 Seattle| `packages\d100\dmvcframework_group.groupproj`|
|
||||||
|
|
||||||
|
### Bug Fixes in 3.2.0-boron
|
||||||
|
|
||||||
|
- Fixed! [issue38](https://github.com/danieleteti/delphimvcframework/issues/38)
|
||||||
|
- Fixed! [issue184](https://github.com/danieleteti/delphimvcframework/issues/184)
|
||||||
|
- Fixed! [issue278](https://github.com/danieleteti/delphimvcframework/issues/278)
|
||||||
|
- Fixed! [issue164](https://github.com/danieleteti/delphimvcframework/issues/164)
|
||||||
|
- Fixed! [issue182](https://github.com/danieleteti/delphimvcframework/issues/182)
|
||||||
|
- Fixed! [issue232](https://github.com/danieleteti/delphimvcframework/issues/232) (Thanks to [João Antônio Duarte](https://github.com/joaoduarte19))
|
||||||
|
- Fixed! [issue289](https://github.com/danieleteti/delphimvcframework/issues/289) (Thanks to [João Antônio Duarte](https://github.com/joaoduarte19))
|
||||||
|
- Fixed! [issue291](https://github.com/danieleteti/delphimvcframework/issues/291) (Thanks to [João Antônio Duarte](https://github.com/joaoduarte19))
|
||||||
|
- Fixed! [issue305](https://github.com/danieleteti/delphimvcframework/issues/305) (Thanks to [João Antônio Duarte](https://github.com/joaoduarte19))
|
||||||
|
- Fixed! [issue312](https://github.com/danieleteti/delphimvcframework/issues/312)
|
||||||
|
- Fixed! [issue330](https://github.com/danieleteti/delphimvcframework/issues/330)
|
||||||
|
- Fixed! [issue333](https://github.com/danieleteti/delphimvcframework/issues/333)
|
||||||
|
- Fixed! [issue334](https://github.com/danieleteti/delphimvcframework/issues/334)
|
||||||
|
- Fixed! [issue336](https://github.com/danieleteti/delphimvcframework/issues/336)
|
||||||
|
- Fixed! [issue337](https://github.com/danieleteti/delphimvcframework/issues/337)
|
||||||
|
- Fixed! [issue338](https://github.com/danieleteti/delphimvcframework/issues/338)
|
||||||
|
- Fixed! [issue345](https://github.com/danieleteti/delphimvcframework/issues/345)
|
||||||
|
- Fixed! [issue349](https://github.com/danieleteti/delphimvcframework/issues/349)
|
||||||
|
- Fixed! [issue350](https://github.com/danieleteti/delphimvcframework/issues/350)
|
||||||
|
- Fixed! [issue355](https://github.com/danieleteti/delphimvcframework/issues/355)
|
||||||
|
- Fixed! [issue356](https://github.com/danieleteti/delphimvcframework/issues/356)
|
||||||
|
- Fixed! [issue362](https://github.com/danieleteti/delphimvcframework/issues/362)
|
||||||
|
- Fixed! [issue363](https://github.com/danieleteti/delphimvcframework/issues/363)
|
||||||
|
- Fixed! [issue364](https://github.com/danieleteti/delphimvcframework/issues/364) (Thanks to [João Antônio Duarte](https://github.com/joaoduarte19))
|
||||||
|
- Fixed! [issue366](https://github.com/danieleteti/delphimvcframework/issues/366)
|
||||||
|
- Fixed! Has been patched a serious security bug affecting deployment configurations which uses internal WebServer to serve static files (do not affect all Apache, IIS or proxied deployments). Thanks to **Stephan Munz** to have discovered it. *Update to dmvcframework-3.2-RC5+ is required for all such kind of deployments.*
|
||||||
|
|
||||||
## DelphiMVCFramework 3.1.0-lithium (Current Release)
|
## DelphiMVCFramework 3.1.0-lithium (Current Release)
|
||||||
|
|
||||||
- New! Added `TMVCActiveRecord` framework (check sample `activerecord_showcase` and `activerecord_crud`)
|
- New! Added `TMVCActiveRecord` framework (check sample `activerecord_showcase` and `activerecord_crud`)
|
||||||
|
BIN
docs/favicons/favicon_io.zip
Normal file
BIN
docs/favicons/favicon_io.zip
Normal file
Binary file not shown.
@ -2,7 +2,7 @@ object MainForm: TMainForm
|
|||||||
Left = 0
|
Left = 0
|
||||||
Top = 0
|
Top = 0
|
||||||
Caption = 'JSON-RPC 2.0 Client'
|
Caption = 'JSON-RPC 2.0 Client'
|
||||||
ClientHeight = 527
|
ClientHeight = 546
|
||||||
ClientWidth = 842
|
ClientWidth = 842
|
||||||
Color = clBtnFace
|
Color = clBtnFace
|
||||||
Font.Charset = DEFAULT_CHARSET
|
Font.Charset = DEFAULT_CHARSET
|
||||||
@ -18,7 +18,7 @@ object MainForm: TMainForm
|
|||||||
Left = 0
|
Left = 0
|
||||||
Top = 0
|
Top = 0
|
||||||
Width = 842
|
Width = 842
|
||||||
Height = 527
|
Height = 546
|
||||||
ActivePage = TabSheet1
|
ActivePage = TabSheet1
|
||||||
Align = alClient
|
Align = alClient
|
||||||
TabOrder = 0
|
TabOrder = 0
|
||||||
@ -28,7 +28,7 @@ object MainForm: TMainForm
|
|||||||
Left = 3
|
Left = 3
|
||||||
Top = 22
|
Top = 22
|
||||||
Width = 815
|
Width = 815
|
||||||
Height = 124
|
Height = 174
|
||||||
Caption = 'Simple Types'
|
Caption = 'Simple Types'
|
||||||
TabOrder = 0
|
TabOrder = 0
|
||||||
object edtValue1: TEdit
|
object edtValue1: TEdit
|
||||||
@ -206,10 +206,43 @@ object MainForm: TMainForm
|
|||||||
TabOrder = 16
|
TabOrder = 16
|
||||||
OnClick = btnWithJSONClick
|
OnClick = btnWithJSONClick
|
||||||
end
|
end
|
||||||
|
object Edit1: TEdit
|
||||||
|
Left = 17
|
||||||
|
Top = 136
|
||||||
|
Width = 32
|
||||||
|
Height = 21
|
||||||
|
TabOrder = 17
|
||||||
|
Text = '42'
|
||||||
|
end
|
||||||
|
object Edit2: TEdit
|
||||||
|
Left = 55
|
||||||
|
Top = 136
|
||||||
|
Width = 26
|
||||||
|
Height = 21
|
||||||
|
TabOrder = 18
|
||||||
|
Text = '10'
|
||||||
|
end
|
||||||
|
object btnSubtractWithNamedParams: TButton
|
||||||
|
Left = 87
|
||||||
|
Top = 134
|
||||||
|
Width = 160
|
||||||
|
Height = 25
|
||||||
|
Caption = 'Subtract (named params)'
|
||||||
|
TabOrder = 19
|
||||||
|
OnClick = btnSubtractWithNamedParamsClick
|
||||||
|
end
|
||||||
|
object Edit3: TEdit
|
||||||
|
Left = 253
|
||||||
|
Top = 136
|
||||||
|
Width = 27
|
||||||
|
Height = 21
|
||||||
|
ReadOnly = True
|
||||||
|
TabOrder = 20
|
||||||
|
end
|
||||||
end
|
end
|
||||||
object GroupBox2: TGroupBox
|
object GroupBox2: TGroupBox
|
||||||
Left = 3
|
Left = 3
|
||||||
Top = 162
|
Top = 202
|
||||||
Width = 489
|
Width = 489
|
||||||
Height = 159
|
Height = 159
|
||||||
Caption = 'Returning Objects'
|
Caption = 'Returning Objects'
|
||||||
@ -247,7 +280,7 @@ object MainForm: TMainForm
|
|||||||
end
|
end
|
||||||
object GroupBox3: TGroupBox
|
object GroupBox3: TGroupBox
|
||||||
Left = 504
|
Left = 504
|
||||||
Top = 162
|
Top = 202
|
||||||
Width = 314
|
Width = 314
|
||||||
Height = 310
|
Height = 310
|
||||||
Caption = 'Returning Datasets'
|
Caption = 'Returning Datasets'
|
||||||
@ -284,7 +317,7 @@ object MainForm: TMainForm
|
|||||||
end
|
end
|
||||||
object GroupBox4: TGroupBox
|
object GroupBox4: TGroupBox
|
||||||
Left = 3
|
Left = 3
|
||||||
Top = 343
|
Top = 383
|
||||||
Width = 489
|
Width = 489
|
||||||
Height = 129
|
Height = 129
|
||||||
Caption = 'Passing Objects as parameters'
|
Caption = 'Passing Objects as parameters'
|
||||||
|
@ -77,6 +77,10 @@ type
|
|||||||
btnDates: TButton;
|
btnDates: TButton;
|
||||||
btnFloatsTests: TButton;
|
btnFloatsTests: TButton;
|
||||||
btnWithJSON: TButton;
|
btnWithJSON: TButton;
|
||||||
|
Edit1: TEdit;
|
||||||
|
Edit2: TEdit;
|
||||||
|
btnSubtractWithNamedParams: TButton;
|
||||||
|
Edit3: TEdit;
|
||||||
procedure btnSubstractClick(Sender: TObject);
|
procedure btnSubstractClick(Sender: TObject);
|
||||||
procedure btnReverseStringClick(Sender: TObject);
|
procedure btnReverseStringClick(Sender: TObject);
|
||||||
procedure edtGetCustomersClick(Sender: TObject);
|
procedure edtGetCustomersClick(Sender: TObject);
|
||||||
@ -92,6 +96,7 @@ type
|
|||||||
procedure btnDatesClick(Sender: TObject);
|
procedure btnDatesClick(Sender: TObject);
|
||||||
procedure btnFloatsTestsClick(Sender: TObject);
|
procedure btnFloatsTestsClick(Sender: TObject);
|
||||||
procedure btnWithJSONClick(Sender: TObject);
|
procedure btnWithJSONClick(Sender: TObject);
|
||||||
|
procedure btnSubtractWithNamedParamsClick(Sender: TObject);
|
||||||
private
|
private
|
||||||
FExecutor: IMVCJSONRPCExecutor;
|
FExecutor: IMVCJSONRPCExecutor;
|
||||||
FExecutor2: IMVCJSONRPCExecutor;
|
FExecutor2: IMVCJSONRPCExecutor;
|
||||||
@ -156,7 +161,7 @@ begin
|
|||||||
lResp := FExecutor.ExecuteRequest(lReq);
|
lResp := FExecutor.ExecuteRequest(lReq);
|
||||||
lRes := lResp.Result.AsType<Extended>;
|
lRes := lResp.Result.AsType<Extended>;
|
||||||
lRes := RoundTo(lRes, -4);
|
lRes := RoundTo(lRes, -4);
|
||||||
Assert(SameValue(lRes, 3580.2467), 'Wrong result: ' + FloatToStrF(lRes, ffGeneral, 18,9));
|
Assert(SameValue(lRes, 3580.2467), 'Wrong result: ' + FloatToStrF(lRes, ffGeneral, 18, 9));
|
||||||
|
|
||||||
lReq := TJSONRPCRequest.Create(1234, 'floatstest');
|
lReq := TJSONRPCRequest.Create(1234, 'floatstest');
|
||||||
lReq.Params.Add(123);
|
lReq.Params.Add(123);
|
||||||
@ -164,7 +169,7 @@ begin
|
|||||||
lResp := FExecutor.ExecuteRequest(lReq);
|
lResp := FExecutor.ExecuteRequest(lReq);
|
||||||
lRes := lResp.Result.AsType<Extended>;
|
lRes := lResp.Result.AsType<Extended>;
|
||||||
lRes := RoundTo(lRes, -4);
|
lRes := RoundTo(lRes, -4);
|
||||||
Assert(SameValue(lRes, 357), 'Wrong result: ' + FloatToStrF(lRes, ffGeneral, 18,9));
|
Assert(SameValue(lRes, 357), 'Wrong result: ' + FloatToStrF(lRes, ffGeneral, 18, 9));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMainForm.btnGetUserClick(Sender: TObject);
|
procedure TMainForm.btnGetUserClick(Sender: TObject);
|
||||||
@ -241,8 +246,8 @@ begin
|
|||||||
lReq := TJSONRPCRequest.Create;
|
lReq := TJSONRPCRequest.Create;
|
||||||
lReq.Method := 'reversestring';
|
lReq.Method := 'reversestring';
|
||||||
lReq.RequestID := Random(1000);
|
lReq.RequestID := Random(1000);
|
||||||
lReq.Params.Add(edtReverseString.Text);
|
lReq.Params.AddByName('aString', edtReverseString.Text);
|
||||||
lReq.Params.Add(CheckBox1.Checked);
|
lReq.Params.AddByName('aUpperCase', CheckBox1.Checked);
|
||||||
lResp := FExecutor.ExecuteRequest(lReq);
|
lResp := FExecutor.ExecuteRequest(lReq);
|
||||||
edtReversedString.Text := lResp.Result.AsString;
|
edtReversedString.Text := lResp.Result.AsString;
|
||||||
end;
|
end;
|
||||||
@ -257,7 +262,7 @@ begin
|
|||||||
lReq.Method := 'saveperson';
|
lReq.Method := 'saveperson';
|
||||||
lReq.RequestID := Random(1000);
|
lReq.RequestID := Random(1000);
|
||||||
lPerson := TPerson.Create;
|
lPerson := TPerson.Create;
|
||||||
lReq.Params.Add(lPerson, pdtObject);
|
lReq.Params.AddByName('Person', lPerson, pdtObject);
|
||||||
lPerson.FirstName := edtFirstName.Text;
|
lPerson.FirstName := edtFirstName.Text;
|
||||||
lPerson.LastName := edtLastName.Text;
|
lPerson.LastName := edtLastName.Text;
|
||||||
lPerson.Married := chkMarried.Checked;
|
lPerson.Married := chkMarried.Checked;
|
||||||
@ -289,7 +294,7 @@ begin
|
|||||||
for I := 0 to lJSON.Count - 1 do
|
for I := 0 to lJSON.Count - 1 do
|
||||||
begin
|
begin
|
||||||
lJObj := lJSON[I].ObjectValue;
|
lJObj := lJSON[I].ObjectValue;
|
||||||
ListBox1.Items.Add(Format('%6s: %-34s € %5.2f',[lJObj.S['codice'], lJObj.S['descrizione'], lJObj.F['prezzo']]));
|
ListBox1.Items.Add(Format('%6s: %-34s € %5.2f', [lJObj.S['codice'], lJObj.S['descrizione'], lJObj.F['prezzo']]));
|
||||||
end;
|
end;
|
||||||
// lbPerson.Items.Add('First Name:'.PadRight(15) + lJSON.S['firstname']);
|
// lbPerson.Items.Add('First Name:'.PadRight(15) + lJSON.S['firstname']);
|
||||||
// lbPerson.Items.Add('Last Name:'.PadRight(15) + lJSON.S['lastname']);
|
// lbPerson.Items.Add('Last Name:'.PadRight(15) + lJSON.S['lastname']);
|
||||||
@ -311,6 +316,20 @@ begin
|
|||||||
edtResult.Text := lResp.Result.AsInteger.ToString;
|
edtResult.Text := lResp.Result.AsInteger.ToString;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TMainForm.btnSubtractWithNamedParamsClick(Sender: TObject);
|
||||||
|
var
|
||||||
|
lReq: IJSONRPCRequest;
|
||||||
|
lResp: IJSONRPCResponse;
|
||||||
|
begin
|
||||||
|
lReq := TJSONRPCRequest.Create;
|
||||||
|
lReq.Method := 'subtract';
|
||||||
|
lReq.RequestID := Random(1000);
|
||||||
|
lReq.Params.AddByName('Value1', StrToInt(Edit1.Text));
|
||||||
|
lReq.Params.AddByName('Value2', StrToInt(Edit2.Text));
|
||||||
|
lResp := FExecutor.ExecuteRequest(lReq);
|
||||||
|
Edit3.Text := lResp.Result.AsInteger.ToString;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TMainForm.btnWithJSONClick(Sender: TObject);
|
procedure TMainForm.btnWithJSONClick(Sender: TObject);
|
||||||
var
|
var
|
||||||
lPerson: TJsonObject;
|
lPerson: TJsonObject;
|
||||||
@ -337,7 +356,7 @@ var
|
|||||||
begin
|
begin
|
||||||
FDMemTable1.Active := False;
|
FDMemTable1.Active := False;
|
||||||
lReq := TJSONRPCRequest.Create(Random(1000), 'getcustomers');
|
lReq := TJSONRPCRequest.Create(Random(1000), 'getcustomers');
|
||||||
lReq.Params.Add(edtFilter.Text);
|
lReq.Params.AddByName('FilterString', edtFilter.Text);
|
||||||
lResp := FExecutor.ExecuteRequest(lReq);
|
lResp := FExecutor.ExecuteRequest(lReq);
|
||||||
FDMemTable1.Active := True;
|
FDMemTable1.Active := True;
|
||||||
FDMemTable1.LoadFromTValue(lResp.Result);
|
FDMemTable1.LoadFromTValue(lResp.Result);
|
||||||
@ -352,11 +371,11 @@ begin
|
|||||||
|
|
||||||
// these are the methods to handle http headers in JSONRPC
|
// these are the methods to handle http headers in JSONRPC
|
||||||
// the following line and the check on the server is just for demo
|
// the following line and the check on the server is just for demo
|
||||||
assert(FExecutor.HTTPHeadersCount = 0);
|
Assert(FExecutor.HTTPHeadersCount = 0);
|
||||||
FExecutor.AddHTTPHeader(TNetHeader.Create('x-token', TGUID.NewGuid.ToString));
|
FExecutor.AddHTTPHeader(TNetHeader.Create('x-token', TGUID.NewGuid.ToString));
|
||||||
assert(FExecutor.HTTPHeadersCount = 1);
|
Assert(FExecutor.HTTPHeadersCount = 1);
|
||||||
FExecutor.ClearHTTPHeaders;
|
FExecutor.ClearHTTPHeaders;
|
||||||
assert(FExecutor.HTTPHeadersCount = 0);
|
Assert(FExecutor.HTTPHeadersCount = 0);
|
||||||
FExecutor.AddHTTPHeader(TNetHeader.Create('x-token', TGUID.NewGuid.ToString));
|
FExecutor.AddHTTPHeader(TNetHeader.Create('x-token', TGUID.NewGuid.ToString));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -58,18 +58,18 @@ type
|
|||||||
const JSONResponse: TJDOJsonObject);
|
const JSONResponse: TJDOJsonObject);
|
||||||
public
|
public
|
||||||
[MVCDoc('You know, returns aValue1 - aValue2')]
|
[MVCDoc('You know, returns aValue1 - aValue2')]
|
||||||
function Subtract(aValue1, aValue2: Integer): Integer;
|
function Subtract(Value1, Value2: Integer): Integer;
|
||||||
[MVCDoc('Returns the revers of the string passed as input')]
|
[MVCDoc('Returns the revers of the string passed as input')]
|
||||||
function ReverseString(const aString: string; const aUpperCase: Boolean): string;
|
function ReverseString(const aString: string; const aUpperCase: Boolean): string;
|
||||||
[MVCDoc('Returns the next monday starting from aDate')]
|
[MVCDoc('Returns the next monday starting from aDate')]
|
||||||
function GetNextMonday(const aDate: TDate): TDate;
|
function GetNextMonday(const aDate: TDate): TDate;
|
||||||
function PlayWithDatesAndTimes(const aJustAFloat: Double; const aTime: TTime; const aDate: TDate;
|
function PlayWithDatesAndTimes(const aJustAFloat: Double; const aTime: TTime; const aDate: TDate;
|
||||||
const aDateAndTime: TDateTime): TDateTime;
|
const aDateAndTime: TDateTime): TDateTime;
|
||||||
function GetCustomers(aString: string): TDataset;
|
function GetCustomers(FilterString: string): TDataset;
|
||||||
function GetMulti: TMultiDataset;
|
function GetMulti: TMultiDataset;
|
||||||
function GetStringDictionary: TMVCStringDictionary;
|
function GetStringDictionary: TMVCStringDictionary;
|
||||||
function GetUser(aUserName: string): TPerson;
|
function GetUser(aUserName: string): TPerson;
|
||||||
function SavePerson(const aPerson: TJsonObject): Integer;
|
function SavePerson(const Person: TJsonObject): Integer;
|
||||||
function FloatsTest(const aDouble: Double; const aExtended: Extended): Extended;
|
function FloatsTest(const aDouble: Double; const aExtended: Extended): Extended;
|
||||||
procedure DoSomething;
|
procedure DoSomething;
|
||||||
function SaveObjectWithJSON(const WithJSON: TJsonObject): TJsonObject;
|
function SaveObjectWithJSON(const WithJSON: TJsonObject): TJsonObject;
|
||||||
@ -123,15 +123,15 @@ begin
|
|||||||
Result := aDouble + aExtended;
|
Result := aDouble + aExtended;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TMyObject.GetCustomers(aString: string): TDataset;
|
function TMyObject.GetCustomers(FilterString: string): TDataset;
|
||||||
var
|
var
|
||||||
lMT: TFDMemTable;
|
lMT: TFDMemTable;
|
||||||
begin
|
begin
|
||||||
lMT := GetCustomersDataset;
|
lMT := GetCustomersDataset;
|
||||||
try
|
try
|
||||||
if not aString.IsEmpty then
|
if not FilterString.IsEmpty then
|
||||||
begin
|
begin
|
||||||
lMT.Filter := aString;
|
lMT.Filter := FilterString;
|
||||||
lMT.Filtered := True;
|
lMT.Filtered := True;
|
||||||
end;
|
end;
|
||||||
lMT.First;
|
lMT.First;
|
||||||
@ -269,7 +269,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TMyObject.SavePerson(const aPerson: TJsonObject): Integer;
|
function TMyObject.SavePerson(const Person: TJsonObject): Integer;
|
||||||
// var
|
// var
|
||||||
// lPerson: TPerson;
|
// lPerson: TPerson;
|
||||||
begin
|
begin
|
||||||
@ -284,9 +284,9 @@ begin
|
|||||||
Result := Random(1000);
|
Result := Random(1000);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TMyObject.Subtract(aValue1, aValue2: Integer): Integer;
|
function TMyObject.Subtract(Value1, Value2: Integer): Integer;
|
||||||
begin
|
begin
|
||||||
Result := aValue1 - aValue2;
|
Result := Value1 - Value2;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TData }
|
{ TData }
|
||||||
|
@ -120,7 +120,7 @@ type
|
|||||||
OneMiB = 1048576;
|
OneMiB = 1048576;
|
||||||
OneKiB = 1024;
|
OneKiB = 1024;
|
||||||
DEFAULT_MAX_REQUEST_SIZE = OneMiB * 5; // 5 MiB
|
DEFAULT_MAX_REQUEST_SIZE = OneMiB * 5; // 5 MiB
|
||||||
HATEOAS_PROP_NAME = '_links';
|
HATEOAS_PROP_NAME = 'links';
|
||||||
X_HTTP_Method_Override = 'X-HTTP-Method-Override';
|
X_HTTP_Method_Override = 'X-HTTP-Method-Override';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -136,8 +136,13 @@ type
|
|||||||
function GetItem(const Index: Integer): TValue;
|
function GetItem(const Index: Integer): TValue;
|
||||||
function GetItemDataType(const Index: Integer): TJSONRPCParamDataType;
|
function GetItemDataType(const Index: Integer): TJSONRPCParamDataType;
|
||||||
protected
|
protected
|
||||||
FParamsValue: TList<TValue>;
|
fParamValues: TList<TValue>;
|
||||||
FParamsType: TList<TJSONRPCParamDataType>;
|
fParamNames: TList<string>;
|
||||||
|
fParamTypes: TList<TJSONRPCParamDataType>;
|
||||||
|
private
|
||||||
|
procedure CheckNotNames;
|
||||||
|
procedure CheckBalancedParams;
|
||||||
|
function GetItemName(const Index: Integer): string;
|
||||||
public
|
public
|
||||||
constructor Create; virtual;
|
constructor Create; virtual;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
@ -145,6 +150,7 @@ type
|
|||||||
function Count: Integer;
|
function Count: Integer;
|
||||||
property Items[const index: Integer]: TValue read GetItem; default;
|
property Items[const index: Integer]: TValue read GetItem; default;
|
||||||
property ItemsType[const index: Integer]: TJSONRPCParamDataType read GetItemDataType;
|
property ItemsType[const index: Integer]: TJSONRPCParamDataType read GetItemDataType;
|
||||||
|
property ItemsName[const index: Integer]: string read GetItemName;
|
||||||
function ToArray: TArray<TValue>;
|
function ToArray: TArray<TValue>;
|
||||||
procedure Add(const Value: string); overload;
|
procedure Add(const Value: string); overload;
|
||||||
procedure Add(const Value: Integer); overload;
|
procedure Add(const Value: Integer); overload;
|
||||||
@ -156,6 +162,16 @@ type
|
|||||||
procedure Add(const Value: TDateTime); overload;
|
procedure Add(const Value: TDateTime); overload;
|
||||||
procedure Add(const Value: Double); overload;
|
procedure Add(const Value: Double); overload;
|
||||||
procedure Add(const Value: TValue; const ParamType: TJSONRPCParamDataType); overload;
|
procedure Add(const Value: TValue; const ParamType: TJSONRPCParamDataType); overload;
|
||||||
|
procedure AddByName(const Name: string; const Value: string); overload;
|
||||||
|
procedure AddByName(const Name: string; const Value: Integer); overload;
|
||||||
|
procedure AddByName(const Name: string; const Value: TJDOJsonObject); overload;
|
||||||
|
procedure AddByName(const Name: string; const Value: TJDOJsonArray); overload;
|
||||||
|
procedure AddByName(const Name: string; const Value: Boolean); overload;
|
||||||
|
procedure AddByName(const Name: string; const Value: TDate); overload;
|
||||||
|
procedure AddByName(const Name: string; const Value: TTime); overload;
|
||||||
|
procedure AddByName(const Name: string; const Value: TDateTime); overload;
|
||||||
|
procedure AddByName(const Name: string; const Value: Double); overload;
|
||||||
|
procedure AddByName(const Name: string; const Value: TValue; const ParamType: TJSONRPCParamDataType); overload;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
IJSONRPCNotification = interface(IJSONRPCObject)
|
IJSONRPCNotification = interface(IJSONRPCObject)
|
||||||
@ -498,6 +514,84 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure AppendTValueToJsonObject(const Value: TValue; const Name: string; const ParamType: TJSONRPCParamDataType;
|
||||||
|
const JSONObj: TJDOJsonObject);
|
||||||
|
var
|
||||||
|
lSer: TMVCJsonDataObjectsSerializer;
|
||||||
|
lOrdinalValue: Int64;
|
||||||
|
begin
|
||||||
|
case ParamType of
|
||||||
|
pdtInteger:
|
||||||
|
begin
|
||||||
|
JSONObj.I[name] := Value.AsInteger;
|
||||||
|
end;
|
||||||
|
pdtFloat:
|
||||||
|
begin
|
||||||
|
JSONObj.F[name] := Value.AsExtended;
|
||||||
|
end;
|
||||||
|
pdtDateTime:
|
||||||
|
begin
|
||||||
|
JSONObj.S[name] := DateTimeToISOTimeStamp(FloatToDateTime(Value.AsExtended));
|
||||||
|
end;
|
||||||
|
pdtDate:
|
||||||
|
begin
|
||||||
|
JSONObj.S[name] := DateToISODate(FloatToDateTime(Value.AsExtended));
|
||||||
|
end;
|
||||||
|
pdtTime:
|
||||||
|
begin
|
||||||
|
JSONObj.S[name] := TimeToISOTime(FloatToDateTime(Value.AsExtended));
|
||||||
|
end;
|
||||||
|
pdtString:
|
||||||
|
begin
|
||||||
|
JSONObj.S[name] := Value.AsString;
|
||||||
|
end;
|
||||||
|
pdtLongInteger:
|
||||||
|
begin
|
||||||
|
JSONObj.L[name] := Value.AsInt64;
|
||||||
|
end;
|
||||||
|
pdtBoolean:
|
||||||
|
begin
|
||||||
|
if not Value.TryAsOrdinal(lOrdinalValue) then
|
||||||
|
begin
|
||||||
|
raise EMVCException.Create('Invalid ordinal parameter');
|
||||||
|
end;
|
||||||
|
JSONObj.B[name] := lOrdinalValue = 1;
|
||||||
|
end;
|
||||||
|
pdTJDOJsonObject:
|
||||||
|
begin
|
||||||
|
JSONObj.O[name] := (Value.AsObject as TJDOJsonObject).Clone as TJDOJsonObject;
|
||||||
|
end;
|
||||||
|
pdtJSONArray:
|
||||||
|
begin
|
||||||
|
JSONObj.A[name] := (Value.AsObject as TJDOJsonArray).Clone as TJDOJsonArray;
|
||||||
|
end;
|
||||||
|
pdtObject:
|
||||||
|
begin
|
||||||
|
if Value.AsObject is TDataSet then
|
||||||
|
begin
|
||||||
|
lSer := TMVCJsonDataObjectsSerializer.Create;
|
||||||
|
try
|
||||||
|
lSer.DataSetToJsonArray(TDataSet(Value.AsObject), JSONObj.A[name], TMVCNameCase.ncLowerCase, []);
|
||||||
|
finally
|
||||||
|
lSer.Free;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
lSer := TMVCJsonDataObjectsSerializer.Create;
|
||||||
|
try
|
||||||
|
JSONObj.O[name] := lSer.SerializeObjectToJSON(Value.AsObject,
|
||||||
|
TMVCSerializationType.stProperties, [], nil);
|
||||||
|
finally
|
||||||
|
lSer.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
raise EMVCException.Create('Invalid type');
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function JSONDataValueToTValue(const JSONDataValue: TJsonDataValueHelper): TValue; overload;
|
function JSONDataValueToTValue(const JSONDataValue: TJsonDataValueHelper): TValue; overload;
|
||||||
begin
|
begin
|
||||||
case JSONDataValue.Typ of
|
case JSONDataValue.Typ of
|
||||||
@ -1048,7 +1142,15 @@ begin
|
|||||||
('Cannot call a function using a JSON-RPC notification. [HINT] Use requests for functions and notifications for procedures');
|
('Cannot call a function using a JSON-RPC notification. [HINT] Use requests for functions and notifications for procedures');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
lJSONRPCReq.FillParameters(lJSON, lRTTIMethod);
|
try
|
||||||
|
lJSONRPCReq.FillParameters(lJSON, lRTTIMethod);
|
||||||
|
except
|
||||||
|
on Ex: EMVCJSONRPCErrorResponse do
|
||||||
|
begin
|
||||||
|
raise EMVCJSONRPCInvalidParams.Create('Cannot map all parameters to remote method. ' + Ex.Message);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
try
|
try
|
||||||
TryToCallMethod(lRTTIType, JSONRPC_HOOKS_ON_BEFORE_CALL, lJSON, 'JSONRequest');
|
TryToCallMethod(lRTTIType, JSONRPC_HOOKS_ON_BEFORE_CALL, lJSON, 'JSONRequest');
|
||||||
LogD('[JSON-RPC][CALL][' + CALL_TYPE[lRTTIMethod.MethodKind] + '] ' + lRTTIMethod.Name);
|
LogD('[JSON-RPC][CALL][' + CALL_TYPE[lRTTIMethod.MethodKind] + '] ' + lRTTIMethod.Name);
|
||||||
@ -1058,6 +1160,10 @@ begin
|
|||||||
begin
|
begin
|
||||||
raise EMVCJSONRPCInvalidParams.Create('Check your input parameters types');
|
raise EMVCJSONRPCInvalidParams.Create('Check your input parameters types');
|
||||||
end;
|
end;
|
||||||
|
on Ex: EMVCJSONRPCInvalidRequest do
|
||||||
|
begin
|
||||||
|
raise EMVCJSONRPCInvalidParams.Create(Ex.Message);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
case lJSONRPCReq.RequestType of
|
case lJSONRPCReq.RequestType of
|
||||||
@ -1365,23 +1471,29 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TJSONRPCNotification.FillParameters(
|
procedure TJSONRPCNotification.FillParameters(
|
||||||
const
|
const JSON: TJDOJsonObject;
|
||||||
JSON:
|
const RTTIMethod: TRTTIMethod);
|
||||||
TJDOJsonObject;
|
|
||||||
const
|
|
||||||
RTTIMethod:
|
|
||||||
TRTTIMethod);
|
|
||||||
var
|
var
|
||||||
lRTTIMethodParams: TArray<TRttiParameter>;
|
lRTTIMethodParams: TArray<TRttiParameter>;
|
||||||
lRTTIMethodParam: TRttiParameter;
|
lRTTIMethodParam: TRttiParameter;
|
||||||
lJSONParams: TJDOJsonArray;
|
lJSONParams: TJDOJsonArray;
|
||||||
|
lJSONNamedParams: TJDOJsonObject;
|
||||||
I: Integer;
|
I: Integer;
|
||||||
|
lUseNamedParams: Boolean;
|
||||||
begin
|
begin
|
||||||
|
lUseNamedParams := False;
|
||||||
lJSONParams := nil;
|
lJSONParams := nil;
|
||||||
|
lJSONNamedParams := nil;
|
||||||
Params.Clear;
|
Params.Clear;
|
||||||
if JSON.Types[JSONRPC_PARAMS] = jdtArray then
|
if JSON.Types[JSONRPC_PARAMS] = jdtArray then
|
||||||
begin
|
begin
|
||||||
lJSONParams := JSON.A[JSONRPC_PARAMS];
|
lJSONParams := JSON.A[JSONRPC_PARAMS];
|
||||||
|
lUseNamedParams := False;
|
||||||
|
end
|
||||||
|
else if JSON.Types[JSONRPC_PARAMS] = jdtObject then
|
||||||
|
begin
|
||||||
|
lJSONNamedParams := JSON.O[JSONRPC_PARAMS];
|
||||||
|
lUseNamedParams := True;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if JSON.Types[JSONRPC_PARAMS] <> jdtNone then
|
if JSON.Types[JSONRPC_PARAMS] <> jdtNone then
|
||||||
@ -1390,12 +1502,27 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
lRTTIMethodParams := RTTIMethod.GetParameters;
|
lRTTIMethodParams := RTTIMethod.GetParameters;
|
||||||
if (Length(lRTTIMethodParams) > 0) and (not Assigned(lJSONParams)) then
|
if lUseNamedParams then
|
||||||
raise EMVCJSONRPCInvalidParams.CreateFmt('Wrong parameters count. Expected %d got %d.',
|
begin
|
||||||
[Length(lRTTIMethodParams), 0]);
|
if (Length(lRTTIMethodParams) > 0) and (not Assigned(lJSONNamedParams)) then
|
||||||
if Assigned(lJSONParams) and (Length(lRTTIMethodParams) <> lJSONParams.Count) then
|
raise EMVCJSONRPCInvalidParams.CreateFmt('Wrong parameters count. Expected %d got %d.',
|
||||||
raise EMVCJSONRPCInvalidParams.CreateFmt('Wrong parameters count. Expected %d got %d.',
|
[Length(lRTTIMethodParams), 0]);
|
||||||
[Length(lRTTIMethodParams), lJSONParams.Count]);
|
|
||||||
|
if Assigned(lJSONNamedParams) and (Length(lRTTIMethodParams) <> lJSONNamedParams.Count) then
|
||||||
|
raise EMVCJSONRPCInvalidParams.CreateFmt('Wrong parameters count. Expected %d got %d.',
|
||||||
|
[Length(lRTTIMethodParams), lJSONNamedParams.Count]);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
if (Length(lRTTIMethodParams) > 0) and (not Assigned(lJSONParams)) then
|
||||||
|
raise EMVCJSONRPCInvalidParams.CreateFmt('Wrong parameters count. Expected %d got %d.',
|
||||||
|
[Length(lRTTIMethodParams), 0]);
|
||||||
|
|
||||||
|
if Assigned(lJSONParams) and (Length(lRTTIMethodParams) <> lJSONParams.Count) then
|
||||||
|
raise EMVCJSONRPCInvalidParams.CreateFmt('Wrong parameters count. Expected %d got %d.',
|
||||||
|
[Length(lRTTIMethodParams), lJSONParams.Count]);
|
||||||
|
end;
|
||||||
|
|
||||||
for lRTTIMethodParam in lRTTIMethodParams do
|
for lRTTIMethodParam in lRTTIMethodParams do
|
||||||
begin
|
begin
|
||||||
if lRTTIMethodParam.Flags * [pfVar, pfOut, pfArray, pfReference] <> [] then
|
if lRTTIMethodParam.Flags * [pfVar, pfOut, pfArray, pfReference] <> [] then
|
||||||
@ -1407,10 +1534,19 @@ begin
|
|||||||
// scroll json params and rttimethod params and find the best match
|
// scroll json params and rttimethod params and find the best match
|
||||||
if Assigned(lJSONParams) then
|
if Assigned(lJSONParams) then
|
||||||
begin
|
begin
|
||||||
|
// positional params
|
||||||
for I := 0 to lJSONParams.Count - 1 do
|
for I := 0 to lJSONParams.Count - 1 do
|
||||||
begin
|
begin
|
||||||
JSONDataValueToTValueParam(lJSONParams[I], lRTTIMethodParams[I], Params);
|
JSONDataValueToTValueParam(lJSONParams[I], lRTTIMethodParams[I], Params);
|
||||||
end;
|
end;
|
||||||
|
end
|
||||||
|
else if Assigned(lJSONNamedParams) then
|
||||||
|
begin
|
||||||
|
// named params
|
||||||
|
for I := 0 to lJSONNamedParams.Count - 1 do
|
||||||
|
begin
|
||||||
|
JSONDataValueToTValueParam(lJSONNamedParams.Values[lRTTIMethodParams[I].Name.ToLower], lRTTIMethodParams[I], Params);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1424,10 +1560,24 @@ begin
|
|||||||
Result.S[JSONRPC_METHOD] := FMethod;
|
Result.S[JSONRPC_METHOD] := FMethod;
|
||||||
if FParams.Count > 0 then
|
if FParams.Count > 0 then
|
||||||
begin
|
begin
|
||||||
for I := 0 to FParams.Count - 1 do
|
if FParams.fParamNames.Count = 0 then
|
||||||
begin
|
begin // positional params
|
||||||
AppendTValueToJsonArray(FParams.FParamsValue[I], FParams.FParamsType[I],
|
for I := 0 to FParams.Count - 1 do
|
||||||
Result.A[JSONRPC_PARAMS]);
|
begin
|
||||||
|
AppendTValueToJsonArray(FParams.fParamValues[I], FParams.fParamTypes[I],
|
||||||
|
Result.A[JSONRPC_PARAMS]);
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin // named params
|
||||||
|
for I := 0 to FParams.Count - 1 do
|
||||||
|
begin
|
||||||
|
AppendTValueToJsonObject(
|
||||||
|
FParams.fParamValues[I],
|
||||||
|
FParams.fParamNames[I],
|
||||||
|
FParams.fParamTypes[I],
|
||||||
|
Result.O[JSONRPC_PARAMS]);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -1560,10 +1710,7 @@ begin
|
|||||||
FID := Value;
|
FID := Value;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TJSONRPCResponse.SetJSON(
|
procedure TJSONRPCResponse.SetJSON(const JSON: TJDOJsonObject);
|
||||||
const
|
|
||||||
JSON:
|
|
||||||
TJDOJsonObject);
|
|
||||||
begin
|
begin
|
||||||
if JSON.Types[JSONRPC_ID] = jdtString then
|
if JSON.Types[JSONRPC_ID] = jdtString then
|
||||||
RequestID := JSON.S[JSONRPC_ID]
|
RequestID := JSON.S[JSONRPC_ID]
|
||||||
@ -1762,117 +1909,106 @@ begin
|
|||||||
// do nothing
|
// do nothing
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TJSONRPCProxyGenerator.StartGeneration(
|
procedure TJSONRPCProxyGenerator.StartGeneration(const aClassName: string);
|
||||||
const
|
|
||||||
aClassName:
|
|
||||||
string);
|
|
||||||
begin
|
begin
|
||||||
// do nothing
|
// do nothing
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TJSONRPCRequestParams }
|
{ TJSONRPCRequestParams }
|
||||||
|
|
||||||
procedure TJSONRPCRequestParams.Add(
|
procedure TJSONRPCRequestParams.Add(const Value: TJDOJsonArray);
|
||||||
const
|
|
||||||
Value:
|
|
||||||
TJDOJsonArray);
|
|
||||||
begin
|
begin
|
||||||
Add(Value, pdtJSONArray);
|
Add(Value, pdtJSONArray);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TJSONRPCRequestParams.Add(
|
procedure TJSONRPCRequestParams.Add(const Value: TJDOJsonObject);
|
||||||
const
|
|
||||||
Value:
|
|
||||||
TJDOJsonObject);
|
|
||||||
begin
|
begin
|
||||||
Add(Value, pdTJDOJsonObject);
|
Add(Value, pdTJDOJsonObject);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TJSONRPCRequestParams.Add(
|
procedure TJSONRPCRequestParams.Add(const Value: Integer);
|
||||||
const
|
|
||||||
Value:
|
|
||||||
Integer);
|
|
||||||
begin
|
begin
|
||||||
Add(Value, pdtInteger);
|
Add(Value, pdtInteger);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TJSONRPCRequestParams.Add(
|
procedure TJSONRPCRequestParams.Add(const Value: string);
|
||||||
const
|
|
||||||
Value:
|
|
||||||
string);
|
|
||||||
begin
|
begin
|
||||||
Add(Value, pdtString);
|
Add(Value, pdtString);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TJSONRPCRequestParams.Add(
|
procedure TJSONRPCRequestParams.Add(const Value: Boolean);
|
||||||
const
|
|
||||||
Value:
|
|
||||||
Boolean);
|
|
||||||
begin
|
begin
|
||||||
Add(Value, pdtBoolean);
|
Add(Value, pdtBoolean);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TJSONRPCRequestParams.Add(
|
procedure TJSONRPCRequestParams.Add(const Value: Double);
|
||||||
const
|
|
||||||
Value:
|
|
||||||
Double);
|
|
||||||
begin
|
begin
|
||||||
Add(Value, pdtFloat);
|
Add(Value, pdtFloat);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TJSONRPCRequestParams.Add(
|
procedure TJSONRPCRequestParams.Add(const Value: TDateTime);
|
||||||
const
|
|
||||||
Value:
|
|
||||||
TDateTime);
|
|
||||||
begin
|
begin
|
||||||
Add(Value, pdtDateTime);
|
Add(Value, pdtDateTime);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TJSONRPCRequestParams.Add(
|
procedure TJSONRPCRequestParams.Add(const Value: TTime);
|
||||||
const
|
|
||||||
Value:
|
|
||||||
TTime);
|
|
||||||
begin
|
begin
|
||||||
Add(Value, pdtTime);
|
Add(Value, pdtTime);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TJSONRPCRequestParams.Add(
|
procedure TJSONRPCRequestParams.Add(const Value: TDate);
|
||||||
const
|
|
||||||
Value:
|
|
||||||
TDate);
|
|
||||||
begin
|
begin
|
||||||
Add(Value, pdtDate);
|
Add(Value, pdtDate);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TJSONRPCRequestParams.CheckBalancedParams;
|
||||||
|
begin
|
||||||
|
if fParamNames.Count <> fParamValues.Count then
|
||||||
|
begin
|
||||||
|
raise EMVCJSONRPCException.Create('Cannot mix positional with named parameters');
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONRPCRequestParams.CheckNotNames;
|
||||||
|
begin
|
||||||
|
if fParamNames.Count > 0 then
|
||||||
|
begin
|
||||||
|
raise EMVCJSONRPCException.Create('Cannot mix positional with named parameters');
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TJSONRPCRequestParams.Clear;
|
procedure TJSONRPCRequestParams.Clear;
|
||||||
begin
|
begin
|
||||||
FParamsValue.Clear;
|
fParamValues.Clear;
|
||||||
FParamsType.Clear;
|
fParamTypes.Clear;
|
||||||
|
fParamNames.Clear;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TJSONRPCRequestParams.Count: Integer;
|
function TJSONRPCRequestParams.Count: Integer;
|
||||||
begin
|
begin
|
||||||
Result := FParamsValue.Count;
|
Result := fParamValues.Count;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TJSONRPCRequestParams.Create;
|
constructor TJSONRPCRequestParams.Create;
|
||||||
begin
|
begin
|
||||||
inherited Create;
|
inherited Create;
|
||||||
FParamsValue := TList<TValue>.Create;
|
fParamValues := TList<TValue>.Create;
|
||||||
FParamsType := TList<TJSONRPCParamDataType>.Create;
|
fParamTypes := TList<TJSONRPCParamDataType>.Create;
|
||||||
|
fParamNames := TList<string>.Create;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TJSONRPCRequestParams.Destroy;
|
destructor TJSONRPCRequestParams.Destroy;
|
||||||
var
|
var
|
||||||
lValue: TValue;
|
lValue: TValue;
|
||||||
begin
|
begin
|
||||||
for lValue in FParamsValue do
|
for lValue in fParamValues do
|
||||||
begin
|
begin
|
||||||
if lValue.IsObject then
|
if lValue.IsObject then
|
||||||
lValue.AsObject.Free;
|
lValue.AsObject.Free;
|
||||||
end;
|
end;
|
||||||
FParamsValue.Free;
|
fParamValues.Free;
|
||||||
FParamsType.Free;
|
fParamTypes.Free;
|
||||||
|
fParamNames.Free;
|
||||||
inherited;
|
inherited;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1881,7 +2017,7 @@ function TJSONRPCRequestParams.GetItem(
|
|||||||
Index:
|
Index:
|
||||||
Integer): TValue;
|
Integer): TValue;
|
||||||
begin
|
begin
|
||||||
Result := FParamsValue[index];
|
Result := fParamValues[index];
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TJSONRPCRequestParams.GetItemDataType(
|
function TJSONRPCRequestParams.GetItemDataType(
|
||||||
@ -1889,24 +2025,86 @@ function TJSONRPCRequestParams.GetItemDataType(
|
|||||||
Index:
|
Index:
|
||||||
Integer): TJSONRPCParamDataType;
|
Integer): TJSONRPCParamDataType;
|
||||||
begin
|
begin
|
||||||
Result := FParamsType[index];
|
Result := fParamTypes[index];
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TJSONRPCRequestParams.GetItemName(const Index: Integer): string;
|
||||||
|
begin
|
||||||
|
Result := fParamNames[index];
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TJSONRPCRequestParams.ToArray: TArray<TValue>;
|
function TJSONRPCRequestParams.ToArray: TArray<TValue>;
|
||||||
begin
|
begin
|
||||||
Result := FParamsValue.ToArray;
|
Result := fParamValues.ToArray;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TJSONRPCRequestParams.Add(
|
procedure TJSONRPCRequestParams.Add(const Value: TValue; const ParamType: TJSONRPCParamDataType);
|
||||||
const
|
|
||||||
Value:
|
|
||||||
TValue;
|
|
||||||
const
|
|
||||||
ParamType:
|
|
||||||
TJSONRPCParamDataType);
|
|
||||||
begin
|
begin
|
||||||
FParamsValue.Add(Value);
|
CheckNotNames;
|
||||||
FParamsType.Add(ParamType);
|
fParamValues.Add(Value);
|
||||||
|
fParamTypes.Add(ParamType);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONRPCRequestParams.AddByName(const Name: string;
|
||||||
|
const Value: Boolean);
|
||||||
|
begin
|
||||||
|
AddByName(name, Value, TJSONRPCParamDataType.pdtBoolean);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONRPCRequestParams.AddByName(const Name: string;
|
||||||
|
const Value: TJDOJsonArray);
|
||||||
|
begin
|
||||||
|
AddByName(name, Value, TJSONRPCParamDataType.pdtJSONArray);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONRPCRequestParams.AddByName(const Name: string;
|
||||||
|
const Value: TJDOJsonObject);
|
||||||
|
begin
|
||||||
|
AddByName(name, Value, TJSONRPCParamDataType.pdTJDOJsonObject);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONRPCRequestParams.AddByName(const Name: string;
|
||||||
|
const Value: Integer);
|
||||||
|
begin
|
||||||
|
AddByName(name, Value, TJSONRPCParamDataType.pdtInteger);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONRPCRequestParams.AddByName(const Name, Value: string);
|
||||||
|
begin
|
||||||
|
AddByName(name, Value, TJSONRPCParamDataType.pdtString);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONRPCRequestParams.AddByName(const Name: string;
|
||||||
|
const Value: TValue; const ParamType: TJSONRPCParamDataType);
|
||||||
|
begin
|
||||||
|
CheckBalancedParams;
|
||||||
|
fParamNames.Add(LowerCase(name));
|
||||||
|
fParamValues.Add(Value);
|
||||||
|
fParamTypes.Add(ParamType);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONRPCRequestParams.AddByName(const Name: string;
|
||||||
|
const Value: Double);
|
||||||
|
begin
|
||||||
|
AddByName(name, Value, TJSONRPCParamDataType.pdtFloat);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONRPCRequestParams.AddByName(const Name: string;
|
||||||
|
const Value: TDateTime);
|
||||||
|
begin
|
||||||
|
AddByName(name, Value, TJSONRPCParamDataType.pdtDateTime);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONRPCRequestParams.AddByName(const Name: string;
|
||||||
|
const Value: TTime);
|
||||||
|
begin
|
||||||
|
AddByName(name, Value, TJSONRPCParamDataType.pdtTime);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONRPCRequestParams.AddByName(const Name: string;
|
||||||
|
const Value: TDate);
|
||||||
|
begin
|
||||||
|
AddByName(name, Value, TJSONRPCParamDataType.pdtDate);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ EMVCJSONRPCException }
|
{ EMVCJSONRPCException }
|
||||||
|
@ -40,7 +40,7 @@ type
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// URL segment that represents the path to static files
|
/// URL segment that represents the path to static files
|
||||||
/// </summary>
|
/// </summary>
|
||||||
STATIC_FILES_PATH = '/';
|
STATIC_FILES_PATH = '/static';
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Physical path of the root folder that contains the static files
|
/// Physical path of the root folder that contains the static files
|
||||||
@ -91,7 +91,8 @@ implementation
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
System.SysUtils,
|
System.SysUtils,
|
||||||
System.IOUtils;
|
System.NetEncoding,
|
||||||
|
System.IOUtils, System.Classes;
|
||||||
|
|
||||||
{ TMVCStaticFilesMiddleware }
|
{ TMVCStaticFilesMiddleware }
|
||||||
|
|
||||||
@ -194,6 +195,13 @@ begin
|
|||||||
AHandled := SendStaticFileIfPresent(AContext, lFileName);
|
AHandled := SendStaticFileIfPresent(AContext, lFileName);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
// if (not AHandled) and lPathInfo.EndsWith('favicon.ico') then
|
||||||
|
// begin
|
||||||
|
// AContext.Response.SetContentStream(TBytesStream.Create(TNetEncoding.Base64.DecodeStringToBytes(DMVC_FAVICON)),
|
||||||
|
// TMVCMediaType.IMAGE_X_ICON);
|
||||||
|
// AHandled := True;
|
||||||
|
// end;
|
||||||
|
|
||||||
if (not AHandled) and fSPAWebAppSupport and AContext.Request.ClientPreferHTML and (not fIndexDocument.IsEmpty) then
|
if (not AHandled) and fSPAWebAppSupport and AContext.Request.ClientPreferHTML and (not fIndexDocument.IsEmpty) then
|
||||||
begin
|
begin
|
||||||
lFileName := TPath.GetFullPath(TPath.Combine(fDocumentRoot, fIndexDocument));
|
lFileName := TPath.GetFullPath(TPath.Combine(fDocumentRoot, fIndexDocument));
|
||||||
|
@ -458,6 +458,11 @@ begin
|
|||||||
case lObj.DataSetSerializationType of
|
case lObj.DataSetSerializationType of
|
||||||
dstSingleRecord:
|
dstSingleRecord:
|
||||||
begin
|
begin
|
||||||
|
if TDataSet(lObj.Data).Eof then
|
||||||
|
begin
|
||||||
|
raise EMVCSerializationException.Create(HTTP_STATUS.InternalServerError,
|
||||||
|
'Cannot serialize a single record of an empty dataset');
|
||||||
|
end;
|
||||||
fCurrentSerializer.InternalSerializeDataSetRecord(
|
fCurrentSerializer.InternalSerializeDataSetRecord(
|
||||||
TDataSet(lObj.Data),
|
TDataSet(lObj.Data),
|
||||||
lOutObject.O[lName],
|
lOutObject.O[lName],
|
||||||
|
@ -37,6 +37,10 @@ type
|
|||||||
[Test]
|
[Test]
|
||||||
procedure TestRequestWithArrayParameters;
|
procedure TestRequestWithArrayParameters;
|
||||||
[Test]
|
[Test]
|
||||||
|
procedure TestRequestWithNamedParameters;
|
||||||
|
[Test]
|
||||||
|
procedure TestRequestWithMixedParamaters;
|
||||||
|
[Test]
|
||||||
procedure TestRequestWithNoParameters;
|
procedure TestRequestWithNoParameters;
|
||||||
[Test]
|
[Test]
|
||||||
procedure TestRequestWithMalformedJSON;
|
procedure TestRequestWithMalformedJSON;
|
||||||
@ -88,6 +92,44 @@ begin
|
|||||||
end, EMVCJSONRPCParseError);
|
end, EMVCJSONRPCParseError);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestJSONRPC.TestRequestWithMixedParamaters;
|
||||||
|
var
|
||||||
|
lReq: IJSONRPCRequest;
|
||||||
|
begin
|
||||||
|
lReq := TJSONRPCRequest.Create;
|
||||||
|
lReq.Method := 'subtract';
|
||||||
|
Assert.WillRaise(
|
||||||
|
procedure
|
||||||
|
begin
|
||||||
|
lReq.Params.AddByName('par1', 42);
|
||||||
|
lReq.Params.Add(42);
|
||||||
|
end, EMVCJSONRPCException);
|
||||||
|
|
||||||
|
lReq := TJSONRPCRequest.Create;
|
||||||
|
lReq.Method := 'subtract';
|
||||||
|
Assert.WillRaise(
|
||||||
|
procedure
|
||||||
|
begin
|
||||||
|
lReq.Params.Add(42);
|
||||||
|
lReq.Params.AddByName('par1', 42);
|
||||||
|
end, EMVCJSONRPCException);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestJSONRPC.TestRequestWithNamedParameters;
|
||||||
|
var
|
||||||
|
lReq: IJSONRPCRequest;
|
||||||
|
begin
|
||||||
|
lReq := TJSONRPCRequest.Create;
|
||||||
|
lReq.Method := 'subtract';
|
||||||
|
lReq.Params.AddByName('par1', 42);
|
||||||
|
lReq.Params.AddByName('PAR2', 23);
|
||||||
|
lReq.RequestID := 1;
|
||||||
|
Assert.AreEqual(1, lReq.RequestID.AsInteger);
|
||||||
|
Assert.AreEqual('par1', lReq.Params.ItemsName[0]);
|
||||||
|
Assert.AreEqual('par2', lReq.Params.ItemsName[1]);
|
||||||
|
Assert.AreEqual('subtract', lReq.Method);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TTestJSONRPC.TestRequestWithNoParameters;
|
procedure TTestJSONRPC.TestRequestWithNoParameters;
|
||||||
var
|
var
|
||||||
lReq: IJSONRPCRequest;
|
lReq: IJSONRPCRequest;
|
||||||
|
@ -220,7 +220,10 @@ type
|
|||||||
// test web server
|
// test web server
|
||||||
[Test]
|
[Test]
|
||||||
procedure TestDirectoryTraversal1;
|
procedure TestDirectoryTraversal1;
|
||||||
|
[Test]
|
||||||
|
procedure TestDirectoryTraversal2;
|
||||||
|
[Test]
|
||||||
|
procedure TestSPASupport;
|
||||||
// test server side views
|
// test server side views
|
||||||
[Test]
|
[Test]
|
||||||
procedure TestViewDataViewDataSet;
|
procedure TestViewDataViewDataSet;
|
||||||
@ -242,10 +245,18 @@ type
|
|||||||
[Test]
|
[Test]
|
||||||
procedure TestRequestWithParams_I_I_ret_I;
|
procedure TestRequestWithParams_I_I_ret_I;
|
||||||
[Test]
|
[Test]
|
||||||
|
procedure TestRequestWithNamedParams_I_I_ret_I;
|
||||||
|
[Test]
|
||||||
procedure TestRequestWithParams_I_I_I_ret_O;
|
procedure TestRequestWithParams_I_I_I_ret_O;
|
||||||
[Test]
|
[Test]
|
||||||
|
procedure TestRequestWithNamedParams_I_I_I_ret_O;
|
||||||
|
[Test]
|
||||||
|
procedure TestRequestWithWrongNamedParams;
|
||||||
|
[Test]
|
||||||
procedure TestRequest_S_I_ret_S;
|
procedure TestRequest_S_I_ret_S;
|
||||||
[Test]
|
[Test]
|
||||||
|
procedure TestRequest_NamedParams_S_I_ret_S;
|
||||||
|
[Test]
|
||||||
procedure TestRequestWithParams_I_I_ret_A;
|
procedure TestRequestWithParams_I_I_ret_A;
|
||||||
[Test]
|
[Test]
|
||||||
procedure TestRequestWithParams_DT_T_ret_DT;
|
procedure TestRequestWithParams_DT_T_ret_DT;
|
||||||
@ -1408,6 +1419,53 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TServerTest.TestDirectoryTraversal2;
|
||||||
|
var
|
||||||
|
lRes: IRESTResponse;
|
||||||
|
I: Integer;
|
||||||
|
lUrl: string;
|
||||||
|
begin
|
||||||
|
lRes := RESTClient
|
||||||
|
.Accept(TMVCMediaType.TEXT_HTML)
|
||||||
|
.doGET('/static/index.html', []);
|
||||||
|
Assert.areEqual(200, lRes.ResponseCode, '/static/index.html');
|
||||||
|
|
||||||
|
lRes := RESTClient
|
||||||
|
.Accept(TMVCMediaType.TEXT_HTML)
|
||||||
|
.doGET('/static.html', []);
|
||||||
|
Assert.areEqual(200, lRes.ResponseCode, '/static.html');
|
||||||
|
|
||||||
|
lRes := RESTClient
|
||||||
|
.Accept(TMVCMediaType.TEXT_HTML)
|
||||||
|
.doGET('/static/', []);
|
||||||
|
Assert.areEqual(200, lRes.ResponseCode, '/static/');
|
||||||
|
|
||||||
|
lRes := RESTClient
|
||||||
|
.Accept(TMVCMediaType.TEXT_HTML)
|
||||||
|
.doGET('/static', []);
|
||||||
|
Assert.areEqual(200, lRes.ResponseCode, '/static');
|
||||||
|
|
||||||
|
lRes := RESTClient
|
||||||
|
.Accept(TMVCMediaType.TEXT_HTML)
|
||||||
|
.doGET('/static/..\..\donotdeleteme.txt', []);
|
||||||
|
Assert.areEqual(404, lRes.ResponseCode);
|
||||||
|
|
||||||
|
lRes := RESTClient
|
||||||
|
.Accept(TMVCMediaType.TEXT_HTML)
|
||||||
|
.doGET('/static/../../donotdeleteme.txt', []);
|
||||||
|
Assert.areEqual(404, lRes.ResponseCode);
|
||||||
|
|
||||||
|
lUrl := 'Windows\win.ini';
|
||||||
|
for I := 1 to 30 do
|
||||||
|
begin
|
||||||
|
lUrl := '..\' + lUrl;
|
||||||
|
lRes := RESTClient
|
||||||
|
.Accept(TMVCMediaType.TEXT_HTML)
|
||||||
|
.doGET('/' + lUrl, []);
|
||||||
|
Assert.areEqual(404, lRes.ResponseCode, 'Fail with: ' + '/' + lUrl);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TServerTest.TestSerializeAndDeserializeNullables;
|
procedure TServerTest.TestSerializeAndDeserializeNullables;
|
||||||
var
|
var
|
||||||
lRes: IRESTResponse;
|
lRes: IRESTResponse;
|
||||||
@ -1544,6 +1602,46 @@ begin
|
|||||||
DoLogout;
|
DoLogout;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TServerTest.TestSPASupport;
|
||||||
|
var
|
||||||
|
lRes: IRESTResponse;
|
||||||
|
I: Integer;
|
||||||
|
lUrl: string;
|
||||||
|
begin
|
||||||
|
lRes := RESTClient
|
||||||
|
.Accept(TMVCMediaType.TEXT_HTML)
|
||||||
|
.doGET('/static/index.html', []);
|
||||||
|
Assert.areEqual(200, lRes.ResponseCode);
|
||||||
|
Assert.Contains(lRes.BodyAsString, 'This is a TEXT file');
|
||||||
|
|
||||||
|
lRes := RESTClient
|
||||||
|
.Accept(TMVCMediaType.TEXT_HTML)
|
||||||
|
.doGET('/static/', []);
|
||||||
|
Assert.areEqual(200, lRes.ResponseCode, '/static/');
|
||||||
|
Assert.Contains(lRes.BodyAsString, 'This is a TEXT file');
|
||||||
|
|
||||||
|
lRes := RESTClient
|
||||||
|
.Accept(TMVCMediaType.TEXT_HTML)
|
||||||
|
.doGET('/static/..\..\donotdeleteme.txt', []);
|
||||||
|
Assert.areEqual(404, lRes.ResponseCode, '/static/..\..\donotdeleteme.txt');
|
||||||
|
|
||||||
|
lRes := RESTClient
|
||||||
|
.Accept(TMVCMediaType.TEXT_HTML)
|
||||||
|
.doGET('/static/../../donotdeleteme.txt', []);
|
||||||
|
Assert.areEqual(404, lRes.ResponseCode, '/static/../../donotdeleteme.txt');
|
||||||
|
Assert.Contains(lRes.Error.ExceptionMessage, 'Not Found', true);
|
||||||
|
|
||||||
|
lUrl := 'Windows\win.ini';
|
||||||
|
for I := 1 to 30 do
|
||||||
|
begin
|
||||||
|
lUrl := '..\' + lUrl;
|
||||||
|
lRes := RESTClient
|
||||||
|
.Accept(TMVCMediaType.TEXT_HTML)
|
||||||
|
.doGET('/' + lUrl, []);
|
||||||
|
Assert.areEqual(404, lRes.ResponseCode, 'Fail with: ' + '/' + lUrl);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TServerTest.TestStringDictionary;
|
procedure TServerTest.TestStringDictionary;
|
||||||
var
|
var
|
||||||
lRes: IRESTResponse;
|
lRes: IRESTResponse;
|
||||||
@ -1853,6 +1951,65 @@ begin
|
|||||||
Assert.areEqual(2000, lYear);
|
Assert.areEqual(2000, lYear);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TJSONRPCServerTest.TestRequestWithWrongNamedParams;
|
||||||
|
var
|
||||||
|
lReq: IJSONRPCRequest;
|
||||||
|
lRPCResp: IJSONRPCResponse;
|
||||||
|
begin
|
||||||
|
lReq := TJSONRPCRequest.Create;
|
||||||
|
lReq.Method := 'add';
|
||||||
|
lReq.Params.AddByName('wrongname1', 3);
|
||||||
|
lReq.Params.AddByName('wrongname2', 4);
|
||||||
|
lReq.Params.AddByName('wrongname3', 5);
|
||||||
|
lReq.RequestID := 1234;
|
||||||
|
|
||||||
|
lRPCResp := FExecutor.ExecuteRequest(lReq);
|
||||||
|
Assert.isTrue(lRPCResp.IsError);
|
||||||
|
Assert.Contains(lRPCResp.Error.ErrMessage, 'cannot map all parameter', true);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONRPCServerTest.TestRequestWithNamedParams_I_I_I_ret_O;
|
||||||
|
var
|
||||||
|
lReq: IJSONRPCRequest;
|
||||||
|
lRPCResp: IJSONRPCResponse;
|
||||||
|
lS: string;
|
||||||
|
begin
|
||||||
|
lReq := TJSONRPCRequest.Create;
|
||||||
|
lReq.Method := 'add';
|
||||||
|
lReq.Params.AddByName('value1', 3);
|
||||||
|
lReq.Params.AddByName('value2', 4);
|
||||||
|
lReq.Params.AddByName('value3', 5);
|
||||||
|
lReq.RequestID := 1234;
|
||||||
|
|
||||||
|
lRPCResp := FExecutor.ExecuteRequest(lReq);
|
||||||
|
lS := (lRPCResp.Result.AsObject as TJDOJsonObject).ToJSON();
|
||||||
|
Assert.areEqual(12, TJDOJsonObject(lRPCResp.Result.AsObject).I['res']);
|
||||||
|
|
||||||
|
lRPCResp := FExecutor2.ExecuteRequest(lReq);
|
||||||
|
lS := (lRPCResp.Result.AsObject as TJDOJsonObject).ToJSON();
|
||||||
|
Assert.areEqual(12, TJDOJsonObject(lRPCResp.Result.AsObject).I['res']);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONRPCServerTest.TestRequestWithNamedParams_I_I_ret_I;
|
||||||
|
var
|
||||||
|
lReq: IJSONRPCRequest;
|
||||||
|
lResp: IJSONRPCResponse;
|
||||||
|
begin
|
||||||
|
lReq := TJSONRPCRequest.Create;
|
||||||
|
lReq.RequestID := 1234;
|
||||||
|
lReq.Method := 'subtract';
|
||||||
|
lReq.Params.AddByName('Value1', 18);
|
||||||
|
lReq.Params.AddByName('Value2', 8);
|
||||||
|
|
||||||
|
lResp := FExecutor.ExecuteRequest(lReq);
|
||||||
|
Assert.areEqual(10, lResp.Result.AsInteger);
|
||||||
|
Assert.areEqual(1234, lResp.RequestID.AsInteger);
|
||||||
|
|
||||||
|
lResp := FExecutor2.ExecuteRequest(lReq);
|
||||||
|
Assert.areEqual(10, lResp.Result.AsInteger);
|
||||||
|
Assert.areEqual(1234, lResp.RequestID.AsInteger);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TJSONRPCServerTest.TestRequestWithoutParams;
|
procedure TJSONRPCServerTest.TestRequestWithoutParams;
|
||||||
var
|
var
|
||||||
lReq: IJSONRPCNotification;
|
lReq: IJSONRPCNotification;
|
||||||
@ -1874,6 +2031,7 @@ begin
|
|||||||
lReq.Method := 'subtract';
|
lReq.Method := 'subtract';
|
||||||
lReq.Params.Add(18);
|
lReq.Params.Add(18);
|
||||||
lReq.Params.Add(8);
|
lReq.Params.Add(8);
|
||||||
|
|
||||||
lResp := FExecutor.ExecuteRequest(lReq);
|
lResp := FExecutor.ExecuteRequest(lReq);
|
||||||
Assert.areEqual(10, lResp.Result.AsInteger);
|
Assert.areEqual(10, lResp.Result.AsInteger);
|
||||||
Assert.areEqual(1234, lResp.RequestID.AsInteger);
|
Assert.areEqual(1234, lResp.RequestID.AsInteger);
|
||||||
@ -1939,6 +2097,24 @@ begin
|
|||||||
Assert.areEqual(12, TJDOJsonObject(lRPCResp.Result.AsObject).I['res']);
|
Assert.areEqual(12, TJDOJsonObject(lRPCResp.Result.AsObject).I['res']);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TJSONRPCServerTest.TestRequest_NamedParams_S_I_ret_S;
|
||||||
|
var
|
||||||
|
lReq: IJSONRPCRequest;
|
||||||
|
lRPCResp: IJSONRPCResponse;
|
||||||
|
begin
|
||||||
|
lReq := TJSONRPCRequest.Create;
|
||||||
|
lReq.Method := 'MultiplyString';
|
||||||
|
lReq.Params.AddByName('aString', 'Daniele');
|
||||||
|
lReq.Params.AddByName('Multiplier', 4);
|
||||||
|
lReq.RequestID := 1234;
|
||||||
|
lRPCResp := FExecutor.ExecuteRequest(lReq);
|
||||||
|
Assert.isFalse(lRPCResp.IsError);
|
||||||
|
Assert.areEqual('DanieleDanieleDanieleDaniele', lRPCResp.Result.AsString);
|
||||||
|
|
||||||
|
lRPCResp := FExecutor2.ExecuteRequest(lReq);
|
||||||
|
Assert.areEqual('DanieleDanieleDanieleDaniele', lRPCResp.Result.AsString);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TJSONRPCServerTest.TestRequest_S_I_ret_S;
|
procedure TJSONRPCServerTest.TestRequest_S_I_ret_S;
|
||||||
var
|
var
|
||||||
lReq: IJSONRPCRequest;
|
lReq: IJSONRPCRequest;
|
||||||
|
@ -28,17 +28,6 @@
|
|||||||
<CfgParent>Base</CfgParent>
|
<CfgParent>Base</CfgParent>
|
||||||
<Base>true</Base>
|
<Base>true</Base>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
|
|
||||||
<Cfg_1>true</Cfg_1>
|
|
||||||
<CfgParent>Base</CfgParent>
|
|
||||||
<Base>true</Base>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''">
|
|
||||||
<Cfg_1_Win32>true</Cfg_1_Win32>
|
|
||||||
<CfgParent>Cfg_1</CfgParent>
|
|
||||||
<Cfg_1>true</Cfg_1>
|
|
||||||
<Base>true</Base>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Config)'=='CI' or '$(Cfg_2)'!=''">
|
<PropertyGroup Condition="'$(Config)'=='CI' or '$(Cfg_2)'!=''">
|
||||||
<Cfg_2>true</Cfg_2>
|
<Cfg_2>true</Cfg_2>
|
||||||
<CfgParent>Base</CfgParent>
|
<CfgParent>Base</CfgParent>
|
||||||
@ -117,17 +106,6 @@
|
|||||||
<PropertyGroup Condition="'$(Base_Win64)'!=''">
|
<PropertyGroup Condition="'$(Base_Win64)'!=''">
|
||||||
<Icon_MainIcon>TestServer_Icon.ico</Icon_MainIcon>
|
<Icon_MainIcon>TestServer_Icon.ico</Icon_MainIcon>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Cfg_1)'!=''">
|
|
||||||
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
|
|
||||||
<DCC_DebugInformation>0</DCC_DebugInformation>
|
|
||||||
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
|
|
||||||
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
|
|
||||||
<VerInfo_Locale>1033</VerInfo_Locale>
|
|
||||||
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)</VerInfo_Keys>
|
|
||||||
<Icon_MainIcon>TestServer_Icon.ico</Icon_MainIcon>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Cfg_2)'!=''">
|
<PropertyGroup Condition="'$(Cfg_2)'!=''">
|
||||||
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
|
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
|
||||||
<DCC_Optimize>false</DCC_Optimize>
|
<DCC_Optimize>false</DCC_Optimize>
|
||||||
@ -171,10 +149,6 @@
|
|||||||
<BuildConfiguration Include="Base">
|
<BuildConfiguration Include="Base">
|
||||||
<Key>Base</Key>
|
<Key>Base</Key>
|
||||||
</BuildConfiguration>
|
</BuildConfiguration>
|
||||||
<BuildConfiguration Include="Release">
|
|
||||||
<Key>Cfg_1</Key>
|
|
||||||
<CfgParent>Base</CfgParent>
|
|
||||||
</BuildConfiguration>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ProjectExtensions>
|
<ProjectExtensions>
|
||||||
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
|
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
|
||||||
|
@ -8,18 +8,18 @@ uses
|
|||||||
type
|
type
|
||||||
TTestJSONRPCController = class(TMVCJSONRPCController)
|
TTestJSONRPCController = class(TMVCJSONRPCController)
|
||||||
public
|
public
|
||||||
function Subtract(aValue1, aValue2: Int64): Integer;
|
function Subtract(Value1, Value2: Int64): Integer;
|
||||||
procedure MyNotify;
|
procedure MyNotify;
|
||||||
function Add(aValue1, aValue2, aValue3: Int64): TJsonObject;
|
function Add(Value1, Value2, Value3: Int64): TJsonObject;
|
||||||
function GetListFromTo(aFrom, aTo: Int64): TJsonArray;
|
function GetListFromTo(aFrom, aTo: Int64): TJsonArray;
|
||||||
function MultiplyString(aString: string; Multiplier: Int64): string;
|
function MultiplyString(aString: string; Multiplier: Int64): string;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TTestJSONRPCClass = class(TObject)
|
TTestJSONRPCClass = class(TObject)
|
||||||
public
|
public
|
||||||
function Subtract(aValue1, aValue2: Int64): Integer;
|
function Subtract(Value1, Value2: Int64): Integer;
|
||||||
procedure MyNotify;
|
procedure MyNotify;
|
||||||
function Add(aValue1, aValue2, aValue3: Int64): TJsonObject;
|
function Add(Value1, Value2, Value3: Int64): TJsonObject;
|
||||||
function GetListFromTo(aFrom, aTo: Int64): TJsonArray;
|
function GetListFromTo(aFrom, aTo: Int64): TJsonArray;
|
||||||
function MultiplyString(aString: string; Multiplier: Int64): string;
|
function MultiplyString(aString: string; Multiplier: Int64): string;
|
||||||
function AddTimeToDateTime(aDateTime: TDateTime; aTime: TTime): TDateTime;
|
function AddTimeToDateTime(aDateTime: TDateTime; aTime: TTime): TDateTime;
|
||||||
@ -32,10 +32,10 @@ uses
|
|||||||
|
|
||||||
{ TTestJSONRPCController }
|
{ TTestJSONRPCController }
|
||||||
|
|
||||||
function TTestJSONRPCController.Add(aValue1, aValue2, aValue3: Int64): TJsonObject;
|
function TTestJSONRPCController.Add(Value1, Value2, Value3: Int64): TJsonObject;
|
||||||
begin
|
begin
|
||||||
Result := TJsonObject.Create;
|
Result := TJsonObject.Create;
|
||||||
Result.I['res'] := aValue1 + aValue2 + aValue3;
|
Result.I['res'] := Value1 + Value2 + Value3;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TTestJSONRPCController.GetListFromTo(aFrom, aTo: Int64): TJsonArray;
|
function TTestJSONRPCController.GetListFromTo(aFrom, aTo: Int64): TJsonArray;
|
||||||
@ -65,17 +65,17 @@ begin
|
|||||||
Self.ClassName;
|
Self.ClassName;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TTestJSONRPCController.Subtract(aValue1, aValue2: Int64): Integer;
|
function TTestJSONRPCController.Subtract(Value1, Value2: Int64): Integer;
|
||||||
begin
|
begin
|
||||||
Result := aValue1 - aValue2;
|
Result := Value1 - Value2;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TTestJSONRPCClass }
|
{ TTestJSONRPCClass }
|
||||||
|
|
||||||
function TTestJSONRPCClass.Add(aValue1, aValue2, aValue3: Int64): TJsonObject;
|
function TTestJSONRPCClass.Add(Value1, Value2, Value3: Int64): TJsonObject;
|
||||||
begin
|
begin
|
||||||
Result := TJsonObject.Create;
|
Result := TJsonObject.Create;
|
||||||
Result.I['res'] := aValue1 + aValue2 + aValue3;
|
Result.I['res'] := Value1 + Value2 + Value3;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TTestJSONRPCClass.AddTimeToDateTime(aDateTime: TDateTime;
|
function TTestJSONRPCClass.AddTimeToDateTime(aDateTime: TDateTime;
|
||||||
@ -111,9 +111,9 @@ begin
|
|||||||
Self.ClassName;
|
Self.ClassName;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TTestJSONRPCClass.Subtract(aValue1, aValue2: Int64): Integer;
|
function TTestJSONRPCClass.Subtract(Value1, Value2: Int64): Integer;
|
||||||
begin
|
begin
|
||||||
Result := aValue1 - aValue2;
|
Result := Value1 - Value2;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
@ -98,7 +98,9 @@ begin
|
|||||||
Result := TTestFault2Controller.Create; // this will raise an exception
|
Result := TTestFault2Controller.Create; // this will raise an exception
|
||||||
end)
|
end)
|
||||||
.AddMiddleware(TMVCSpeedMiddleware.Create)
|
.AddMiddleware(TMVCSpeedMiddleware.Create)
|
||||||
.AddMiddleware(TMVCStaticFilesMiddleware.Create('/', '..\www'))
|
.AddMiddleware(TMVCStaticFilesMiddleware.Create('/', '..\www', 'index.html', False))
|
||||||
|
.AddMiddleware(TMVCStaticFilesMiddleware.Create('/static', '..\www', 'index.html', False))
|
||||||
|
.AddMiddleware(TMVCStaticFilesMiddleware.Create('/spa', '..\www', 'index.html', True))
|
||||||
.AddMiddleware(TMVCBasicAuthenticationMiddleware.Create(TBasicAuthHandler.Create))
|
.AddMiddleware(TMVCBasicAuthenticationMiddleware.Create(TBasicAuthHandler.Create))
|
||||||
.AddMiddleware(TMVCCustomAuthenticationMiddleware.Create(TCustomAuthHandler.Create, '/system/users/logged'))
|
.AddMiddleware(TMVCCustomAuthenticationMiddleware.Create(TCustomAuthHandler.Create, '/system/users/logged'))
|
||||||
.AddMiddleware(TMVCCompressionMiddleware.Create);
|
.AddMiddleware(TMVCCompressionMiddleware.Create);
|
||||||
|
1
unittests/general/TestServer/www/static.html
Normal file
1
unittests/general/TestServer/www/static.html
Normal file
@ -0,0 +1 @@
|
|||||||
|
This is a TEXT file named STATIC.html
|
Loading…
Reference in New Issue
Block a user