htaccess URL redirect excluding a couple of urls

Viewed 20

So from our old server we want almost all URLs to be redirected to new server except a few.

So I tried the following .htaccess rule:

RewriteEngine on

RewriteCond %{REQUEST_FILENAME} !\.(css|js|Js|png|jpg|gif)$ [NC]
RewriteCond %{REQUEST_URI} !^/admin/
RewriteCond %{REQUEST_URI} !^/albums/
RewriteCond %{REQUEST_URI} !^/songs/
RewriteCond %{REQUEST_URI} !^/update_list.php
RewriteRule (.*) http://www.newserver.com/$1 [R=301,L]

The idea is that other than the admin, albums, songs URLs and update_list php file and the asset files (css, js, images) everything else should redirect to new server.

This works "almost" fine - admin URL correctly stays in old server, as does update_list. All other legacy urls redirect to the new server.

However my problem is that albums and songs URLs also keep redirecting to new server.

I am not sure why. Just so you are aware the songs url is of the structure

oldserver.com/songs/album-id/song-name

And the albums URL has session values set based on query params when loading.

Can anyone help me? I have been sitting with this for over 4 hours now :( And I have tried almost all kinds of rule syntaxes I read online. Any advice/pointers is greatly appreciated.

1 Answers

It looks like your albums and songs URLs would need to be internally rewritten to a "front-controller" (eg. index.php or something) in order to be successfully routed through your application.

If that's the case then these URLs are likely being redirected after the request has been rewritten to the front-controller, effectively bypassing the conditions in your current rule. (Although you should also be seeing a "malformed" redirect to the "front-controller", the original URL will be lost. Is that the case?)

You can ensure you only redirect direct requests from the client (and not "rewritten" requests) by checking against the REDIRECT_STATUS environment variable, which is empty on the initial request and set to "200" (as in 200 OK HTTP status) after the first successful rewrite.

For example:

RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_URI} !\.(css|js|png|jpg|gif)$ [NC]
RewriteCond %{REQUEST_URI} !^/admin/
RewriteCond %{REQUEST_URI} !^/albums/
RewriteCond %{REQUEST_URI} !^/songs/
RewriteCond %{REQUEST_URI} !^/update_list\.php
RewriteRule (.*) http://www.newserver.com/$1 [R=301,L]

You can use REQUEST_URI, rather than REQUEST_FILENAME to check for the file extension. And there's no need to check for js and Js, since the comparison is not case-sensitive (ie. NC - nocase)

You will need to clear your browser cache before testing, since the erroneous 301 (permanent) redirect will have been cached by the browser.

Always test first with 302 (temporary) redirects to avoid potential caching issues.

Related