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

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 :)

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.

.htaccess redirect to example.com except for directory redirect to example.com/example

Variations on this question have been asked, and so I apologize in advance -- I simply cannot get this to work. I know the devil is in the details with the .htaccess, so I'm sure I'm missing something small.
Here's what have:
I have a page: example.com/ which redirects all traffic to its https equivalent. I'm building the next version of the same site inside of the directory example.com/example.com/ I'm trying to write a redirect that will send all traffic to its https equivalent except for the directory that I'm working in, which should be left alone. My problem is, whenever I try to access example.com/example.com/ I get redirected to the 404 of example.com (which makes sense). I just can't get the redirect to not loop indefinitely.
I currently have a redirect from http to https for example.com as follows:
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://example.com/$1 [R,L]
This works just fine, and only causes troubles when I try to access the subfolder.
tl;dr
Here's what I need:
http://example.com/ REDIRECTS TO https://example.com/
http://example.com/[anything else] REDIRECTS TO https://example.com/[anything else]
https://example.com/example.com/ SHOULD NOT REDIRECT
Try:
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteCond %{REQUEST_URI} !example.com
RewriteRule ^(.*)$ https://example.com/$1 [L]

.htaccess mod_rewrite redirect without query string variables not working

I'm having a problem with one of my rewrite rules. I would like to redirect all of the following URL's to another URL without the query string.
/gallery/products.aspx?C=9&SC=&ID=428&P=10
/gallery/products.aspx?C=2&SC=2&ID=128&P=1
/gallery/products.aspx?ID=147&C=2&SC=&P=7
/gallery/products.aspx?ID=1337&C=15&SC=&P=1
/gallery/products.aspx?ID=1532&C=3&SC=&P=2
/gallery/products.aspx?C=9&SC=&ID=1489&P=1
/gallery/products.aspx?C=7&SC=&ID=100&P=2
/gallery/products.aspx?C=2
/gallery/products.aspx?ID=1328&C=14&SC=11&P=17
/gallery/products.aspx?C=1&SC=&ID=767&P=3
/gallery/products.aspx?ID=1270&C=1&SC=&P=26
and I have this in my .htaccess file
RewriteRule ^gallery/products.aspx http://www.domain.com/category/? [L,R=301]
but it's not working. I checked it in a .htaccess simulator and it found the rule then redirected, but when I upload to my server, it doesn't redirect. I've also tried some other rules with no luck
I was finally able to make this work with the following:
RewriteCond %{HTTP_HOST} www.domain.com [NC]
RewriteRule products.aspx http://www.domain.com/category? [L,R=301]

ModRewrite: QUERY_STRING not redirecting

I have the following rewrite rules in place:
RewriteEngine on
RewriteCond %{QUERY_STRING} ^manufacturer=&
RewriteRule (.*) $1? [R=410,L]
But it doesn't seem to work. I'm trying to redirect with URL's like
http://www.example.com/?manufacturer=someone to http://www.example.com/ and page.php?manufacturer=someone to page.php
What am I doing wrong?
EDIT:
I have mod_rewite enabled and AllowOverride All in my site config
The above code is in the .htaccess file
The query string ^manufacturer=& only matches manufacturer parameters that are empty and it also requires that the equals sign is followed by an ampersand which doesn't seem to be your wanted behaviour.
By the way, you do realize the status code 410 means that the resource is Gone (indicates that the resource requested is no longer available and will not be available again)?
You seem to want to redirect back to the current page without the query parameter, so I suggest using a 302 or 301 redirect instead.
Try this:
RewriteEngine on
RewriteCond %{QUERY_STRING} ^manufacturer=.+$
RewriteRule .* $0? [R=301,L]

redirecting with virtual hosts except robots.txt

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.