Stefan P
Stefan P

Reputation: 1043

Redirect loop with simple htaccess rule

I have been pulling my air out over this. It worked before the server migration!

Ok so basically it's as simple as this:

I have a .php file that I want to view the content of using a SEO friendly URL via a ReWrite rule.

Also to canonicalise and to prevent duplicate content I want to 301 the .php version to the SEO friendly version.

This is what I used and has always worked till now on the new server:

RewriteRule ^friendly-url/$ friendly-url.php [L,NC]
RewriteRule ^friendly-url.php$ /friendly-url/$1 [R=301,L]

However disaster has struck and now it causes a redirect loop.

Logically I can only assume that in this version of Apache it is tripping up as it's seeing that the script being run is the .php version and so it tries the redirect again.

How can I re-work this to make it work? Or is there a config I need to switch in WHM?

Thanks!!

Upvotes: 1

Views: 6994

Answers (2)

Chuck Kollars
Chuck Kollars

Reputation: 2175

The exact same .htaccess file will work differently depending on where it's placed because the [L]ast flag means something different depending on location. In ...conf, [L]ast means all finished processing so get out, but in .htaccess the exact same [L]ast flag means start all over at the top of this file.

To work as expected when moving a block of code from ...conf to .htaccess, most .htaccess files will need one or the other of these tweaks:

  • Change the [L]ast flags to [END]. (Problem is, the [END] flag is only available in newer [version 2.3.9 and later] Apaches, and won't even "fall back" in earlier versions.)

  • Add boilerplate code like this at the top of each of your .htaccess files:

*

RewriteCond %{ENV:REDIRECT_STATUS} !^[\s/]*$
RewriteRule ^ - [L]

Upvotes: 2

Prix
Prix

Reputation: 19528

This is how your .htaccess should look like:

Options +FollowSymLinks -MultiViews 

RewriteEngine On
RewriteBase /

# To externally redirect /friendly-url.php to /friendly-url/
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+(friendly-url)\.php [NC]
RewriteRule ^ /%1/? [R=302,L]

## To internally redirect /anything/ to /anything.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1\.php -f
RewriteRule ^(.+?)/$ $1.php [L]

Note how I am using R=302, because I don't want the rule to cache on my browser until I confirm its working as expected, then, once I can confirm its working as expected I switch from R=302 to R=301.

Keep in mind you may have also been cached from previous attempts since you're using R=301, so you better of trying to access it from a different browser you have used just to make sure its working.

However disaster has struck and now it causes a redirect loop.

It causes a redirect loop because your redirecting it to itself, the different on my code is that I capture the request, and redirect the php files from there to make it friendly and then use the internal redirect.

Upvotes: 3

Related Questions