1

Due to different priorities of the parts of the PHP app, the goal here is to have one pool for general usage, and another for The /api/* URLs. To make things complicated, the app uses internal URL routing, so it's not possible to distinguish the two cases by only FilesMatch.

I've started with this:

<FilesMatch "\.php$"> SetHandler proxy:fcgi://127.0.0.1:9000 </FilesMatch> <LocationMatch "^/api/"> SetHandler proxy:fcgi://127.0.0.1:9001 </LocationMatch> 

This is in the global context, outside VirtualHost directives as there are multiple vhosts, all with the same requirement.

It doesn't work and all URLs are handled by the first pool (the one at :9000).

Any ideas how to create this configuration? This is for Apache 2.4.

3
  • 1
    Do any URLs under /api/ end with .php, cause if so, they're all getting matched by the first block. Try changing the order of the blocks to see if it helps. Commented Mar 9, 2016 at 15:30
  • The URL's don't end with .php's (AFAIK that's what Location matches), but the PHP files do. I.e. the URL's look like /api/whatever, and are mapped to /index.php/api/whatever by Rewrite. Commented Mar 9, 2016 at 16:42
  • That still means that all your .php files are going to be matched by the first block. Try changing their order. Commented Mar 9, 2016 at 16:43

2 Answers 2

3

Ok, solved it with an If. Apparently something funny is going on with the translation of REQUEST_URI: at the time the If gets evaluated, it doesn't contain what I required, so I matched THE_REQUEST which contains the verbatim HTTP request. Here's how my solution looks like:

<FilesMatch "\.php$"> # First pool, catches everything SetHandler proxy:fcgi://127.0.0.1:9000 SetEnv PHP_POOL_ID "1" </FilesMatch> <If "%{THE_REQUEST} =~ m#/api/#"> # Second pool, only for certain URLs SetHandler proxy:fcgi://127.0.0.1:9001 SetEnv PHP_POOL_ID "2" </If> 

The SetEnv statements are for debugging only, they can be used in logs to track which pool has served the request, e.g. with:

CustomLog "/var/log/httpd/php_pool.log" "%h %l %u %t \"%r\" %>s %b php:%{PHP_POOL_ID}e" env=PHP_POOL_ID 
0

The URL's don't end with .php's (AFAIK that's what Location matches), but the PHP files do. I.e. the URL's look like /api/whatever, and are mapped to /index.php/api/whatever by Rewrite.

I think with such rewrites it wouldn't be possible to get what you want.

<VirtualHost *:80> ServerAdmin webmaster@localhost ServerName www.example.net DocumentRoot /vhosts/default/public_html <Directory /vhosts/default/public_html> DirectoryIndex index.html index.php Options -Indexes AllowOverride all Order allow,deny allow from all </Directory> SetEnv FCGI-PORT 9000 <LocationMatch \.php$> SetEnv FCGI-PORT 9001 </LocationMatch> <LocationMatch ^/api/> SetEnv FCGI-PORT 9002 RewriteEngine On RewriteRule (.*) /index.php?route=%{REQUEST_URI} [R=301,L] </LocationMatch> </VirtualHost> 

Some basic tests

# curl http://www.example.net/ 9000 # curl http://www.example.net/index.php 9001 # curl -I http://www.example.net/api/whatever HTTP/1.1 301 Moved Permanently Date: Wed, 09 Mar 2016 17:03:56 GMT Server: Apache/2.2.15 (CentOS) Location: http://www.example.net/index.php?route=/api/whatever Connection: close Content-Type: text/html; charset=iso-8859-1 # curl http://www.example.net/index.php?route=/api/whatever 9001 

But if we comment rewrite rules - all works as expected

# curl http://www.example.net/ 9000 # curl http://www.example.net/index.php 9001 # curl http://www.example.net/api/ 9002 # curl http://www.example.net/api/test.php 9002 

Try changing their order.

in this particular case (with rewrites) the order doesn't matter

P.S. index.php/test.php it's just a simple php script

<?php echo $_SERVER['FCGI-PORT']; 

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.