.htaccess adds /var/www/html - .htaccess

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.

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:
https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewritebase
https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewriteoptions
https://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewriteoptions

Related

Htaccess replace one image with another one

So Ive been making a code which replaces one image with another without changing the link.
So heres the code that I found on one of the forums.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^.*/fredShip1.png$ /fredShip2.png [L]
</IfModule>
So this code not only redirects user to another page but also to a random link.
So original link is http://toss.rf.gd/storage/fredShip1.png though it should have replaced the image with http://toss.rf.gd/storage/fredShip2.png(Just an example) but it sends the user here toss.rf.gd/home/vol8_1/[Account info]/htdocs/storage/FredShip2.png
I added the image too ->
The image
I am really bad at htaccess so make sure correct me if Im wrong. Also english is not my first language so expect some minor mistakes.
EDIT : So i solved the problem with redirection to a random link. But Im still wondering is it possible to just change the image without changing the link?
RewriteRule ^.*/fredShip1.png$ /fredShip2.png [L]
The code you've posted already does essentially what you require, except that you need to adjust the paths to match your example. The "problem" with the above rule is that it rewrites the request to /fredShip2.png (in the document root), not /storage/fredShip2.png as in your example.
Assuming the .htaccess file is in the document root of the site and you wish to internally rewrite the request from /storage/fredShip1.png to /storage/fredShip2.png then you would do it like this:
RewriteRule ^storage/fredShip1.png$ storage/fredShip2.png [L]
There should be no slash prefix on the URL-path in either argument.
If you have other directives in your .htaccess file then the order of these directives can be important.
Make sure you've cleared your browser cache before testing.
but it sends the user here example.com/home/vol8_1/[Account info]/htdocs/storage/FredShip2.png
That's not possible with the directive you've posted. This is most likely a cached redirect due to an earlier (erroneous) experiment with 301 (permanent) redirects. For example, something like the following would produce the above "erroneous" output:
RewriteRule fredShip1\.png$ storage/FredShip2.png [R=302,L]
Note the use of the R (redirect) flag and the lack of a slash prefix on the RewriteRule substitution string (2nd argument). Since the substitution string is "relative", the directory-prefix (ie. /home/vol8_1/[Account info]/htdocs/ in your example) is prepended to substitution and since this is an external redirect (as denoted by the R flag) this then exposes the absolute filesystem path to the user.
NB: The above is a 302 (temporary) redirect - so should not be cached by the browser (at least not by default).

HTACCESS 301 redirect keep sending to the wrong page

I am trying to redirect an old page from a website I have redesigned, to the new one, but it's not working.
Here's my 2 lines of code in the .htaccess file regarding that domain:
Redirect 301 /deaneco http://solutionsgtr.ca/fr/deaneco/accueil.html
RewriteRule ^/deaneco/contact http://solutionsgtr.ca/fr/deaneco/contact.html [R=301,L,QSA]
If go on the solutionsgtr.ca/deaneco/contact URL, it gives me the following page:
http://solutionsgtr.ca/fr/deaneco/accueil.html/contact
The first rule works though (deaneco/ to solutionsgtr.ca/fr/deaneco/accueil.html).
I feel like both lines are being mixed together and are giving me the wrong page, that doesn't exist so I get a 404 error.
There are a couple of issues here:
The Redirect directive (part of mod_alias) is prefix-matching and everything after the match is appended on the end of the target URL. This explains the redirect you are seeing.
The RewriteRule (mod_rewrite) pattern ^/deaneco/contact will never match in a .htaccess context since the URL-path that is matched does not start with a slash. So, this rule is not doing anything currently.
You should avoid mixing redirects from both modules since they execute independently and at different times during the request (mod_rewrite executes first, despite the apparent order of the directives).
Either use mod_alias, ordering the directives most specific first:
Redirect 301 /deaneco/contact http://solutionsgtr.ca/fr/deaneco/contact.html
Redirect 301 /deaneco http://solutionsgtr.ca/fr/deaneco/accueil.html
NB: You will need to clear your browser cache, since the erroneous 301 (permanent) redirect will have been cached by the browser. Test with 302 (temporary) redirects to avoid potential caching issues.
OR, if you are already using mod_rewrite for other redirects/rewrites then consider using mod_rewrite instead (to avoid potential conflicts as mentioned above):
RewriteEngine On
RewriteRule ^deaneco/contact$ http://solutionsgtr.ca/fr/deaneco/contact.html [R=301,L]
RewriteRule ^deaneco$ http://solutionsgtr.ca/fr/deaneco/accueil.html [R=301,L]
The QSA flag is not required, since the query string is passed through to the substitution by default.
The order of the RewriteRule directives are not important in this instance, since they match just that specific URL.
If go on the solutionsgtr.ca/deaneco/contact URL
If you are redirecting to the same host then you don't need to explicitly include the scheme + hostname in the target URL, since this will default.

