redirecting with virtual hosts except robots.txt - apache

I'm having a complicated seo issue where google has indexed thousands of pages from one of my nameservers. I need to redirect every request 301 EXCEPT robots.txt
This is what I have so far, but its not working. The commented out portion is a section that i originally put (that works), except it doesnt account for robots.txt. The two lines under that are my failure attempt
<VirtualHost xx.xx.xx.xx:80>
ServerName ns2.example.com
#RedirectMatch permanent /(.*) http://example.new/$1
RewriteCond %{REQUEST_URI} !^/robots\.txt [NC]
RewriteRule ^(.*)$ http://example.new/$1 [R=301,L]
</VirtualHost>
Does anyone see my error? example.new is the site i want to redirect to

Does anyone see my error? example.new is the site i want to redirect to
For starters, it looks like you need to turn on the rewrite engine:
RewriteEngine On
that worked, except now its redirecting everything as http://example.com//whatever-page with two //
This line:
RewriteRule ^(.*)$ http://example.new/$1 [R=301,L]
Needs to have the / removed:
RewriteRule ^(.*)$ http://example.new$1 [R=301,L]
This is because the URI that the RewriteRule is matching against has a leading slash when in vhost/server config, so you don't need the slash after the hostname in your target.

Related

.htaccess redirecting URL but not content for subdomain

