#1 2015-10-08 11:29:11

squirrel
Member
Registered: 2015-08-13
Posts: 155

Serve files compiled into the exe

Is it possible to serve files/resources that are compiled into the executable? 

I am busy creating a bunch of javascript files which will be used to access the interfaces defined in the mormot service.  Ideally I would like these files to be accessible similar to http://mormotserver:888/root/files/usermanagement.js. But I do not want them in a folder on the disk where anyone can edit them and claim I provided them in a different state than I did.  Having them compiled in as a resource also ensures that these files are always at the same version as the rest of the executable.

I use mormot authentication and they would have to be available to unauthenticated users, since the login pages will need them.

Does anybody have any practical ideas or pointers on how to achieve this?

Offline

#2 2015-10-08 11:57:18

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,666
Website

Re: Serve files compiled into the exe

You could simply use ResourceToRawByteString or ResourceSynLZToRawByteString functions to retrieve the content as a blob, ready to be sent back to the client.

The easiest is to define a method-based service named "Files", like this:

procedure TMyRestServer.Files(Ctxt: TSQLRestServerURIContext);
var fn: TFileName;
    blob: RawByteString;
begin
  if Ctxt.Method<>mGet then
    exit;
  UTF8ToString(Ctxt.URIBlobFieldName,fn);
  ResourceToRawByteString(fn,PChar(10),blob);
  if blob<>'' then
    Ctxt.ReturnBlob(blob,200,true,fn) else
    Ctxt.Error('',HTML_NOTFOUND);
end;

Note that the resource name should contain the file name extension (.js) to return the expected mime type.

Offline

#3 2015-10-08 12:11:46

squirrel
Member
Registered: 2015-08-13
Posts: 155

Re: Serve files compiled into the exe

Thanks, this looks exactly like what I need.  Were there any recent changes to UTF8ToString and ReturnBlob?  The compiler doesn't expect the fn parameter as well in these 2 functions.

Offline

#4 2015-10-08 12:28:29

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,666
Website

Re: Serve files compiled into the exe

Offline

#5 2015-10-08 12:40:00

squirrel
Member
Registered: 2015-08-13
Posts: 155

Re: Serve files compiled into the exe

This is excellent!  Works like a dream! Thanks ab!

For future users, resource names are not allowed to contain a fullstop . So I name the resources the same as the filename, but just exclude the fullstop in the resource name.  Then when loading the resource, instead of the filename, I use:

  ResourceToRawByteString(ReplaceStr(fn, '.', ''), PChar(10), blob);

and leave the rest as-is.

Last edited by squirrel (2015-10-08 12:41:42)

Offline

#6 2015-10-08 17:32:28

danielkuettner
Member
From: Germany
Registered: 2014-08-06
Posts: 357

Re: Serve files compiled into the exe

I can't see a difference between sending a js from an exe or from a file-system on the server.
In both cases the user could change the file on the client.

Offline

#7 2015-10-09 04:46:08

squirrel
Member
Registered: 2015-08-13
Posts: 155

Re: Serve files compiled into the exe

@daniel: I fully agree about client side, opening firebug and making changes to loaded code is childsplay.  But the issue here is server side when you distribute software to sites that you do not administer yourself.  In this scenario, you want the js files to always be at the same version as the exe (updated together) and not give the local site admins the option to permanently change the js files on server side to impact an sla. 

Admins are supposed to be the responsible ones, but that does not change reality.  When you deal with partial upgrades or custom changes done by someone else's admins and it impacts your application's stability, you want to package as much together as possible.

Offline

#8 2015-12-17 07:12:59

squirrel
Member
Registered: 2015-08-13
Posts: 155

Re: Serve files compiled into the exe

@ab: The method based service you provided works perfectly and I am currently using it to serve .js files without issue.  I currently use ServiceMethodByPassAuthentication to ensure these files can be served before log in.

I now need to be able to serve some files only to authenticated users.  I tried 2 approaches without success and would be very happy if you can give some advice.

First I copied the working method above, gave it a new name and then didn't bypass authentication for it.  Requests to this method always results in 403 Forbidden.
Secondly as an alternative, I added it to one of my interfaces (which I prefer since it keeps related code together).  But I'm not sure how to impliment it / what the return type must be.  This just always returns {"result":[]}

Offline

#9 2015-12-17 08:16:43

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,666
Website

Re: Serve files compiled into the exe

To have an interface-based service method return any content, see http://synopse.info/files/html/Synopse% … #TITLE_447

You could use the very same method-based service, and use the Ctxt.Session* properties to check if the user is currently authenticated.

Offline

#10 2016-01-28 08:19:32

squirrel
Member
Registered: 2015-08-13
Posts: 155

Re: Serve files compiled into the exe

@ab  Would it be possible to use this method to serve files without explicitly calling the Files function?  Similarly, is it possible to have an empty root?

So that for example this url: http://localhost:8080/root/files/myfile.html
would become: http://localhost:8080/myfile.html

I assume that one way of using the files method as default would be to register it as an error handler for Error 400s, which would allow me to use custom pages for errors such as 500, 404 etc

Any advice?

Offline

#11 2016-01-28 08:26:39

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,666
Website

Re: Serve files compiled into the exe

There is some advanced routing features at mORMotHTTPServer.pas level.
See e.g. TSQLHttpServer.DomainHostRedirect() and TSQLHttpServer.RootRedirectToURI().

Offline

#12 2016-01-28 10:16:04

squirrel
Member
Registered: 2015-08-13
Posts: 155

Re: Serve files compiled into the exe

Thanks, that sounds exactly like what I need, but I'm not sure how to make it work.  The server runs locally on an intranet server called demoserver on port 8080.

Without redirecting, I am able to access a file using either http://localhost:8080/root/files/login.html or http://demoserver:8080/root/files/login.html
These same urls still work with redirecting, but the Ctxt.URIBlobFieldname changes to include the root/files/ which it didn't before
However, even with redirection, I am unable to access the files function using http://localhost:8080/login.html
It doesnt enter the files method and returns a 503 Service Unavailable error

Using the documentation, I tried all of the following

aHttpServer.DomainHostRedirect('localhost', 'root/files');
aHttpServer.DomainHostRedirect('localhost:8080', 'root/files');
aHttpServer.DomainHostRedirect('demoserver', 'root/files');
aHttpServer.DomainHostRedirect('demoserver:8080', 'root/files');

using

aHttpServer.RootRedirectToURI('root/files');

causes a visit to http://localhost:8080/login.html to give a 404 error (not generated by mormot) while visiting http://localhost:8080/root/files/login.html still works

Additional info: My model and server is created using   

aModel := TSQLModel.Create([],'root');
aHttpServer := TSQLHttpServer.Create(IntToStr(8080), [aRestServer],'+',useHttpApiRegisteringURI)

Last edited by squirrel (2016-01-28 10:32:43)

Offline

#13 2016-02-09 04:56:29

squirrel
Member
Registered: 2015-08-13
Posts: 155

Re: Serve files compiled into the exe

Am I doing something wrong?

Offline

#14 2016-02-10 14:51:20

mpv
Member
From: Ukraine
Registered: 2012-03-24
Posts: 1,571
Website

Re: Serve files compiled into the exe

On the HTTP API level your server is listening on `http://localhost:8080/root` (you pass a `root` during call to TSQLModel.Create), so URL http://localhost:8080/ do not handled by mORMot at all. Only requests to http://localhost:8080/root/* are handled by mORMot

Last edited by mpv (2016-02-10 14:51:40)

Offline

Board footer

Powered by FluxBB