danieleteti / delphimvcframework

DMVCFramework (for short) is a popular and powerful framework for WEB API in Delphi. Supports RESTful and JSON-RPC WEB APIs development.
Apache License 2.0
1.21k stars 346 forks source link

Apache routing broken #723

Closed fastbike closed 2 weeks ago

fastbike commented 6 months ago

The Apache framework used by the underlying web broker has a "feature" where it takes the first segment of the request path and strips this off into the Request.ScriptName property. The remainder of the path is then available via the Request.PathInfo property.

This means if you set up a virtualhost and serve pages directly out of the root then things start to break. In particular the static files routing and the MVCPath attribute based routing are broken.

I have tested this on Apache 2.4 running under Windows - I do not have a Linux machine set up but assume it will be the same. The root of the problem is in file Web.HTTPD24Impl.pas (part of the Delphi RTL)

function THTTPMethods24.get_path_info(const ARequestRec: PHTTPDRequest): UTF8String;
var
  LSPlit:  TStrings;
  I, IStart: Integer;
begin
/// snip
    if LSplit.DelimitedText.StartsWith('/') then
      IStart := 2
    else
      IStart := 1;

// NB- it discards the first part of the request path
    for I := IStart to LSplit.Count-1 do
      Result := Result + '/' + UTF8String(LSplit[I]);
  finally
    LSplit.Free;
  end;
end;

The Static files and MVC Routing take the path which in this case will be missing the first segment. I'll need to think what a possible work around could be.

fastbike commented 6 months ago

Some more information. Given a Delphi MVC Framework app that outputs a DLL file "mod_FHIRBirdServer.dll" with the these symbols

// Declare exported variable so that Apache can access this module.
var
  GModuleData: TApacheModuleData;
exports
  GModuleData name 'FHIRBirdServer_module';

We have the following entries in the Apache httpd.conf file

# register the module that exports "FHIRBirdServer_module"
LoadModule FHIRBirdServer_module modules/mod_FHIRBirdServer.dll

# set the handler for the base path, this will not work
<Location />
    SetHandler mod_FHIRBirdServer-handler
</Location>

# set the location for a path that will be discarded
<Location /abc/>
    SetHandler mod_FHIRBirdServer-handler
</Location>

Navigating to http://localhost/ does not work, log files show

2023-12-20 07:25:31:108  [TID 1064    ][INFO      ] pathinfo ""
2023-12-20 07:25:31:108  [TID 1064    ][INFO      ] scriptinfo "/" 

Navigating to http://localhost/abc/ does work, log files show

2023-12-20 09:43:08:889  [TID 15224   ][INFO      ] pathinfo ""
2023-12-20 09:43:08:889  [TID 15224   ][INFO      ] scriptname "/abc"

The original page had a link to a css file <link rel="stylesheet" href="/dist/app.css" /> This shows a 404 not found in the browser dev tools However the browser can fetch http://localhost/abc/dist/app.css (which is processed via the StaticFiles middleware mapped for a URL path of "/dist"

danieleteti commented 2 months ago

If you serve static files would be better to use the webserver facilities to do that and not the dmvcframework static files middleware. Just becouse web servers do a very good job doing... well, their job :-) In such kind of project leave the static file for the web server and the API for dmvcframework. This is a best practice.

danieleteti commented 2 weeks ago

Any news David?

fastbike commented 2 weeks ago

@danieleteti We're going to be porting one of our apps to run as an Apache so under Linux later this year, so if I come up with a solution I'll post it back here.