htaccess for local testing and live server

I'm close, to my final solution I think.
The .htaccess looks like this:
Options +FollowSymLinks
RewriteEngine On
RewriteBase /myproject/development/
RewriteRule ^((?!index\.php)[^/]+)/?$ index.php?page=$1 [L]
RewriteRule ^((?!index\.php)[^/]+)/([A-Za-z0-9]+)/([0-9]+)/([0-9]+)/?$ index.php?page=$1&keyword=$2&zip=$3&range=$4 [L,R]
I don't need the RewriteBase for the 1st rule(was a little surprised about that) but I need it if I add the 2nd rule and open this URL:
//localhost/myproject/development/somepage/test/13245/50
Otherwise the page will be opened but of course without the stylesheets and javaScripts can be found then.
1.) Target: I want to use the 2nd rewriteRule without changing or adding a rewriteBase. What do I need to change in the .htaccess so I can keep testing my project without a rewriteBase.
Why: As I asked before I want to test my project locally and on the live-server without changing too much on the project configuration.
2.) The [R] Flag If I request
//localhost/myproject/development/somepage/test/53229/2000
Of course in the adressline then we have this URL
//localhost/myproject/development/index.php?page=somepage&keyword=test&zip=12345&range=2000
To avoid this behaviour I simply should remove the R-Flag. But then the CSS and JS can't be found anymore. Also Here I'm looking for a solution without rewritebase, basepath, virtual host, etc. if possible.
Here is where I started:
Rewrite rules for localhost AND live envoirement
By the looks, you don't want the R flag on the 2nd RewriteRule. That defeats the object of your "pretty" URLs.
But then the CSS and JS can't be found anymore.
Because you are using relative paths to your CSS and JS files. Either change your paths to root-relative (starting with a slash), or use the base element in the head section of your pages, to indicate the URL that all relative URLs are relative to:
<base href="http://www.example.com/page.html">
More Information:
https://developer.mozilla.org/en/docs/Web/HTML/Element/base
I don't need the RewriteBase for the 1st rule(was a little surprised about that)
You don't need the RewriteBase for the 1st rule (an internal rewrite) because the directory-prefix (the filesystem path that lead to this .htaccess file) is automatically added back on relative path substitutions.
However, for external redirects (ie. R flag), the directory-prefix does not make sense, so you either need to specify a root-relative (starting with a slash) or absolute URL. Or specify the appropriate RewriteBase directive, which overrides what URL-path will be added for relative substitutions (that's all it does).

Stop mod_rewrite returning REQUEST_URI when (.*) is empty

Options +FollowSymLinks
RewriteEngine On
RewriteRule ^mocks/site/(.*)$ http://thelivewebsite.com/$1 [R=301,L]
That is my htaccess file's contents.
The htaccess file is in the root directory of the hosting account and I just want to redirect the directory mocks/site/ to the new domain (with or without any extra directories).
eg: if someone goes to http://mywebsite.com/mocks/site then it needs to redirect to http://thelivewebsite.com. If they go to http://mywebsite.com/mocks/site/another/directory then it needs to redirect to http://thelivewebsite.com/another/directory. I hope that makes sense.
So the problem I have is that the htaccess code above seems to work pretty well when there is something after mocks/site/ however when there isn't something after that then the $1 in the redirect seems to reference the whole REQUEST_URI (eg: mocks/site/ rather than nothing - as there is nothing after it).
I don't know how to stop this. I thought about using a RewriteCond, but I'm not sure what to use there. I can't find anything that helps me to determine if there is anything after mocks/site/ or not.
Any help will be much appreciated.
Thank you.
That's very strange behaviour -- never seen anything like that. Therefore I think it could be something else (another rule somewhere -- on old or even new site). I recommend enabling rewrite debugging (RewriteLogLevel 9) and check the rewrite log (that's if you can edit Apache's config file / virtual host definition).
In any case, try this combination:
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^mocks/site/$ http://thelivewebsite.com/ [R=301,L]
RewriteRule ^mocks/site/(.+)$ http://thelivewebsite.com/$1 [R=301,L]
It will do matching/redirecting in 2 steps: first rule is for exact directory match (so no $1 involved at all) and 2nd will work if there is at least 1 character after the /mocks/site/.
Alternatively (Apache docs even recommending this one) use Redirect directive (no need for mod_rewrite at all for such simple redirects):
Redirect 301 /mocks/site/ http://thelivewebsite.com/

How do I use .htaccess to redirect to a URL containing HTTP_HOST?

Problem
I need to redirect some short convenience URLs to longer actual URLs. The site in question uses a set of subdomains to identify a set of development or live versions.
I would like the URL to which certain requests are redirected to include the HTTP_HOST such that I don't have to create a custom .htaccess file for each host.
Host-specific Example (snipped from .htaccess file)
Redirect /terms http://support.dev01.example.com/articles/terms/
This example works fine for the development version running at dev01.example.com. If I use the same line in the main .htaccess file for the development version running under dev02.example.com I'd end up being redirected to the wrong place.
Ideal rule (not sure of the correct syntax)
Redirect /terms http://support.{HTTP_HOST}/articles/terms/
This rule does not work and merely serves as an example of what I'd like to achieve. I could then use the exact same rule under many different hosts and get the correct result.
Answers?
Can this be done with mod_alias or does it require the more complex mod_rewrite?
How can this be achieved using mod_alias or mod_rewrite? I'd prefer a mod_alias solution if possible.
Clarifications
I'm not staying on the same server. I'd like:
http://example.com/terms/ -> http://support.example.com/articles/terms/
https://secure.example.com/terms/ -> http://support.example.com/articles/terms/
http://dev.example.com/terms/ -> http://support.dev.example.com/articles/terms/
https://secure.dev.example.com/terms/ -> http://support.dev.example.com/articles/terms/
I'd like to be able to use the same rule in the .htaccess file on both example.com and dev.example.com. In this situation I'd need to be able to refer to the HTTP_HOST as a variable rather than specifying it literally in the URL to which requests are redirected.
I'll investigate the HTTP_HOST parameter as suggested but was hoping for a working example.
It's strange that nobody has done the actual working answer (lol):
RewriteCond %{HTTP_HOST} support\.(([^\.]+))\.example\.com
RewriteRule ^/terms http://support.%1/article/terms [NC,QSA,R]
To help you doing the job faster, my favorite tool to check for regexp:
http://www.quanetic.com/Regex (don't forget to choose ereg(POSIX) instead of preg(PCRE)!)
You use this tool when you want to check the URL and see if they're valid or not.
I think you'll want to capture the HTTP_HOST value and then use that in the rewrite rule:
RewriteCond %{HTTP_HOST} (.*)
RewriteRule ^/terms http://support.%1/article/terms [NC,R=302]
If I understand your question right, you want a 301 redirect (tell browser to go to other URL).
If my solution is not the correct one for you, try this tool: http://www.htaccessredirect.net/index.php and figure out what works for you.
//301 Redirect Entire Directory
RedirectMatch 301 /terms(.*) /articles/terms/$1
//Change default directory page
DirectoryIndex
According to this cheatsheet ( http://www.addedbytes.com/download/mod_rewrite-cheat-sheet-v2/png/ ) this should work
RewriteCond %{HTTP_HOST} ^www\.domain\.com$ [NC]
RewriteRule ^(.*)$ http://www.domain2.com/$1
Note that i don't have a way to test this so this should be taken as a pointer in the right direction as opposed to an explicit answer.
If you are staying on the same server then putting this in your .htaccess will work regardless of the server:
RedirectMatch 301 ^/terms$ /articles/terms/
Produces:
http://example.com/terms -> http://example.com/articles/terms
or:
http://test.example.com/terms -> http://test.example.com/articles/terms
Obviously you'll need to adjust the REGEX matching and the like to make sure it copes with what you are going to throw at it. Same goes for the 301, you might want a 302 if you don't want browsers to cache the redirect.
If you want:
http://example.com/terms -> http://server02.example.com/articles/terms
Then you'll need to use the HTTP_HOST parameter.
You don't need to include this information. Just provide a URI relative to the root.
Redirect temp /terms /articles/terms/
This is explained in the mod_alias documentation:
The new URL should be an absolute URL beginning with a scheme and hostname, but a URL-path beginning with a slash may also be used, in which case the scheme and hostname of the current server will be added.
It sounds like what you really need is just an alias?
Alias /terms /www/public/articles/terms/

Resources