mirror of
https://github.com/danieleteti/delphimvcframework.git
synced 2024-11-15 07:45:54 +01:00
Improved SPA support
This commit is contained in:
parent
eb112316f7
commit
530084271b
@ -342,6 +342,7 @@ Render(lPerson, False,
|
||||
- New! `TMVCActiveRecord.Count` method (e.g. `TMVCActiveRecord.Count(TCustomer)` returns the number of records for the entity mapped by the class `TCustomer`)
|
||||
- Change! `TMVCACtiveRecord.GetByPK<T>` raises an exception by default if the record is not found - optionally can returns `nil` using new parameter `RaiseExceptionIfNotFound`
|
||||
- New! `contains` clause has been added in the RQL compiler for Firebird and Interbase
|
||||
- New! Added support out operator in RQL parser. The RQL out operator is equivalent to the SQL NOT IN operator.
|
||||
- New! `TMVCAnalyticsMiddleware` to do automatic analytics on the API (generates a CSV file). Based on an idea by Nirav Kaku (https://www.facebook.com/nirav.kaku). Check the sample in `\samples\middleware_analytics\`
|
||||
- New! `TMVCActiveRecord.DeleteAll` deletes all the records from a table
|
||||
- New! `TMVCActiveRecord.DeleteRQL` deletes records using an `RQL` expression as `where` clause.
|
||||
|
@ -3,5 +3,6 @@
|
||||
<body>
|
||||
<h1>This is the index.html file</h1>
|
||||
<h2>Folder: www</h2>
|
||||
<script src="js/app.js"></script>
|
||||
</body>
|
||||
</html>
|
4
samples/middleware_staticfiles/bin/www/js/app.js
Normal file
4
samples/middleware_staticfiles/bin/www/js/app.js
Normal file
@ -0,0 +1,4 @@
|
||||
window.addEventListener('load', (event) => {
|
||||
console.log('The page has fully loaded');
|
||||
alert('The page has fully loaded');
|
||||
});
|
@ -124,7 +124,7 @@ constructor TMVCStaticFilesMiddleware.Create(
|
||||
const AStaticFilesCharset: string = TMVCStaticFilesDefaults.STATIC_FILES_CONTENT_CHARSET);
|
||||
begin
|
||||
inherited Create;
|
||||
fStaticFilesPath := AStaticFilesPath;
|
||||
fStaticFilesPath := AStaticFilesPath;
|
||||
fDocumentRoot := TPath.Combine(AppPath, ADocumentRoot);
|
||||
fIndexDocument := AIndexDocument;
|
||||
fStaticFilesCharset := AStaticFilesCharset;
|
||||
@ -175,6 +175,23 @@ begin
|
||||
Exit;
|
||||
end;
|
||||
|
||||
{
|
||||
If user ask for
|
||||
www.server.it/folder
|
||||
the browser is redirected to
|
||||
www.server.it/folder/
|
||||
}
|
||||
if SameText(lPathInfo, fStaticFilesPath) then
|
||||
begin
|
||||
if (not lPathInfo.EndsWith('/')) and (not fIndexDocument.IsEmpty) then
|
||||
begin
|
||||
AContext.Response.StatusCode := HTTP_STATUS.MovedPermanently;
|
||||
AContext.Response.CustomHeaders.Values['Location'] := lPathInfo + '/';
|
||||
AHandled := True;
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
if not((fStaticFilesPath = '/') or (fStaticFilesPath = '')) then
|
||||
begin
|
||||
lPathInfo := lPathInfo.Remove(0, fStaticFilesPath.Length);
|
||||
|
@ -223,6 +223,8 @@ type
|
||||
[Test]
|
||||
procedure TestDirectoryTraversal2;
|
||||
[Test]
|
||||
procedure TestDirectoryRedirect;
|
||||
[Test]
|
||||
procedure TestSPASupport;
|
||||
// test server side views
|
||||
[Test]
|
||||
@ -1392,6 +1394,22 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TServerTest.TestDirectoryRedirect;
|
||||
var
|
||||
lRes: IRESTResponse;
|
||||
begin
|
||||
lRes := RESTClient
|
||||
.Accept(TMVCMediaType.TEXT_HTML)
|
||||
.doGET('/static/', []);
|
||||
Assert.areEqual(200, lRes.ResponseCode, '/static/');
|
||||
|
||||
lRes := RESTClient
|
||||
.Accept(TMVCMediaType.TEXT_HTML)
|
||||
.doGET('/static', []);
|
||||
Assert.areEqual(301, lRes.ResponseCode, '/static');
|
||||
Assert.areEqual('/static/', lRes.HeaderValue('Location'), 'Wrong redirect');
|
||||
end;
|
||||
|
||||
procedure TServerTest.TestDirectoryTraversal1;
|
||||
var
|
||||
lRes: IRESTResponse;
|
||||
@ -1435,16 +1453,6 @@ begin
|
||||
.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', []);
|
||||
@ -1610,26 +1618,21 @@ var
|
||||
begin
|
||||
lRes := RESTClient
|
||||
.Accept(TMVCMediaType.TEXT_HTML)
|
||||
.doGET('/static/index.html', []);
|
||||
.doGET('/spa/index.html', []);
|
||||
Assert.areEqual(200, lRes.ResponseCode);
|
||||
Assert.Contains(lRes.BodyAsString, 'This is a TEXT file');
|
||||
|
||||
lRes := RESTClient
|
||||
.Accept(TMVCMediaType.TEXT_HTML)
|
||||
.doGET('/static/', []);
|
||||
.doGET('/spa/', []);
|
||||
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);
|
||||
.doGET('/spa/pippo/pluto/paperino', []);
|
||||
Assert.areEqual(200, lRes.ResponseCode, '/spa/pippo/pluto/paperino');
|
||||
Assert.Contains(lRes.BodyAsString, 'This is a TEXT file');
|
||||
|
||||
lUrl := 'Windows\win.ini';
|
||||
for I := 1 to 30 do
|
||||
@ -1637,8 +1640,9 @@ begin
|
||||
lUrl := '..\' + lUrl;
|
||||
lRes := RESTClient
|
||||
.Accept(TMVCMediaType.TEXT_HTML)
|
||||
.doGET('/' + lUrl, []);
|
||||
Assert.areEqual(404, lRes.ResponseCode, 'Fail with: ' + '/' + lUrl);
|
||||
.doGET('/spa/' + lUrl, []);
|
||||
Assert.areEqual(200, lRes.ResponseCode);
|
||||
Assert.Contains(lRes.BodyAsString, 'This is a TEXT file');
|
||||
end;
|
||||
end;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user