Dealing with non-hardcoded domain names with mod_rewrite - mod-rewrite

I am migrating my application which provides a subsite for each user from domain.com/~user to user.domain.com. In order to do this, I wrote the following RewriteRule:
RewriteRule ^~([a-z_]+)(/.*)?$ http://$1.%{HTTP_HOST}$2 [R=301,QSA,NC]
However, %{HTTP_HOST} doesn't do exactly what I need it to, because if for instance a user browses to www.domain.com/~user, it'll redirect to user.www.domain.com which is obviously not what I'm looking for.
I know that I can replace %{HTTP_HOST} with a hardcoded domain, but I don't want to do this either, because I will be rolling out the changes on multiple domains and don't want to have to customize it for each one. Is there a better way to make a singular change without hardcoding? (Furthermore, what if the base domain already has a subdomain -- ie. sub.domain.com/~user -> user.sub.domain.com)

Try it with this additional RewriteCond:
RewriteCond %{HTTP_HOST} ^(www\.)?(.+)
RewriteRule ^~([a-z_]+)(/.*)?$ http://$1.%2$2 [R=301,QSA,NC]
This will remove the www. prefix from the host if present.

Related

Apache .htaccess mod rewrite

I need to rewrite this url schema
http://www.example.com/a/b/c/d.php?param=hi
to
http://www.example.com/a/b/d.php?type=c&param=hi
It's possible with mod_rewrite in .htaccess?
Thanks a lot for yours help!
[MORE DETAILS]
The base url of site is http://www.example.com/a/b/, and i have two type of customers, privates & sellers. I ask if is possible for customers call this url http://www.example.com/a/b/private/index.php, and internally rewrite it, with htaccess, to http://www.example.com/a/b/index.php?cust=private preserving the other GET parameters.
Well if the URL is always the same you can literally just write it one for one.
RewriteEngine On
RewriteRule ^a/b/private/index\.php$ /a/b/index.php?cust=private [QSA,L]
Ok, based on the Panama Jack's answer this is the standard rule for rewriting all page,
RewriteEngine On
RewriteRule ^/?([a-zA-Z_]+)/([a-zA-Z_]+)$ $2.php?cust=$1 [QSA]

mod_rewrite separate two numbers with hyphen/dash

To secure my URL I am trying to add some additional numeric values to the user's id using mod_rewrite.
I have this URL
https://www.domain.com/dashboard.php?userempid=48&hgid=45
I need to rewrite the above URL to
https://www.domain.com/1848-6245.html
This is what I tried and it never works
RewriteRule ^18([0-9])-62([0-9]).html$ dashboard.php?userempid=$1&hgid=$2 [NC,L]
Please Help!
Change your rule adding a plus:
RewriteRule ^18([0-9]+)\-62([0-9]+).html$ dashboard.php?userempid=$1&hgid=$2 [NC,L]

New NICE URLs with 301s. How to make them work Together?

