4

I'm trying to have dynamically determined Unix socket used for different separated PHP "apps" (different sockets lead to different PHP-FPM pools) on my Apache (2.4.18) server (using mod_proxy_fcgi):

<DirectoryMatch "/home/apps/app_(?<appname>[a-zA-Z]+)">

    <FilesMatch \.php$>
        SetHandler "proxy:unix://var/run/app_%{env:MATCH_APPNAME}.sock|fcgi://localhost:42001"
    </FilesMatch>

</DirectoryMatch>

Unfortunately Apache doesn't seem to recognize/evaluate the variable defined by the regular expression match in the <DirectoryMatch> directive when used with the SetHandler directive.

The error.log says this:

[proxy:error] (2)No such file or directory: AH02454: FCGI: attempt to connect to Unix domain socket /run/app_%{MATCH_APPNAME}e.sock (*) failed

How would one go about passing a variable to the SetHandler directive? My PHP-FPM is working correctly when I use a "rigid" path to the UDS (eg. "proxy:unix://var/run/app_someappname.sock|fcgi://localhost:42001", but there seems to be a problem when using a variable in it.


I also tried building the path using several variables joined together:

<FilesMatch \.php$>
    Define one "proxy:unix://var/run/app_"
    Define two ".sock|fcgi://localhost:42001"
    Define final ${one}%{MATCH_APPNAME}e${two}
    Header set HANDLER_PATH ${final}
</FilesMatch>

In this case the PHP source is not processed by PHP, but the HTTP response header for the URL http://127.0.0.1/apps/someappname/index.php (correctly) contains: HANDLER_PATH: proxy:unix://var/run/app_someappname.sock|fcgi://localhost:42001

But when I pass the ${final} variable to SetHandler, server returns 503 Service Unavailable and error.log says:

*: using default reverse proxy worker for unix://var/run/app_%{MATCH_APPNAME}e.sock|fcgi://localhost:42001/home/apps/app_someappname/www/index.php (no keepalive)
*: rewrite of url due to UDS(/run/app_%{MATCH_APPNAME}e.sock): fcgi://localhost:42001/home/apps/app_someappname/www/index.php (proxy:fcgi://localhost:42001/home/apps/app_someappname/www/index.php)
AH01143: Running scheme unix handler (attempt 0)
AH01076: url: fcgi://localhost:42001/home/apps/app_someappname/www/index.php proxyname: (null) proxyport: 0
AH01078: serving URL fcgi://localhost:42001/home/apps/app_someappname/www/index.php
AH00942: FCGI: has acquired connection for (*)
AH00944: connecting fcgi://localhost:42001/home/apps/app_someappname/www/index.php to localhost:42001
AH02545: fcgi: has determined UDS as /run/app_%{MATCH_APPNAME}e.sock
AH00947: connected /home/apps/app_someappname/www/index.php to httpd-UDS:0
(2)No such file or directory: AH02454: FCGI: attempt to connect to Unix domain socket /run/app_%{MATCH_APPNAME}e.sock (*) failed
AH01079: failed to make connection to backend: httpd-UDS
proxy_util.c(2175): AH00943: FCGI: has released connection for (*)

What strikes me is that when the sock's path is being put into HTTP header, it is correctly resolved as proxy:unix://var/run/app_someappname.sock, but when the variable is passed to SetHandler, it suddenly becomes unix://var/run/app_%{MATCH_APPNAME}e.sock with a literal %{MATCH_APPNAME}e, like if the variable was resolved by the SetHandler itself (and incorrectly) ...

How would one do this? Is this even possible? I think it must be.

Smuuf
  • 146
  • 7

1 Answers1

3

Have you tried RewriteRule with [H= instead of SetHandler?

RewriteRule would have the advantage of evaluating arguments when it's executed rather at startup (typical directives do not interpolate per-request variables when they actually execute)

covener
  • 1,665
  • 9
  • 15
  • 1
    Oh my, I tried it again and you're right. Thank you so much! For those than would need this: `Define handler proxy:unix://var/run/app_%{env:MATCH_APPNAME}.sock|fcgi://localhost` and then `RewriteRule ^ - [H=${handler}]` – Smuuf Jan 18 '16 at 13:57
  • 1
    This might work for misleading reasons. I think define is substituting the literal %{env...} string and startup and mod_rewrite is evaluating it. So it is a handy way to avoid a massive line for the RewriteRUle but it is not really helping with the evaluation (IIUC) – covener Jan 18 '16 at 14:04
  • 1
    Yes, it is true that `RewriteRule ^ - [H=proxy:unix://var/run/app_%{env:MATCH_APPNAME}.sock|fcgi://localhost]` works too. – Smuuf Jan 18 '16 at 14:07