Home > front end >  Apache mod_rewrite sets request method to "GET" if directory exists
Apache mod_rewrite sets request method to "GET" if directory exists

Time:09-17

I'm currently developing an API using a self-written router. It uses an .htaccess file to redirect all incoming requests to the index.php file.

I have found the following problem: If there is an incoming request e.g.: OPTIONS https://<domain>/auth and the directory auth/ exists on the root-level, the request method is switched to GET.

.htaccess file:

RewriteEngine On

RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]

RewriteCond %{REQUEST_FILENAME}  -f [OR]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [L,QSA]

How can I fix this? Thanks.

CodePudding user response:

This is because mod_dir issues a 301 redirect to append the trailing slash to directories (in order to "fix" the URL). A consequence of the 301 redirect is that the user-agent (browser) changes the subsequent request method to GET.

If you specifically want to allow these types of requests then you'll need to prevent mod_dir from appending the slash with DirectorySlash Off. However, you will also need to ensure that mod_autoindex (auto generated directory listings) are disabled (to prevent accidental disclosure of information) and you could potentially encounter issues if you need to access directories directly elsewhere.

For example, at the top of your .htaccess file:

# Disable directory listings (mod_autoindex)
Options -Indexes

# Prevent mod_dir from appending the slash to directories
DirectorySlash Off

Reference:


Aside:

RewriteCond %{REQUEST_FILENAME}  -f [OR]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [L,QSA]

These RewriteCond directives are superfluous. You are rewriting literally everything to index.php. It would be more efficient to write this as:

RewriteRule !^index\.php$ index.php [L]
  • Related