Home > database >  .htaccess adds /var/www/html
.htaccess adds /var/www/html

Time:11-22

We have had our Website running on an older Apache2 instance with a large .htaccess file for redirects of old URLs to new ones. Since we have a lot of equal sub-URLs the redirect looks like this:

RewriteRule ^(.*)old/url(.*)$ new/url [L,R=301]

This worked like a charm.

For example www.example.com/a/old/url got redirected to www.example.com/a/new/url and also worked for /b/ or /c/.

With the new Apache (2.4.54) the redirect doesn't work as expected since it redirects as follows:

www.example.com/var/www/html/new/url

What am I doing wrong? Why does it place the base path of the website in front?

I've tried to google as good as possible but couldn't find anything. I would expect any weird path that I don't know of is set in the wrong way.

I'm not very deep into .htaccess which makes it hard to troubleshoot.

CodePudding user response:

RewriteRule ^(.*)old/url(.*)$ new/url [L,R=301]

This worked like a charm.

For example www.example.com/a/old/url got redirected to www.example.com/a/new/url and also worked for /b/ or /c/.

It would only do that if you also had a RewriteBase /a directive defined elsewhere in the config file. (Although it's not clear how it would work the same for /b/ or /c/, unless you have other directives that are helping. Unless you mean that it redirects from /b/ or /c/ to /a/? In which case, the RewriteBase directive alone is what is enabling this to work.)

With the new Apache (2.4.54) the redirect doesn't work as expected since it redirects as follows: www.example.com/var/www/html/new/url

That will happen if RewriteBase is not defined as mentioned above.

This applies to both Apache 2.2 and 2.4.

However, it's also possible that RewriteBase is/was defined in a parent config and RewriteOptions MergeBase was set (which propagates the setting to child configs). A further complication is that in later versions of Apache 2.2 (specifically 2.2.23 and later) and early versions of Apache 2.4 (specifically 2.4.0 to 2.4.3) this was actually the default (arguably buggy) behavior. So, if you are upgrading from one of these "buggy" versions of Apache, it's possible this was "just working".

The RewriteBase directive defines the URL-path that is prefixed to relative substitution strings (new/url is a relative substitution string). If no RewriteBase is defined then the directory-prefix (ie. the absolute file-path of where the .htaccess file is located) is added back - which is resulting in your malformed redirect.

For external "redirects" it is often preferable to use a root-relative (starting with a slash) or absolute (scheme hostname) substitution string. For example:

 RewriteRule ^(.*)old/url(.*)$ /a/new/url [L,R=301]

The above is no longer dependent on the RewriteBase directive, since the substitution string (ie. /a/new/url) is no longer relative.

However, ^(.*)old/url(.*)$ is the same as simply old/url, which is rather too general. Perhaps something like the following would be preferable:

 RewriteRule ^(a|b|c)/old/url /a/new/url [L,R=301]

The above redirects /a/old/url or /b/old/url or /c/old/url<anything> to /a/new/url.

OR, redirect to the same URL-path (ie. a, b or c) using a backreference:

 RewriteRule ^(a|b|c)/old/url /$1/new/url [L,R=301]

You will need to clear your browser cache before testing, since the erroneous 301 (permanent) redirect will have been cached by the browser (and possibly any intermediary caches). Test first with 302 (temporary) redirects to avoid potential caching issues.

Reference:

  • Related