I'm trying to set up a test site but having real trouble getting .htaccess to redirect properly.
I want the contents of www.example.com/test to show when a user types in test.example.com. My rewrite rules allow me to use test.example.com in the address bar, but it's actually showing me the content of the root (www.example.com), not the test subfolder.
I'm not an .htaccess guru by any stretch, but I've been using Stack Overflow for 5 years and this is the first time I've been stumped enough to ask a question! Your collective wisdom is appreciated.
Here's the relevant part of my .htaccess code:
RewriteEngine On
# Rewrite for http cases
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L]
# Rewrite for no www cases
RewriteCond %{HTTP_HOST} !www\.example\.com [NC]
#redirect for test subdomain
RewriteCond %{HTTP_HOST} !^test\.example\.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]
# redirect to correct for old subfolder usage
RewriteRule ^oldsubfolder/$ https://www.example.com/ [L,R=301]
I want the contents of www.example.com/test to show when a user types in test.site.com.
I assume you just have one domain and test.site.com should really be test.example.com (which would seem to be consistent with the rest of your question)?
In the code you've posted, there's nothing that really attempts to do this redirect? In the code you've posted, a request for test.example.com would not be redirected - so if it is then you may be seeing a cached response. Clear your browser cache.
You would need something like:
RewriteCond %{HTTP_HOST} ^(?:www\.)?(test)\.example\.com [NC]
RewriteRule (.*) http://www.example.com/%1/$1 [R,L]
The (?:www\.)? part simply catches an optional www subdomain of the subdomain! Depending on how this subdomain was created, both test.example.com and www.test.example.com might be accessible. (Although I suspect your SSL cert probably doesn't allow this anyway?)
%1 is a backreference to the captured group in the CondPattern (ie. test) and $1 is a backreference to the captured RewriteRule pattern. Capturing the subdomain (eg. "test") just avoids repetition, but also allows for more than one subdomain to be handled by the same rule.
This is also a temporary (302) redirect. Change this to a 301 only when you are sure it's working (if that is the intention). 301s are cached by default, so can make testing problematic.
Clear your browser cache before testing.
# Rewrite for no www cases
RewriteCond %{HTTP_HOST} !www\.example\.com [NC]
#redirect for test subdomain
RewriteCond %{HTTP_HOST} !^test\.example\.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]
The comment in the middle of this block would seem to be misleading (it doesn't "redirect for test subdomain"). The whole block just redirects to www, excluding the test subdomain. The other code then redirects the subdomain.
UPDATE:
I was hoping it would continue to show test.example.com in the address bar
Yes, this is possible. Providing test.example.com and www.example.com point to the same filesystem then you can simply rewrite the request without actually changing the host. For this example, I'll assume test.example.com and www.example.com point to the same document root.
Change the above redirect to the following rewrite:
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{HTTP_HOST} ^(?:www\.)?(test)\.example\.com [NC]
RewriteRule (.*) /%1/$1 [L]
The request now stays on test.example.com and will serve content from test.example.com/test (although this is hidden from the user) since test.example.com and www.example.com are really the same thing.
The check against REDIRECT_STATUS ensures we are only processing the intial request and not the rewritten request, thus avoiding a rewrite loop. REDIRECT_STATUS is empty on the initial request and set to 200 after the first successful rewrite.
However, if test.example.com points somewhere entirely different then you'll need to implement a reverse proxy and "proxy" the request to www.example.com in order to "hide" this from the user.

Redirection between domains

I have two webs on two different domains. One is on domain.com and the other web is on domain.es.
I am shutting down the web on domain.es but first I have to redirect every request to domain.es to domain.com. This is easy and I had already done it with RewriteCond & RewriteRule, like this:
www.domain.es/ -- redirects to --> www.domain.com/
But I am having a problem now. I also need to redirect one specific page from domain.es to domain.com like this:
www.domain.es/a_page/ -- redirects to --> www.domain.com/another_page/
I am having problems when redirecting with both rules, as when apache detects a request to www.domain.es/a_page it goes to www.domain.com/ and not to the specific page I need.
I have this in my virtualhost:
RewriteCond %{HTTP_HOST} ^domain.es/a_page/
RewriteRule ^(.*)& http://www.domain.com/another_page/ [R=301,L]
RewriteCond %{HTTP_HOST} ^domain.es/
RewriteRule ^(.*)& http://www.domain.com/ [R=301,L]
I've got the [L] flag so apache would stop processing rules, but this is not working.
Any help would be appreciated.
RewriteCond %{HTTP_HOST} ^domain.es/a_page/
The line above is never going to match anything - you're asking if the host is equal to domain.es/a_page/, which is a host as well as a path. You need to test against only the hostname, and then redirect based on the path, e.g.
RewriteCond %{HTTP_HOST} ^domain\.es
RewriteRule ^a_page/ http://www.domain.com/another_page/ [R=301,L]

.htaccess prepending additional '/' when redirecting to www.*

I am using this snippet:
RewriteEngine on
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}$1 [R=301,L]
to redirect non-www requests to www.domain.tld. The redirect is fine except when I access the domain like domain.tld i get redirected to www.domain.tld// (Note the second slash). And that occurs only if the query string is empty, if I add /test/123 to it I get a perfect redirection: www.domain.tld/test/123/ as expected.
What are the possible reasons and how could I fix it?
What is the reason for this strange behaviour?
PS If you want to see the full VHost config, let me know :)

How to combine Apache redirects?

