How to rewrite URL based on domain in apache and add extra parameter? - apache

Basically, what I want to do is to rewrite all urls because we have many different languages. We have a server that hosts several domains. We have www.example.com, www.example.fr, www.example.de, www.anotherdomain.com, www.anotherdomain.de. What I want to do is to redirect all requests from example.xxx to www.example.com with extra url parameter lang=en. This should not affect other domains like www.anotherexample.com etc.
This does not work:
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.de$
RewriteRule ^(.*)$ http://www.example.com/$1?lang=de [PT]
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.fr$
RewriteRule ^(.*)$ http://www.example.com/$1?lang=fr [PT]
One thing that makes it even more difficult is that the ServerName is totally different than the host name, it is called prod.migr.com.
Any suggestions would be appreciated.

Try this:
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.de$
RewriteRule ^ http://www.example.com%{REQUEST_URI}?lang=de [L,R=301,QSA]
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.fr$
RewriteRule ^ http://www.example.com%{REQUEST_URI}?lang=fr [L,R=301,QSA]

The PT flag is most likely your problem. I've never seen it used when the target is a full domain address because it's meant for URI's to be further redirected with mod_alias.
The flag you should be using is the QSA flag in case the page the user is visiting has a query string on it.
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.de$
RewriteRule ^(.*)$ http://www.example.com/$1?lang=de [QSA]
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.fr$
RewriteRule ^(.*)$ http://www.example.com/$1?lang=fr [QSA]
However, a much better solution would be to check the host the user is visiting in your server-side language such as php or asp if all languages are hosted on the same server like this.
EDIT in response to additional information:
You can not get POST variables through rewriting to different domains like that because it has to redirect the request.
Your best bet is to determine the language in your server side language instead of using mod_rewrite.
If you use php it would be like this
$lang = substr(strrchr($_SERVER['HTTP_HOST'], '.'), 1);
Other languages have similar ways to determine the host.

Related

What is the correct syntax for "if host is not foo, redirect to bar" in a .htaccess file?

