Dancer icon indicating copy to clipboard operation
Dancer copied to clipboard

request->uri_base contains dispatch.(f)cgi when Dancer is executed via DirectoryIndex (Apache 2.4)

Open isync opened this issue 6 years ago • 2 comments

Dancer version 1.3202 Dunno if this is a bug or wanted behaviour:

On one Dancer site I recently had an issue where dispatch.fcgi ended up in request->uri_base, for example request->uri_base = "http://www.example.com/dispatch.fcgi"

By accident I found that this only happened at the root "/" path of the site... Which led me to why it happened: I had a new (over-optimisation!?) Directive in the site's Apache .conf file. Illustrated with the example from Dancer::Deployment, I had this:

<VirtualHost *:80>
    ServerName localhost
    DocumentRoot "/path/to/rootdir"

    <Directory "/path/to/rootdir">
        AllowOverride None
        Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
        Order allow,deny
        Allow from all
        AddHandler fastcgi-script .fcgi
    </Directory>

    DirectoryIndex    /dispatch.fcgi      # <<-- this here

    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f

    RewriteRule /(.*)$     /dispatch.fcgi$1 [QSA,L]
</VirtualHost>

As suggested in the Dancer::Deployment docs, my .conf ended with every path going through the rewrite engine, with "RewriteRule ^(.*)$ /dispatch.fcgi$1 [QSA,L]". However, I decided to be extra smart, and that the root "/" doesn't need to be elaborately parsed, thus I set a DirectoryIndex directive at the beginning of the config file, to break out of testing the URL early.

That didn't work as expected! As it seems, when dispatch.fcgi is called via DirectoryIndex, ".../dispatch.fcgi" ends up in request->uri_base. Obviously Apache calls the script different via DirectoryIndex (without appending the path, right?). And when no URI path is appended, Dancer's uri_base() algorithm decides that the script name is part of the uri_base...

If that's the feature/problem, then why is my current over-optimisation working?

    ...
    RewriteRule ^/$         /dispatch.fcgi         [QSA,L]
    RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
    RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
    RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-
    RewriteRule ^(.*)$      /dispatch.fcgi        [QSA,L]

The above "/"-edge-case-rewrite-rule is also passing nothing to dispatch.fcgi... Clearly, Apache handles scripts different via DirectoryIndex, and Dancer's uri_base() returns a different value.

isync avatar Oct 16 '17 21:10 isync

Yes, that's how DirectoryIndex works, and why I said you needed to use mod_rewrite. This was the very first diagnosis and solution I suggested before you spent an hour plus on other configs :P

By the time the request gets to Dancer we've no way of telling that you use DirectoryIndex that I can think of so unless you can see something in the PSGI environment that we could test, I don't think it's possible to change this behaviour, and the only assistance I can give you is "if at first you don't succeed, maybe try doing what mst suggested in the first place".

I'm not closing this immediately because I'd like to give others a chance to explain why I'm completely wrong, since I'd be happy to trade any dignity I have on this ticket for the pleasant surprise that this is fixable after all ;)

shadowcat-mst avatar Oct 17 '17 15:10 shadowcat-mst

Actually, took me more time to discuss the issue..., as once I stumbled over the behaviour again, I quickly discovered it to be related with DirectoryIndex. Anyway. As a final remark, let me emphasize that my intention wasn't to annoy you or anyone! So, really, thank you for looking into this again.

isync avatar Oct 17 '17 18:10 isync