Nita
Nita

Reputation: 561

htaccess - redirect to error pages issue (with slash or without slash)

There is an issue with redirection to error pages: example.com/test - will redirect to 404 error page

but example.com/test/ - will go to the white "File not found." page

to mention:

.htaccess file code

<Files .htaccess>
order allow,deny
deny from all
</Files>

RewriteEngine On
RewriteRule ^([^/]+)/$ $1.php
RewriteRule ^([^/]+)/([^/]+)/$ /$1/$2.php
RewriteRule sample/(.*)/(.*)/$ /sample.php?$1=$2

ErrorDocument 400 /400.php
ErrorDocument 401 /401.php
ErrorDocument 403 /403.php
ErrorDocument 404 /404.php
ErrorDocument 410 /410.php

Upvotes: 0

Views: 1022

Answers (2)

MrWhite
MrWhite

Reputation: 45829

The difference with your URLs that end in a trailing slash is that they are unconditionally rewritten to the corresponding .php file. The URLs that do not end in a trailing slash are not rewritten - nothing happens.

You are seeing the same basic "File not found" response when you directly request a non-existent .php file, regardless of whether the request is rewritten (by your rules) or not.

The "problem" might be due to the way PHP is implemented on your server. For instance, if all *.php requests are proxied to an alternative backend process then this is going to bypass your .htaccess file on the application server and the "basic" 404 response you are seeing is possibly coming from the proxy, not your application server.

You may be able to resolve this by first checking that the .php exists before rewriting to it (so it doesn't trigger a 404). And if none of your URLs contain a .php extension, you could also force any direct request for .php files to 404 (on your server, before the request is proxied - if that is what's happening).

RewriteEngine On
RewriteRule ^([^/]+)/$ $1.php
RewriteRule ^([^/]+)/([^/]+)/$ /$1/$2.php
RewriteRule sample/(.*)/(.*)/$ /sample.php?$1=$2

The first two rules can also be combined into one. You are missing L flags on all your rules. You need to ensure that MultiViews is disabled, otherwise the last rule will not work.

Also, the regex in the last rule needs to be anchored and made more specific since it is matching too much, eg. /sample/foo/bar/baz/qux will be rewritten to /sample.php?foo/bar/baz=qux, which I assume is not the intention.

Try the following instead:

Options -MultiViews

RewriteEngine On

# Force any direct request for ".php" files to 404
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule \.php$ - [R=404]

# Rewrite to ".php" file - 1 or 2 path segments
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^([^/]+(/[^/]+)?)/$ $1.php [L]

# Rewrite "/sample/one/two/"
RewriteRule ^sample/([^/]+)/([^/]+)/$ sample.php?$1=$2 [L]

Reference:

Another recent question that has a very similar issue and was resolved in the same way:
Custom 404 error handler in htaccess not working for non-existent ".php" files

Upvotes: 2

jacek_SQ6KBQ
jacek_SQ6KBQ

Reputation: 66

The problem is with ending slash of RewriteRule ^([^/]+)/$ $1.php

If you write RewriteRule ^([^/]+)/?$ $1.php the tailing slash would be optional.

edit

You should also add

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

before RewriteRule statements, because of server loop - when the file exists the statements will break loop by skipping rewriting.

Upvotes: 1

Related Questions