I have this old website URL structure:
site.com/folder/prod.php?cat=MAIN%20CAT%20&prodid1=123&prodtitle=PROD%20TITLE&subcat=SUB%20CAT
and real example will be something like:
site.com/folder/prod.php?cat=CAR%20AUDIO&prodid1=4444&prodtitle=MTX%20AMPS&subcat=AMPS
here you can see that for the product page there are 4 variables: category, produt id, product title and sub category. Some of this variables were used to open a menu. And yes, the URL pulls variables with space and both lower and uppercase.
The new site url has a new structure:
site.com/x/product-title-prodid2
a rel example will be like:
site.com/x/mtx-amps-8888
Which is accomplish by using two variables (friendly slug + a second product id: prodid2) with the following code in the .htaccess
<IfModule mod_rewrite.c>
Options +Indexes
Options +FollowSymlinks
RewriteEngine on
RewriteBase /
RewriteRule ^p/(.*)/$ product.php?prodid2=$1
RewriteRule ^p/(.*)$ product.php?prodid2=$1
</IfModule>
Internally we can get prodid2 if we have prodid1 from the same table, but not viceversa.
Everything works fine, but we now have to create 301 redirects and apparently since the same variables are not used in the old / new url, then it becomes tricky since apparently we have to create a single rule for the nice URL creation and the 301s?
We have tried adding the following to the htaccess:
RewriteCond %{QUERY_STRING} ^cat=CAR%20AUDIO&prodid1=4444&prodtitle=MTX%20AMPS&subcat=AMPS$ [NC]
RewriteRule ite.com/folder/prod.php site.com/x/mtx-amps-8888? [R=301,L]
and it works for only 1 product, but when adding 2 or more, the site goes down. I imaging this would be an infinite loop?
An alternative would be adding a:
ErrorDocument 404 /404.php
to get the URL and redirect to the page, but this would be ugly for SEs.
UPDATE:
Sorry for my lack of understanding on this topic, am very new to this.
The product has 2 important ids. For example:
MTX AMP (which is the actual product title) if listed in 3 categories will have 1 single prodid2 repeated and 3 different prodid1 (1 for each category). They all reside in the same table. So, if we have a prodid1 we can get the prodid2 which is right next to it in the db table.
The rule to get a nice URL on the new site is pulled using prodid2
RewriteRule ^p/(.*)$ product.php?prodid2=$1
which brings the complete value stored in the database. e.g. mtx-amps-8888 << this is a mix of a slug + the prodid2
complete url is:
site.com/p/mtx-amps-888
(the p is just a virtual forder and we take advantage of that variable to show the right page template)
So mtx-amps-888 are not 3 keys, these are generated when creating a product and saved all together in a single field in the db. They already include the separation - so this is not done in the htaccess.
The cat (key) value is really used to expand a menu used in the old site with, but to create the 301 redirect we would probably use prodid1 since we can match that value to get a prodid2. prodid2 is used as the main query to get the nice URL in the new site and its value will bring the nice URL stored in the db.
What makes sense from all my research would be the following:
<IfModule mod_rewrite.c>
Options +Indexes
Options +FollowSymlinks
RewriteEngine on
RewriteBase /
RewriteRule ^p/(.*)$ product.php?prodid2=$1
RewriteCond %{QUERY_STRING} ^cat=CAR%20AUDIO&prodid1=4444&prodtitle=MTX%20AMPS&subcat=AMPS$ [NC]
RewriteRule ite.com/folder/prod.php site.com/x/mtx-amps-8888? [R=301,L]
RewriteCond %{QUERY_STRING} ^cat=CAR%20AUDIO&prodid1=5555&prodtitle=BOSS%20AMPS&subcat=AMPS$ [NC]
RewriteRule ite.com/folder/prod.php site.com/x/mtx-amps-8888? [R=301,L]
RewriteCond %{QUERY_STRING} ^cat=CAR%20VIDEO&prodid1=6666&prodtitle=ALPINE%20DVDS&subcat=DVD%20PLAYERS$ [NC]
RewriteRule ite.com/folder/prod.php site.com/x/mtx-amps-8888? [R=301,L]
</IfModule>
Pls note that I removed a line from the main rewrite rule:
RewriteRule ^p/(.*)/$ product.php?prodid2=$1
This only assures that the user can also use / at the end of the URL: site.com/p/mtx-amps-888/
I also repeated the rewrite condition for the 301 redirects of 3 products, but i really have about 3K products to list here. If I keep 1, it will work but if I add 2, I believe a loop is created.
Hopefully this makes sense. You have no idea how important is for me to get this up and running, so my best wishes to those who can help :)
Just re-create the file /folder/prod.php and have php do the redirect. This is the easiest and cleanest solution.
<?php
$prodid1 = $_GET['prodid1'];
//calculate prodid2 based on prodid1, or use mysql to retreive the prodid2 belonging to prodid1
$prodid2 = $prodid1;//just for testing
$newpath = "/p/$prodid2/";
// redirect using 301
header("Location: http://{$_SERVER['HTTP_HOST']}{$newpath}");
header('HTTP/1.1 301 Moved Permanently');
?>

Apache Mod Rewrite Rule Special Condition

