#1 2014-12-11 11:36:22

Geziel
Member
Registered: 2014-12-11
Posts: 7

Multiple domain names - Same Server

It is possible with mormot to host multiple websites with different domain names but in the same port at the same server?

For instance:

    website 1:  project1.com
    website 2:  project2.com
    website 3:  blog.project2.com


What is the best approach for this kind of situation?

Offline

#2 2014-12-11 14:18:12

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

Re: Multiple domain names - Same Server

There was yet no direct handling of host name supplied by the HTTP clients.
Workaround may be:
1. Either use a redirection proxy in front of the mORMot server (redirecting domains/sub-domains to proper URI as expected by TSQLHttpServer
2. Or interpret the HOST value in incoming HTTP headers

So I've just added TSQLHttpServer.DomainHostRedirect() method for virtual-host redirection of Internet domains or sub-domains.
See http://synopse.info/fossil/info/2dc9a48b61

Following our "30 MVC BLOG" sample, you may define sub-domain hosting, to make a difference between the REST methods and the MVC web site. For instance, you may define some per domain / per sub-domain hosting redirection:

aHttpServer.DomainHostRedirect('rest.project.com','root');      // 'root' is current Model.Root
aHttpServer.DomainHostRedirect('project.com','root/html');      // call the Html() method
aHttpServer.DomainHostRedirect('www.project.com','root/html');  // call the Html() method
aHttpServer.DomainHostRedirect('blog.project.com','root/blog'); // MVC application

All ORM/SOA activity should be accessed remotely via rest.project.com, then would be handled as expected by the ORM/SOA methods of the TSQLRestServer instance.
For proper AJAX / JavaScript process, you may have to write:

aHttpServer.AccessControlAllowOrigin := '*'; // allow cross-site AJAX queries

Any attempt to access to the project.com or www.project.com URI would be redirected to the following method-based service:

procedure TMyServer.Html(Ctxt: TSQLRestServerURIContext);
begin 
  if fMyFileCache='' then
    fMyFileCache := StringFromFile(ChangeFileExt(paramstr(0),'.html'));
  Ctxt.Returns(fMyFileCache,HTML_SUCCESS,HTML_CONTENT_TYPE_HEADER,true);
end;

This method would serve some static HTML content as the main front end page of this server connected to the Internet. For best performance, this UTF-8 content is cached in memory, and the HTTP 304 command would be handled, if the browser supports it. Of course, your application may return some more complex content, even serving a set of files hosted in a local folder, e.g. by calling Ctxt.ReturnFile() method in this Html() service.

In addition, you may have specified an expected sub-URI when initializing your TMVCApplication:

constructor TBlogApplication.Create(aServer: TSQLRestServer);
begin
...
fMainRunner := TMVCRunOnRestServer.Create(self,nil,'blog').
...

Here, any request to blog.project.com will be redirected to the TBlogApplication URIs.

Feedback is welcome!

Offline

#3 2014-12-11 19:43:44

Geziel
Member
Registered: 2014-12-11
Posts: 7

Re: Multiple domain names - Same Server

Thank you.

Offline

#4 2014-12-11 20:17:50

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

Re: Multiple domain names - Same Server

You are welcome.

Note that I've also added the new TSQLRestServerURIContext.ReturnFileFromFolder() method, for direct fast transmission to a HTTP client, handling "304 Not Modified" and proper mime type recognition.
See http://synopse.info/fossil/info/4c6d4bb4a34a0

procedure TMyServer.Html(Ctxt: TSQLRestServerURIContext);
begin
  Ctxt.ReturnFileFromFolder('c:\www');
end;

This single method will search for any matching file in the local c:\www folder and its sub-directories, returning the default index.html content if no file is specified at URI level. See the optional parameters to the Ctxt.ReturnFileFromFolder() method for proper tuning, e.g. to change the default file name or disable the HTTP 304 answers. In all cases, the file content will be served by the High-performance http.sys server directly from the kernel mode, so would be very fast.
It may help you serving static content from one domain, with ease and performance.
Not need to deploy IIS, Apache nor NGinx: a simple mORMot executable is able to do your work.

Feedback is welcome!

Offline

#5 2014-12-13 09:31:30

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

Re: Multiple domain names - Same Server

AB, in our implementation of static file transferring we use this function to prevent retrieve files outside of wwwRoot:

function RelToAbs(const ABaseDir, AFileName: string; ACheckResultInsideBase: boolean = false): string;
begin
  if PathIsRelative(PChar(AFileName)) then begin
    SetLength(Result, MAX_PATH);
    if PathCombine(@Result[1], PChar(ABaseDir), PChar(AFileName)) = nil then
      Result := ''
    else
      SetLength(Result, StrLenW(@Result[1]));
  end else
    Result := AFileName;
  if ACheckResultInsideBase and
     ((length(Result) < length(ABaseDir)) or (length(ABaseDir)=0) or
      (StrLIComp(PWideChar(@Result[1]), @ABaseDir[1], length(ABaseDir)) <> 0)) then
    Result := ''
end;

This allow us to safely use relative path (your current implementation not allow relative path). May be someone find it useful.

Offline

#6 2014-12-13 09:45:54

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

Re: Multiple domain names - Same Server

Geziel wrote:

It is possible with mormot to host multiple websites with different domain names but in the same port at the same server?

For instance:

    website 1:  project1.com
    website 2:  project2.com
    website 3:  blog.project2.com


What is the best approach for this kind of situation?

On the low level we do it for THttpApiServer in this way:

We run 2 instance of our server, first register listener to:
THttpApiServer.AddUrl('', '80', false, 'project1.com')
while second
THttpApiServer.AddUrl('', '80', false, 'project2.com')

And HTTP.sys do all work for us.

Offline

Board footer

Powered by FluxBB