Forum Replies Created
-
AuthorPosts
-
-
February 19, 2019 at 19:13 #53442
Decoder
ParticipantThanks Kim. By the time you posted this I had figured it out. Good example though.
In researching this I found the following mime type:
vnd.android.package-archive
The reason this is relevant is because my ‘zip’ file is an apk. Which is essentially a zip file, with a custom extension. I didn’t find that mime type in kbmMWCustomHTTPService.pas, procedure TkbmMWHTTPServiceDefinition.SetupStandardMimeTypes.
Is there a location where it would make sense to add this mime type? I did get it working with the following code:
Result := HTTPResponseFromFile(‘AppFileDir\AppFile.apk’,’AppFile.apk’);
SetResponseFileName(‘AppFile.apk’);
SetResponseMimeType(‘vnd.android.package-archive’);
SetResponseContentType(‘UTF-8’);It seems that Android likes that MimeType ‘more better’ than application/octet-stream.
Thanks again Kim.
-
February 14, 2019 at 02:04 #53432
Decoder
ParticipantOk, figured that out, it’s the AMapPath: Boolean = True param in HTTPResponseFromFile that was messing me up.
Now I get the file, but the client treats it as a web page, even though I’ve specified the content type as responseMimeType:”application/octet-stream”,
and displays the content of the zip file in the browser view.
So I guess I’m looking for the param, attribute, call, switch, component, property etc. that tells the request/response mechanism that this is a file, and specifies the file name.
Been browsing through your demos, but have not found anything that would demonstrate how to do this via a REST request.
Help!
-
February 13, 2019 at 22:59 #53431
Decoder
ParticipantI found this:
function HTTPResponseFromFile(const APath:string; const AAsFileName:string; const AMapPath:boolean = true):variant; overload;
…in the public interface of TkbmMWCustomHTTPService. I added a file pool to my smart service, creating it in the constructor with the service as the owner, and set the properties to match the properties in Demo\FileTransferStress\Server\Unit1.pas, and finally I assigned the file pool component to the smart service’s filepool property.
The test file store is a linux folder masked 777. When I call the service method, the response I get is:
“Cant access file:<file path as designated at runtime>”.
I checked the path, it’s totally valid. What have I missed?
Thanks.
-
December 20, 2018 at 18:36 #53361
Decoder
ParticipantHi Kim!
I’ve included code below that illustrates how I coded this process. If I understood you correctly, I’m responsible for freeing the kbmMemTable’s that I create in the methods below, correct?
Thanks
[kbmMW_Service(‘name:<myServiceName>, flags:[listed]’)]
[kbmMW_Rest(‘path:/<myPath>’)]
TMyService = class(TkbmMWCustomHTTPSmartService)
private
FData: TkbmServerData;…
public
// allergies
[kbmMW_Rest(‘method:get, path:allergies, anonymousResult:true, responseMimeType:”application/json”‘)]
function Allergies([kbmMW_Rest(‘value: “$AnInt”, required: true’)] const AnInt: Integer): TkbmMemTable;// Pt Chart
[kbmMW_Rest(‘method:get, path:ptchart, anonymousResult:true, responseMimeType:”application/json”‘)]
function PtChart: TPtChart;end;
…
implementation
…
function TMyService.Allergies(const AnInt: Integer): TkbmMemTable;
begin
Result := Nil;
if Authorized then
Result := FData.Allergies[AnInt];
end;
end;function TMyService.PtChart: TPtChart;
begin
if Authorized then
begin
Result := TPtChart.Create;
Result.Allergies := Allergies(32126);…
end;
…
initialization
kbmMWRegisterKnownClasses([TPtChart]);type
TkbmServerData = class(TComponent)
kAllergies: TkbmMemTable;…
private
…
function GetAllergies(AnInt: Integer = 0): TkbmMemTable;…
public
property Allergies[AnInt: Integer]: TkbmMemTable read GetAllergies;…
end;
…
implementation
…
function TkbmServerData.GetAllergies(AnInt: Integer): TkbmMemTable;
var
oraprof: TOraQueryProfile;
sErrorMsg: AnsiString;
fldKey,fldAllergies,fldReaction: TField;
begin
if AnInt > 0 then
begin
if not Assigned(kAllergies) then
kAllergies := TkbmMemTable.Create(Self);oraprof := TOraQueryProfile.Create(Self,FSession,QAllergies,KSQLAllergies);
oraprof.AddParam(‘FKEY’,otInteger,FKEY);
QAllergies.Open;with kAllergies.FieldDefs.AddFieldDef do
begin
Name := ‘1’;
DataType := ftString;
end;
kAllergies.LoadFromDataSet(QAllergies,[mtcpoStructure,mtcpoFieldIndex]);
Result := kAllergies;
end;
end; -
December 18, 2018 at 23:17 #53349
Decoder
ParticipantThanks Kim –
In the intervening time between my post and your response, I found the helper and had started to try to work with it. Your timely blog post helped shorten the curve. 🙂
Just an FYI, in trying to load test a server I run multiple instances of a client app that runs a sequential loop, iterating through the list of available methods and issuing requests/logging responses.
One of the methods on the server returns a class – converted to JSON of course – that pulls all data from all of the requests. This works well thanks to your excellent design. However I’m sometimes getting memory leak errors when I shut down the server, related to the class.
I don’t explicitly destroy the class as I read in one of your blog posts that the service handles destruction of classes that are created within it’s domain.
Here’s the class:
TPtChart = class
public
Allergies: TkbmMemTable;
HomeMeds: TkbmMemTable;
LabResults: UnicodeString;
MDNotes: UnicodeString;
RadResults: UnicodeString;
RNNotes: UnicodeString;
Vitals: TkbmMemTable;
end;Here’s the service method declaration:
// Pt Chart
[kbmMW_Rest(‘method:get, path:ptchart, anonymousResult:true, responseMimeType:”application/json”‘)]
function PtChart: TPtChart;Here’s the service method implementation:
function TWellRESTFunctionsService.PtChart: TPtChart;
begin
if Authorized then
begin
Result := TPtChart.Create;
Result.Allergies := Allergies(32126);
Result.HomeMeds := HomeMeds(27390);
Result.LabResults := LabResults(27390,’ANDROID’);
Result.MDNotes := MDNotes(27390,’ANDROID’);
Result.RadResults := RadResults(32227,’ANDROID’);;
Result.RNNotes := RNNotes(27390,’ANDROID’);
Result.Vitals := AllVitals(32126);
end;
end;This method executes quickly and returns all of the required data without issue. Can you see why this would leak at the server side? Is there more to be done here?
Thanks.
-
-
AuthorPosts