Im trying to redirect an old domain to its noew domain but there are some rules wheich I need to put in place and so far I havn't managed to get it quite right.
the old domain e.g www.old-domain.com has hundreds of folders names after UK towns like this:
www.old-domain.com/sheffield/
www.old-domain.com/london/
www.old-domain.com/essex/
inside each of these folders contains an index.html file and possible other directoreis and files.
I needs to redirect them to the new domain in such a way so that old domain/town maps to new domain/town but old domain/town/index.html doesnt put index.html on the new domain end however if the path after the town is anything other than index.html to redirect to it on the new domain.
Sorry that isn't the easiest to explain and not the easiest to read and undeerstand Im sure.
www.old-domain.com/sheffield => www.new-domain.com/sheffield
www.old-domain.com/sheffield/ => www.new-domain.com/sheffield/
www.old-domain.com/sheffield/index.html => www.new-domain.com/sheffield/
www.old-domain.com/sheffield/main.html => www.new-domain.com/sheffield/main.html
www.old-domain.com/sheffield/innerFolder/ => www.new-domain.com/sheffield/innerFolder
www.old-domain.com/sheffield/innerFolder/file.php => www.new-domain.com/sheffield/innerFolder/file.php
The two in bold above I managed to get working by this:
Options +FollowSymLinks
RewriteEngine on
RewriteRule ^sheffield/(.*)$ http://www.new-domain.com/sheffield/$1 [R=301,L]
However Im really struggling to get old-domain.com/sheffield/index.html to not put .index.html on the new domain.
Can anyone shed any light on this before I pull my hair out staring at mod rewrite tutorial for any more hours?
Hint: The rewrite rules are processed on first matched basis.
You can put your exception before the main rule
After roughly 4-5 hours of trying different combniations and reading god know how many rewriterule tutorials I managed to get there. Heres the htacess file for just 3 locations which all work wonderfully now.
Options +FollowSymLinks
RewriteEngine on
RewriteRule ^sheffield\/index\.html http://www.new-domain.co.uk/sheffield/ [R=301,L]
RewriteRule ^sheffield/(.*)$ http://www.new-domain.co.uk/sheffield/$1 [R=301,L]
RewriteRule ^bolton\/index\.html http://www.new-domain.co.uk/bolton/ [R=301,L]
RewriteRule ^bolton/(.*)$ http://www.new-domain.co.uk/bolton/$1 [R=301,L]
RewriteRule ^coventry\/index\.html http://www.new-domain.co.uk/coventry/ [R=301,L]
RewriteRule ^coventry/(.*)$ http://www.new-domain.co.uk/coventry/$1 [R=301,L]

Getting the original REQUEST_URI when using mod_rewrite AND mod_proxy

I'm using a custom.conf file for rewrites and codeigniter for some features of the site, mainly the articles.
My original url gets rewritten, so I have http://example.com/article-a101, this uses the custom.conf file to rewrite to codeigniter/article/read/101. I think I must send this as a proxy call using the [P] flag in mod_rewrite to make it rewrite again in codeigniters .htaccess file. Once it hits the code igniter .htaccess, it uses that mod rewrite structure to call the index file and use the article controller and the read function sending in the 101 as the parameter.
What I'm trying to figure it is how do I get the original url in the address bar as its not in the $_SERVER variable. Since I use the [P] on the first rewrite, request_uri has codeigniter/article/read/101.
custom.conf
RewriteRule ^/([_a-zA-Z0-9-]+)-a([0-9]+)$ /codeigniter/article/read/$2 [P,L]
codeigniters .htaccess, fairly basic
RewriteRule ^(.*)$ index.php?/$1 [L]
Here's my current solution that I know there must be a better method for
RewriteRule ^/([_a-zA-Z0-9-]+)-a([0-9]+)$ /codeigniter/article/read/$2?orig_url=%{REQUEST_URI}&%{QUERY_STRING} [P,L]
This stays hidden from the user, and I can access the original url through the query string, but doesn't seem like an elegant solution.
I'm pretty sure you cant do it any other way with mod_rewrite
but you could do it with codeigniter routing.
$route['^([_a-zA-Z0-9-]+)-a([0-9]+)$'] = "article/read/$2";
assuming your controller is named article and your function is named read
if you visited /article-a101
then $this->uri->uri_string(); would return article-a101 (the original url, which should be in your url bar now)
and $this->uri->ruri_string(); would return article/read/101 (where you actually are)

Resources