I've got an Apache config that features multiple rewrite rules and redirects in order to get the cutest URLs, prevent duplicates for SEO, etc. Here's a snippet as an example (it features a lot more):
# Redirecting non-www to www
RewriteCond %{HTTP_HOST} ^example.com
RewriteRule (.*) http://www.example.com/$1 [R=301,L]
# Removing index.php
RewriteCond %{REQUEST_URI} index\.php$ [NC]
RewriteRule .* / [R=301,L]
# A big bunch of these
Redirect permanent /old-article.html http://www.example.com/new-article.html
Redirect permanent /another-old-article.html http://www.example.com/new-article2.html
This works well, but it happens to generate a lot of redirects. A common case looks like this:
http://example.com/index.php, 301 redirect to http://www.example.com/index.php
http://www.example.com/index.php, 301 redirect to http://www.example.com
It sometimes reaches 4-5 redirects.
Now, I want all these rules to be chained and generate only one 301 redirect, like this:
http://example.com/index.php, 301 redirect to http://www.example.com
I know I can spend an afternoon thinking and sorting the rules to a better match, and also that I can create combined rules. But that would complicate an already long file. I want a flag, operand or whatever that will execute all the rules as if they where internal and only issue the redirect once it has crawled every rule. Is this even possible?
It seems as if simply re-ordering this would get you what you want:
# A big bunch of these
Redirect permanent /old-article.html http://www.example.com/new-article.html
Redirect permanent /another-old-article.html http://www.example.com/new-article2.html
# Removing index.php
RewriteRule ^/index.php http://www.example.com/ [R=301,L]
# Redirecting non-www to www
RewriteCond %{HTTP_HOST} ^example.com
RewriteRule (.*) http://www.example.com/$1 [R=301,L]
A direct request for an old article at the example.com domain:
http://example.com/old-article.html
Will result in a single redirect to:
http://www.example.com/new-article.html
A request for either http://example.com/index.php or http://www.example.com/index.php will result in a single redirect to:
http://www.example.com/
A request that doesn't match anything else will result in a single redirect from:
http://example.com/foo
To:
http://www.example.com/foo
This seems to cover all the bases. Have I missed anything?
Remove the [L] flag from your RewriteRules, and they will be combined automatically.

.htaccess 301 redirect from old domain to new domain while structure of pages and url are same

I want to redirect http://olddomain.com to http://newdomain.com for my all urls..keeping the page on new domain same.
What i mean to say is URLs such as below
http://olddomain.com/home/category/page.html
http://olddomain.com/home/mybook/page2.html
http://olddomain.com/login
should be 301 redirect to the new newdomain but same pages, like below
http://newdomain.com/home/category/page.html
http://newdomain.com/home/mybook/page2.html
http://newdomain.com/login
this is what i have in my .htaccess currently
RewriteEngine on
RewriteCond $1 !^(index\.php|img|public|robots\.txt) [NC]
RewriteRule ^(.*)$ /index.php?/$1 [L]
Please help me to do this cleanly and exlpain things in details since i am new in this.
also does someone know how much time search engines might take to move away from the references of my olddomain? i mean the old-domain urls in search queries should be replaced by new-domain urls... n old domain should go away from search engines.
Add following code at the beginning of .htaccess -
RewriteEngine On
# Redirect Entire Site to New Domain
RewriteCond %{HTTP_HOST} ^olddomain.com$ [OR]
RewriteCond %{HTTP_HOST} ^another.olddomain.com$ [NC]
RewriteRule ^(.*)$ http://newdomain.com/$1 [R=301,L]
Much simpler:
Redirect 301 / http://newdomain.com/
Replace your .htaccess file with that one line OR if you have access to it, put it in the apache conf file(s) for your old domain (I place it following the DocumentRoot directive).
See Redirecting and Remapping with mod_rewrite for more info.
I usually add the following codes in .htaccess in the old website
#Options +FollowSymLinks
RewriteEngine on
RewriteRule ^(.*)$ http://newdomain.com/$1 [R=301,L]
This above code will redirect all links to new domain, you don't have to do anything, each link and images redirect to new domain link.
Beside this we have to tell Google when your site moves
If you've moved your site to a new domain, you can use the Change of address tool to tell Google about your new URL. We'll update our index to reflect your new URL. Changes will stay in effect for 180 days, by which time we'll have crawled and indexed the pages at your new URL.
Here is the link for this https://support.google.com/webmasters/answer/83106?hl=en
I have done this for 2 to 3 sites without losing seo as well. It does work.
Thanks
Tried to do
LoadModule rewrite_module modules/mod_rewrite.so
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_HOST} ^localhost$ [NC]
RewriteRule ^(.*)$ http://newdomain.com/$1 [R=301,L]
</IfModule>
But did not worked the way it should, was just trying to point my localhost to newdomain.com.
But when I hit localhost still it does not point.