Something wrong in my .htaccess/mod_rewrite rule? - apache

Next simple rule at .htaccess for redirect all requests with non-www to www:
RewriteCond %{HTTP_HOST} !^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://www.%1/$1 [R=301,L]
and when check it with the URL of kind
http://example.com/something
this redirect me to
http://www./something
seems that RewriteCond works, but there is nothing in result of regular expression, where as i think must be the host name without www. What's wrong - who knows?
Variants of rules with redirect to concrete host, like:
RewriteCond %{HTTP_HOST} !^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]
and other alike variants works fine.

Instead of capturing the HTTP_HOST into %1 with (.*) (which isn't working for you), just substitute %{HTTP_HOST} in the RewriteRule:
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
The way you had it, your %1 is not populated because of the ! negation, it would seem.
From the RewriteRule documentation:
When using the NOT character to negate a pattern, you cannot include grouped wildcard parts in that pattern. This is because, when the pattern does NOT match (ie, the negation matches), there are no contents for the groups. Thus, if negated patterns are used, you cannot use $N in the substitution string!

This standard way of doing this seems to be:
RewriteCond %{HTTP_HOST} ^example\.com$
RewriteRule ^(.*) http://www.example.com/$1 [R=301]
This is how mediatemple, wordpress, etc. recommend their users setup their .htaccess files.

Related

three conditions and one rule to use any domain name in htaccess file

I have these conditions and rule in my htaccess file, and it works and does what it's supposed to do.
RewriteCond %{REQUEST_URI} !^/index/parser.php?(.*)?$
RewriteCond %{HTTP_HOST} ^(.*)\.mydomain\.extension$ [NC]
RewriteCond %{HTTP_HOST} ^(www\.)?([a-z0-9-.]+)\.mydomain\.extension [NC]
RewriteRule ^(.*)$ http://mydomain.extension/index/parser.php?%2&domain_name=mydomain.extension [QSA,L]
I want to rewrite it so it can work with any domain name pointed at the server, but don't know how. I tried this but it failed. It should only activate on subdomains, not root domains. Also, I am not versed on the whole dollar sign and percentage usage in htaccess files. $1, $2, %1, %2, etc. Never know when dollar or percent should be used, or what number to use after it.
RewriteCond %{REQUEST_URI} !^/index/parser.php?(.*)?$
RewriteCond %{HTTP_HOST} ^(.*)\.(.*)$ [NC]
RewriteCond %{HTTP_HOST} ^(www\.)?([a-z0-9-.]+)\.(.*) [NC]
RewriteRule ^(.*)$ /index/parser.php?%2&domain_name=%1 [QSA,L]
Edit
Tried this on last line. Still didn't work.
RewriteRule ^(.*)$ http://%1/index/parser.php?%2&domain_name=%1 [QSA,L]
Edit
Tried suggestion and it made this:
something.tld
Go to this:
http://tld/index/parser.php?something&domain_name=tld
Should be:
http://something.tld/index/parser.php?something&domain_name=something.tld
Edit
The next version didn't work either. Showed an internal server error page. Same error whether domain.tld was used or subdomain.domain.tld was used.
How about:
RewriteCond %{REQUEST_URI} !^/index/parser.php
RewriteCond %{HTTP_HOST} ^(?:www\.|)([a-z0-9-]+)\.(.+\.(?:[a-z]{2}\.[a-z]{2}|[a-z]+))$ [NC]
RewriteRule ^(.*)$ http://%2/index/parser.php?%1&domain_name=%2 [QSA,L]
So this will take a request for:
http://www.foo.some-domain.tld/anything
and redirect to:
http://some-domain.tld/index/parser.php?foo&domain_name=some-domain.tld
As far as the backreferences go, the $ ones backreference groupings made in the rewrite rule, while the % ones backrefernce groupings from a rewrite condition.
See: http://httpd.apache.org/docs/trunk/rewrite/intro.html#regex

Mod ReWrite to remove component of URL

I must be an idiot because I just can't work this bit out.
I've got a URL:
www.site.com.au/products/product-name.html
I need to redirect these to:
www.site.com.au/product-name.html
All the links are dynamic, the folder doesn't exist. What ReWrite rule do I use to accomplish this?
This is what I've got so far:
RewriteCond %{HTTP_HOST} ^(www|test)\.site\.com\.au
RewriteCond %{REQUEST_URI} ^(/products/)
RewriteCond %{REQUEST_URI} [A-Z]
RewriteRule ^.+\.html$ ${lc:%{REQUEST_URI}} [NC,R=301,L]
Just need to add the bit to remote /products
Thanks.
RewriteRule ^products(/.*)$ http://www.site.com.au$1 [L, R=301]
This replaces everything you listed, except for the first RewriteCond (to match the domain, though if your VirtualHost only answers on those two domains, you can exclude that RewriteCond to simplify it).
RewriteRules are matched first before Apache looks at the RewriteConds, so if you can do the match in the RewriteRule itself it greatly simplifies things. Just for your future reference, if you did need to match in the RewriteCond, it would look something like this:
RewriteCond %{REQUEST_URI} ^/products(/.*)$
RewriteRule ^.*$ http://www.site.com.au%1 [L, R=301]
Note the %1 for matching what's in the parentheses in the RewriteCond vs. the $1 for matching what's in the RewriteRule.
EDIT: Per your comment, the following modification should force lowercase. I haven't had to do that myself, but per this Apache documentation it's an internal function via RewriteMap. Based on your original code it looks like maybe you already have the RewriteMap definition elsewhere. If not, I've included it here.
RewriteMap lc int:tolower
RewriteCond %{REQUEST_URI} ^/products(/.*)$ [NC]
RewriteRule ^.*$ http://www.site.com.au${lc:%1} [L, R=301]
OK, I really don't know enough about Apache Rewrite to figure out the exact formatting. But after much ado these are the results that worked:
# Lowercase all /products/
RewriteCond %{HTTP_HOST} ^(www)\.site\.com\.au
RewriteCond %{REQUEST_URI} ^/products/.+\.html
RewriteCond %{REQUEST_URI} [A-Z]
RewriteRule ^ ${lc:%{REQUEST_URI}} [R=301,L]
# Lowercase all /products/ and strip products/ subfolder
RewriteCond %{HTTP_HOST} ^(www)\.site2\.com\.au
RewriteCond %{REQUEST_URI} ^/products/.+\.html
RewriteCond %{REQUEST_URI} [A-Z]
RewriteRule ^products/(.+\.html)$ /${lc:$1} [R=301,L]
Thanks,
Dom

Non www to www using httpd.conf - // error

When I use
RewriteEngine On
RewriteCond %{HTTP_HOST} ^example.com
RewriteRule (.*) http://www.example.com/$1 [R=301,L]
in my httpd.conf file, why is my site redirecting to www.example.com//
(www.example.com//file.html). Why are there two slashes ?
I think this should be:
RewriteCond %{HTTP_HOST} !^www\.example\.com [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [L,R=301]
EDIT:
The above RewriteCond was probably overkill - it was intended to only match urls that are not preceded by www. However this should work too:
RewriteCond %{HTTP_HOST} ^example.com
RewriteRule ^(.*)$ http://www.example.com/$1 [L,R=301]
Like David Chan mentioned, the ^(.*)$ is what you were missing. The ^ and $ are special characters in Regular Expressions. Here is a link that explains regex string anchors: http://www.regular-expressions.info/anchors.html
Also, here is a link that can explain the mod_rewrite syntax in more detail: http://httpd.apache.org/docs/current/mod/mod_rewrite.html

mod_rewrite for specific domains in a mappings file

I have a bunch of domains that I want to go to one domain but various parts of that domain.
# this is what I currently have
RewriteEngine On
RewriteCond %{HTTP_HOST} ^.*\.?foo\.com$ [NC]
RewriteRule ^.*$ ${domainmappings:www.foo.com} [L,R=301]
# rewrite map file
www.foo.com www.domain.com/domain/foo.com.php
www.bar.com www.domain.com/domain/bar.com.php
www.baz.com www.domain.com/other/baz.php.foo
The problem is that I don't want to have to have each domain be part of the RewriteCond. I tried
RewriteCond %{HTTP_HOST} ^www\.(.*)
RewriteRule (.*) http://%1/$1 [R=301,L]
but that will do it for EVERY domain. I only want the domains that are in the mappings file to redirect, and then continue on to other rewrites if it doesn't match any domains in the mappings file.
I'm close as I figured out the the case matching, but unable to figure out the www prefix. If I use the first one below, it works without www. If I use the second one, it works with the www. If I use BOTH - neither work.
RewriteCond %{HTTP_HOST} (.*)$ [NC] # works for without www
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC] # works with www
RewriteCond ${domainmappings:%1|NOTFOUND} ^(.+)$ [NC]
RewriteCond %1 !^NOTFOUND$
RewriteRule ^.*$ ${domainmappings:%1} [L,R=301]
Any ideas?
You are on the right track. What you have to do is use the pipe operator on the map so that you have a catch-all.
RewriteCond ${domainmappings:%{HTTP_HOST}|NOTFOUND} ^(.+)$
RewriteCond %1 !^NOTFOUND$
RewriteRule ^.*$ ${domainmappings:%1} [L,R=301]
The second condition will not match if the host is not in the list. You still have to deal with the www prefix, and the case matching, but you get the idea.

mod_rewrite rules, how to test for 'not a string'?

I have a blog installed in www.foo.com/wp/ and would like all requests that go to any page that doesn't start with /wp/ to be redirected to www.foo.com/wp/ (without preservation of the URL).
E.g.:
www.foo.com/bar/baz/hello.gif > www.foo.com/wp/
Also, at the same time, I need the URL to have www. added if it doesn't (which might be where my rules are getting confused)
At the moment, I have:
RewriteCond %{HTTP_HOST} !^www.foo.com [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule ^/(.*) http://www.foo.com/$1 [R=permanent]
RewriteRule ^(?!wp)/(.*)$ http://%{HTTP_HOST}/wp/($2) [R=permanent]
But I think this is currently completely broken.
Help much appreciated.
RewriteCond %{HTTP_HOST} !^www.foo.com [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule (.*) http://www.foo.com/$1 [R=permanent,L]
RewriteRule ^(?!wp/)(.*) http://%{HTTP_HOST}/wp/$1 [R=permanent]
The path portion of the URL being matched never has a leading slash, and you don't need to anchor a .*.
L modified prevents rewriting from continuing after you arrive at your first redirect.
Negative-lookbehind (?!) is not a capturing construct, and you substitute in captured patterns by writing $1, not ($1).
Edit: Apparently for OP the last rule doesn't work, failing to exclude the cases that begin with /wp/, which makes no sense to me but whatever. Here's an attempt at a workaround:
RewriteCond %{HTTP_HOST} !^www.foo.com [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule (.*) http://www.foo.com/$1 [R=permanent,L]
RewriteCond %{REQUEST_URI} !^/wp/
RewriteRule (.*) http://%{HTTP_HOST}/wp/$1 [R=permanent]
Try these rules:
RewriteCond %{HTTP_HOST} !^www.exmaple.com [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule ^ http://www.example.com%{REQUEST_URI} [R=301,L]
RewriteCond %{THE_REQUEST} ^GET\ /wp/
RewriteRule ^wp/(.*) /$1 [R=301,L]
RewriteRule !^wp/ wp%{REQUEST_URI} [L]
The first rule is for the host name. The second is to remove the /wp path prefix externally. And the third is to add the prefix again for internal redirection.