This website has a ton of extra domains (note: these are not subdomains; one of them, for instance, is http://eduard.fi) that the owner (or the SEO people, rather) wants to redirect to the main domain. Instead of listing them one by one, this is what I tried:
RewriteCond %{HTTPS_HOST} !^masetti\.fi$
RewriteRule ^(.*)$ https://masetti.fi/$1 [R=301,L]
However this creates a redirect loop. Why is that? This does not produce a server error, so for that part the syntax is correct, but it does not do what I want.
You were close, but made a logical mistake. Take a look at this:
RewriteEngine on
RewriteCond %{HTTP_HOST} !^masetti\.fi$
RewriteRule ^(.*)$ https://masetti.fi/$1 [R=301]
An alternative would be that:
RewriteEngine on
RewriteCond %{HTTP_HOST} !^masetti\.fi$
RewriteRule ^ https://masetti.fi%{REQUEST_URI} [R=301]
The RewriteCond has been slightly altered: It is the variable %{HTTP_HOST} you want to check, not %{HTTPS_HOST}which does not exist.
PS: it is a good idea to start out with a 302 redirection and only change that to a 301 once everything works as intended. That prevents issues with client side caching.

How to redirect url to the url with htaccess

I didn't know how to question this but my problem is like this
I have written a rule for a url
RewriteRule ^mysite.com.pk/([a-zA-Z0-9]+) index.php?store=$1
RewriteRule ^mysite.com.pk/([a-zA-Z0-9]+)/products index.php?store=$1&view=products
RewriteRule ^mysite.com.pk/([a-zA-Z0-9]+)/products/([0-9]+) index.php?store=$1&view=products&category=$2
RewriteRule ^mysite.com.pk/([a-zA-Z0-9]+)/single/([0-9]+) index.php?store=$1&view=single&product=$2
I am new to htaccess so I don't know much about it. Is there a way that even if a old url comes like index.php?store=abc&view=single&product=123
this will be redirected to a new one like mysite.com.pk/abc/single/123
You have to make some small modifications to your proposed rules to get them to work. And you have to add additional rewriting rules to achieve what you actually ask: redirecting "old" URLs to your new syntax.
This is probably what you are looking for:
RewriteEngine on
RewriteRule ^/?([a-zA-Z0-9]+)$ index.php?store=$1 [END]
RewriteRule ^/?([a-zA-Z0-9]+)/products$ index.php?store=$1&view=products [END]
RewriteRule ^/?([a-zA-Z0-9]+)/products/([0-9]+)$ index.php?store=$1&view=products&category=$2 [END]
RewriteRule ^/?([a-zA-Z0-9]+)/single/([0-9]+)$ index.php?store=$1&view=single&product=$2 [END]
# index.php?store=xyz&view=single&product=123
RewriteCond %{QUERY_STRING} store=([^&]+)&?
RewriteCond %{QUERY_STRING} view=single&?
RewriteCond %{QUERY_STRING} product=([^&]+)&?
RewriteRule /?index.php$ /%1/single/%3 [END,R=301]
# index.php?store=xyz&view=products&product=123
RewriteCond %{QUERY_STRING} store=([^&]+)&?
RewriteCond %{QUERY_STRING} view=products&?
RewriteCond %{QUERY_STRING} category=([^&]+)&?
RewriteRule /?index.php$ /%1/products/%3 [END,R=301]
# index.php?store=xyz&view=products
RewriteCond %{QUERY_STRING} store=([^&]+)&?
RewriteCond %{QUERY_STRING} view=products&?
RewriteRule /?index.php$ /%1/products [END,R=301]
# index.php?store=xyz
RewriteCond %{QUERY_STRING} store=([^&]+)&?
RewriteRule /?index.php$ /%1 [END,R=301]
Those rules should work the same in a .htaccess style file and in the real http host configuration. Please see the note below about that.
If you are using an old version of the apache http server then you may have to replace the END flag by the L flag. Try that if you receive an "internal server error" (http status 500) and the server complains about the END flag in the error log file. You may have to add some additional conditions to prevent an endless rewriting loop in that case.
Please note that I did not test that rule set. I hope it does not contain any silly mistakes and you certainly will have to test it.
All of the above assumes that mysite.com.pk is meant to match your host name ("domain"). But that will not work, since the RewriteRules work on the request path, not the full URL. If you want to limit the application of the rules to a specific host, then you can add a leading condition to stop the rewriting process:
RewriteCond %{HTTP_HOST} !^mysite\.com\.pk`
RewriteRule .* - [END]
And a general hint: you should always prefer to place such rules inside the http servers host configuration instead of using .htaccess style files. Those files are notoriously error prone, hard to debug and they really slow down the server. They are only provided as a last option for situations where you do not have control over the host configuration (read: really cheap hosting service providers) or if you have an application that relies on writing its own rewrite rules (which is an obvious security nightmare).

.Htaccess RewriteRule (Subdomain vs Request_URI)

I have several domain names, each with their own multiple subdomains.
currently, I have a global RewriteRule for any domain with a specific Request_URI meant for my REST APIs.
.htaccess
RewriteEngine on
RewriteRule ^/?api/(.*)$ /api/inbound.php [NC,L]
Affected Url Examples:
acct.domain1.com/api/clients/123
my.domain2.com/api/tasks/2323
new.domain3.com/api/products/1212
And the Rule works great!
Now I've started using these subdomains:
api.domain1.com/api/clients/123
api.domain2.com/api/tasks/2323
api.domain3.com/api/products/1212
Though this still works, it's annoyingly redundant.
So, if the Subdomain happens to be "api, sandbox, api.test, or any chosen nuance I'm going to omit the /api/ path from the URL.
How would the RewriteRule look for this scenario?
Examine the HTTP Host Header value with a RewriteCond:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^api(\.test)?|sandbox
RewriteRule ^/?(.*)$ /api/inbound.php [NC,L]

Is my rewrite code correct?

I am trying to write rewrite code for my customer's site. I have no way of verifying if it's correct because I don't have access to the server yet. I know that sounds strange but it's what I have to accept and work around.
I plan to put this in the root htaccess file on the server. Bottom line is this URL does not work:
http://www.regions.noaa.gov/gulf-mexico/index.php/highlights/restore-act-passed/
So when the above fires, I want it to permanently redirect to:
http://www.regions.noaa.gov/gulf-mexico/highlights/restore-act-passed/
Here is what I have
RewriteEngine on
RewriteCond %{HTTP_HOST} ^regions\.noaa\.gov$ [OR]
RewriteCond %{HTTP_HOST} ^www\.regions\.noaa\.gov$
RewriteRule ^gulf\-mexico\/index\.php\/highlights\/restore\-act\-passed\/$ "http\:\/\/www\.regions\.noaa\.gov\/gulf\-mexico\/highlights\/restore\-act\-passed\/" [R=301,L]
I'd appreciate any feedback on this. Thanks.
UPDATE - thanks to all who replied. Here's what I don't understand. I found this code on my web hosting company's code generator. It seems to work:
RewriteCond %{HTTP_HOST} ^designerandpublisher.com$ [OR]
RewriteCond %{HTTP_HOST} ^www.designerandpublisher.com$
RewriteRule ^services.html$ "http\://www.regions.noaa.gov/gulf-mexico/highlights/restore-act-passed/" [R=301,L]
I usually do like this and works fine.
IF user enter in the URL with highlights/restore-act-passed/ THEN will display contents from index.php/highlights/restore-act-passed/ in the browser.
# [NC] Means “No Case”, so it doesn’t matter whether the domain name was written in upper case, lower case or a mixture of the two.
RewriteEngine on
RewriteRule ^highlights/restore-act-passed/?$ index.php/highlights/restore-act-passed/ [NC]
IF the user enter in the URL with index.php/highlights/restore-act-passed/ THEN will display contents from _http://%{HTTP_HOST}/gulf-mexico/highlights/restore-act-passed/
RewriteRule ^index.php/highlights/restore-act-passed/?$ _http://%{HTTP_HOST}/gulf-mexico/highlights/restore-act-passed/ [NC]
You don't need to specify the HTTP_HOST, unless you will have multiple domains coming through here (add-ons, subdomains, parked domains, etc.). If you do want to specify it, it can be simplified to one line:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www\.)?regions\.noaa\.gov$
RewriteRule ^gulf\-mexico\/index\.php\/highlights\/restore\-act\-passed\/$ "http\:\/\/www\.regions\.noaa\.gov\/gulf\-mexico\/highlights\/restore\-act\-passed\/" [R=301,L]
Actually, a subdomain doesn't even need the www, but it doesn't hurt. Then, in the rewrite rule, you only need to escape specific metacharacters in the pattern, and none in the replacement string:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www\.)?regions\.noaa\.gov$
RewriteRule ^gulf-mexico/index\.php/highlights/restore-act-passed(/)?$ http://www.regions.noaa.gov/gulf-mexico/highlights/restore-act-passed/ [R=301,L]
I also made the last (trailing) / optional. Since you're going to the same domain, there is no need to repeat it:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www\.)?regions\.noaa\.gov$
RewriteRule ^gulf-mexico/index\.php/highlights/restore-act-passed(/)?$ /gulf-mexico/highlights/restore-act-passed/ [R=301,L]
The 301 code says to alert search engines that this URL or URI has permanently moved (it will show up changed in a browser address bar, too, so human visitors can choose to rebookmark it).
As this appears to be an SEO URI, presumably it will be translated into a dynamic format (/gulf-mexico/index.php?area=highlights&item=restore-act-passed). That means that the above rewrite has to be done before any SEO-to-dynamic translation. An alternative would be to directly translate it to dynamic format right here, but since you're giving a 301, presumably you want the SEO format to show in a browser or search engine result.

Apache mod_rewrite: can these simple RewriteRule be improved? And suggestions!

I started finally to understand Apache mod_rewrite. It's pretty GREAT!
Plz have a look at the followings:
1) Permanent redirects http://www.domain.com/folder_name/ (with or without final slash and with or without the www) to http://www.domain.com/some/path/some_page.html
RewriteRule ^folder_name[/]*$ "http\:\/\/domain\.com\/some\/path\/some_page.html" [R=301,L]
2) Permanent redirects all requests to www.domain.com... to same path and file request but without www in domain
RewriteCond %{HTTP_HOST} !^domain.com$
RewriteRule ^(.*)$ "http\:\/\/domain\.com\/$1" [R=301,L]
They all work as expected and do their jobs, I'm simply curios if some guy, who is more expert than me in mod_rewrite, could give me some advises like: "it could be better in this way...", "there might be a problem if...", etc.
Thanks!
Use the ? quantifier instead of * and you don’t need to escape the substitution URL:
RewriteRule ^folder_name/?$ http://example.com/some/path/some_page.html [R=301,L]
You might want to consider HTTP 1.0 requests where the Host header field is missing. Another useful extension would be to take HTTPS into account:
RewriteCond %{HTTP_HOST} !^(|example\.com)$
RewriteCond %{HTTPS} ^on(s)|
RewriteRule ^ http%1://example.com%{REQUEST_URI} [R=301,L]