Question

I've set up a server using PHP5-FPM (using PHP 5.3.27) and apache2.

There is an api.php file in the doc root, and using mod_rewrite i've got this rule in .htaccess:

RewriteEngine on
RewriteRule ^api/rest api.php?type=rest [QSA,L]
RewriteCond %{REQUEST_URI} !^/(media|skin|js)/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule .* index.php [L]

So what i want is for everything except exact file matches to be passed to index.php

What is happening, however, is when i go to /api/ the api.php is being loaded, instead of the request being forwarded to the index.php

I've gone through the documentation, googled thoroughly (unless i'm not using the right keywords), and checked out both the apache and php configuration. This doesn't happen on our live server or our development servers that use a conbination of nginx and php5-fpm or apache and mod_php5

My Apache config for the vhost is:

<VirtualHost *:80>

  DocumentRoot /var/www/html

  ServerName admin.localhost
  ServerAlias  *.localhost

  <Directory "/var/www/html">
    Options FollowSymLinks MultiViews ExecCGI
    AllowOverride All
    Order deny,allow
    Allow from all
  </Directory>

  # Wire up Apache to use Travis CI's php-fpm.
  <IfModule mod_fastcgi.c>
    AddHandler php5-fcgi .php
    Action php5-fcgi /php5-fcgi
    Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi
    FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -host 127.0.0.1:9000 -pass-header Authorization
  </IfModule>

</VirtualHost>

EDIT I've investigated further:

  • If i remove api.php - the rewrite works
  • If i remove the RewriteCond %{REQUEST_FILENAME} !-f - the rewrite works
  • Any .php file they get loaded without the extension - not non-php files only work with the extension.
Was it helpful?

Solution

Try replacing:

Options FollowSymLinks MultiViews ExecCGI

By:

Options FollowSymLinks -MultiViews ExecCGI

The MultiViews keyword comes from mod_negociation and can have a lot of side-effects. One of theses effect is that it can scan for known extensions, when you request 'api' it can scan for api.php' or 'api.html' files and redirect internally the requests on theses files.

From http://httpd.apache.org/docs/2.2/content-negotiation.html#multiviews :

The effect of MultiViews is as follows: if the server receives a request for /some/dir/foo, if /some/dir has MultiViews enabled, and /some/dir/foo does not exist, then the server reads the directory looking for files named foo.*, and effectively fakes up a type map which names all those files, assigning them the same media types and content-encodings it would have if the client had asked for one of them by name. It then chooses the best match to the client's requirements.

To me this seems like a big hole, some considers it a feature.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top