Can someone explain this rewrite in plain english - .htaccess

I have a domain and have been hosting several subdomains as well. The environment was setup pretty barebones by the provider and I have full access to make whatever changes I deem fit. I need to understand what this rewrite thing is doing so that I can learn and fix the issue of everything being sent to /homepage regardless of address people type in the bar.
RewiteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}/homepage
Ideally results would be that a user types http://domain.tld and get https://domain.tld or they type https://domain.tld and get what they typed. or type http://sub.domain.tld and get https://sub.domain.tld.
also ideally only domain.tld and https://domain.tld should be sent to https://domain.tld/homepage

RewriteEngine On
#This will enable the Rewrite capabilities
RewriteCond %{HTTPS} off
#This checks to make sure the connection is not already HTTPS
RewriteRule (.*) https://%{HTTP_HOST}/homepage
#This will send all requests to specified address, in this case homepage
The RewriteCond defines the condition under which the rewriting will takes place. In other words the execution of the RewriteRule
Check this link for more information

Related

Make a redirect of url with ?id=(VAR)

I try all posible, i need redirect this url's type:
http://www.midominio.com/esp/productos_listado.php?id=98
with id [1-4504] To
http://www.midominio.com/categorias/98-libro.html
I prove:
RewriteCond %{QUERY_STRING} (^|&)id=([0-9]+)
RewriteRule ^id=(.*)$ /categoria/%1$1-libro.html? [R=301]
But only rewrite:
http://www.midominio.com/categorias/-libro.html
Without var nu,be
It is unclear from your description in what direction you actually want the rewriting to be applied.
If the incoming request to be rewritten is /categorias/..., then something like this should be just fine:
RewriteEngine on
RewriteRule ^/?categorias/(\d+)-libro.html /esp/productos_listado.php?id=$1 [L]
If however, as your phrasing suggests, you have the unusual situation that you want to rewrite incoming requests to /esp/productos_listado.php, then try it this way 'round:
RewriteEngine on
RewriteCond %{QUERY_STRING} id=(\d+)
RewriteRule ^/?esp/productos_listado\.php /categorias/%1-libro.html [L]
That notation would be working for .htaccess style files and also in the real host configuration. Note that if you have access to the host configuration, then you always should prefer placing the rules in there. .htaccess style files are notoriously error prone, hard to debug and they really slow the http server down. They are only offered for situations where people do not have access to the host configuration. So for example when using really cheap hosting service providers...

Don't initiate old-to-new-domain RewriteRule if a certain variable is specified in query string

I've searched SO and Google long and hard for this one and I'm really surprised not to have found an answer (or stumbled upon the solution by trial and error!). It's a slightly tough search as most of the keywords lead to people wanting to exclude query strings as part of their redirect, whereas I want to exclude certain query strings from the subsequent redirect entirely.
We have migrated a content site from olddomain.com (running Drupal) to newdomain.com (running Wordpress). All the paths stay the same and so we want to redirect like-for-like from one domain to the other. However, we still want to be able to access Drupal's admin panel (and other associated admin URLs) for a variety of reasons. These exceptions must be done by exclusion so that, when we are not redirecting to the new domain, Drupal's existing generic mod_rewrite rules still activate in order to serve the redirect- excluded URLs correctly.
The main "like for like" redirect rule looked like this, and works well:
RewriteCond %{REQUEST_URI} !^/?(admin/|index.php|install.php|authorize.php|cron.php|update.php|xmlrpc.php|batch)
RewriteRule ^(.*) https://newdomain.com/$1 [R=301,L]
However, some admin-only paths (typically for editing a piece of content) don't always use "admin" in the path, e.g.:
/node/4823/edit
So what I want to do is to be able to manually add a noredirect query string variable which is then used as a further negated RewriteCond of my existing RewriteRule so in essence I am saying "do a like-for-like redirect on all paths as long as they are not in any of these folders and noredirect doesn't appear in the query string".
This is as far as I've got, you can see some of the steps I've taken, all of which have failed so far:
RewriteCond %{REQUEST_URI} !^/?(admin/|index.php|install.php|authorize.php|cron.php|update.php|xmlrpc.php|batch)
#RewriteCond %{QUERY_STRING} !^noredirect=([^&]+)
#RewriteCond %{QUERY_STRING} !^/noredirect/
#RewriteCond %{QUERY_STRING} !^.*(\bnoredirect\b)
#RewriteCond %{QUERY_STRING} !^.*(noredirect)
RewriteCond %{QUERY_STRING} !(noredirect)
RewriteRule ^(.*) https://newdomain.com/$1 [R=301,L]
As I've gone on I've tried to make it more and more generic in order to try and simplify the task; all I care about is checking for "noredirect" anywhere in the query string, so I'd be happy with all of these query strings matching the exclusion and thus preventing the redirect:
?noredirect
?noredirect=
?foo=bar&noredirect=whatever
?thisbitsaysnoredirectinit&foo=bar
As always, I look forward to basking in your expertise...
After much fiddling, and reordering and testing the rules separately (stupid I didn't do this before, this clearly showed the query string rule in itself was fine), this was the solution:
RewriteCond %{REQUEST_URI} !(^|/)(admin/|index.php|install.php|authorize.php|cron.php|update.php|xmlrpc.php|batch|node)
RewriteCond %{QUERY_STRING} !(noredirect)
RewriteRule ^(.*) https://newdomain.com/$1 [R=301,L]
So it required the change from ^/? to (^|/) in the "exclude these folders" rule.
I'll happily admit I don't understand why this has fixed it. Unfixed, this condition itself was working fine, it was just preventing the next condition from being looked at. If there was a problem with the syntax it seems to me that the condition should have been broken entirely rather than messing with other conditions. If anyone can shed any light on that for me, thank you!
For what it's worth, RewriteBase is unspecified (so I assume defaults to root).
Drupal-specific bonus
Also note the addition of "node" to the list of folders I'm excluding from the 1:1 redirect to the new domain.
When I thought about this more I realised that this would mean the admin-only extensions of "node" (e.g. /node/123/edit) would be safe as they are not rewritten to an alias. The public views of nodes (e.g. /node/123) would be initially ignored but then subsequently rewritten to their aliases by Drupal's own functionality, at which point .htaccess is called a second time and the redirect to the new domain (as the alias does not begin with "node") is activated.
This is not only a better system (anyone trying to go to an original Drupal node URL rather than an alias will not get redirected too soon) but of course means I now only have to use the ?noredirect query string in much rarer use cases.

htaccess redirect of different add-on domains to folders which are associated to each domain

We tried various htaccess rewrite rules but could not get to work what we need to do. Maybe some advise here?
Assume we have a main domain (a.com) with 2 add-on domains (b.com and c.com), all pointing to the website root.
Then we have folders, all in root, like /folder_a1, /folder_a2, /folder_a3,/folder_b1,/folder_b2,/folder_b3 and /folder_c1, /folder_c2,/folder_c3 in which there are php files.
Users shall be able to come to the site via:
URL=a.com/folder_1/xxx.php and be redirected to root/folder_a1
URL=b.com/folder_1/xxx.php and be redirected to root/folder_b1
URL=c.com/folder_1/xxx.php and be redirected to root/folder_c1
Each time we want to keep in the browser address bar the URL the user came from (if he came via a.com we want to keep showing a.com... etc.)
In this example we basically have to map the url string .../folder_1, dependent on the URL used, either to folder_a1, folder_b1 or folder_c1.
We tried (amongst others):
RewriteCond %{HTTP_HOST} ^www\.a\.com [NC]
RewriteRule ^folder1(/.*|)$ /folder_a1$1 [L,NC]
RewriteCond %{HTTP_HOST} ^www\.b\.com [NC]
RewriteRule ^folder1(/.*|)$ /folder_b1$1 [L,NC]
RewriteCond %{HTTP_HOST} ^www\.c\.com [NC]
RewriteRule ^folder1(/.*|)$ /folder_c1$1 [L,NC]
But that does not do the trick. With these rules we always and up at folder_a1.
Any suggestions how we can do this?
We found the solution (thanks to the support of our host rochenhost !).
As there was no answer here (yet ;), here is what we found:
The only issue was that we did not repeat the re-write condition before every re-write-rule, which meant that the condition was only applied once, to the first rule, and to none of the following rules.
Once added, all works.
Cheers

Redirect Desktop Internal Pages to Correct Mobile Internal Pages with Htaccess

I have built a Mobile site in a sub-domain.
I have successfully implemented the redirect 302 from:
www.domain.com to m.domain.com in htaccess.
What I'm looking to achieve now it to redirect users from:
www.domain.com/internal-page/ > 302 > m.domain.com/internal-page.html
Notice that URL name for desktop and mobile is not the same.
The code I'm using looks like this:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
# Mobile Redirect
# Verify Desktop Version Parameter
RewriteCond %{QUERY_STRING} (^|&)ViewFullSite=true(&|$)
# Set cookie and expiration
RewriteRule ^ - [CO=mredir:0:www.domain.com:60]
# Prevent looping
RewriteCond %{HTTP_HOST} !^m.domain.com$
# Define Mobile agents
RewriteCond %{HTTP_ACCEPT} "text\/vnd\.wap\.wml|application\/vnd\.wap\.xhtml\+xml" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "sony|symbian|nokia|samsung|mobile|windows ce|epoc|opera" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "mini|nitro|j2me|midp-|cldc-|netfront|mot|up\.browser|up\.link|audiovox"[NC,OR]
RewriteCond %{HTTP_USER_AGENT} "blackberry|ericsson,|panasonic|philips|sanyo|sharp|sie-"[NC,OR]
RewriteCond %{HTTP_USER_AGENT} "portalmmm|blazer|avantgo|danger|palm|series60|palmsource|pocketpc"[NC,OR]
RewriteCond %{HTTP_USER_AGENT} "smartphone|rover|ipaq|au-mic,|alcatel|ericy|vodafone\/|wap1\.|wap2\.|iPhone|android"[NC]
# Verify if not already in Mobile site
RewriteCond %{HTTP_HOST} !^m\.
# We need to read and write at the same time to set cookie
RewriteCond %{QUERY_STRING} !(^|&)ViewFullSite=true(&|$)
# Verify that we previously haven't set the cookie
RewriteCond %{HTTP_COOKIE} !^.*mredir=0.*$ [NC]
# Now redirect the users to the Mobile Homepage
RewriteRule ^$ http://m.domain.com [R]
RewriteRule $/internal-page/ http://m.domain.com/internal-page.html [R,L]
At the end, you have two RewriteRule lines which I believe should be changed to:
RewriteRule ^\/?$ http://m.domain.com [R=302]
RewriteRule ^\/?(.*)\/?$ http://m.domain.com/$1.html [R=302,L]
The ^\/?(.*)\/?$ means give me a string that starts at the beginning (^) and gives me all characters ((.*)) until the end ($) without the trailing/beginning (/) if there is one (?).
The http://m.domain.com/$1.html means that if the address is http://www.domain.com/internal-page/ then it becomes http://m.domain.com/internal-page.html.
The [R=302,L] should mean a 302 redirect (R=302) and the last rewrite (L), so no other rewrites can occur on our URL.
EDIT:
I believe that in the case of your RewriteRules the first one was redirecting to http://m.domain.com in the event that the URL was just the domain, but if there was anything else then the second rewrite was failing because it was not actually literally /internal-page/ and you needed a regex variable to put into the new URL.
EDIT (2):
To redirect to each mobile page from a specific desktop page:
RewriteRule ^\/foo\/?$ http://m.domain.com/bar.html [R=302]
RewriteRule ^\/hello\/?$ http://m.domain.com/world.html [R=302]
The (/?) means that a / is optional in that position and the (^) denotes beginning and ($) denotes ending in this case (the ^ can also be used to indicated something like [^\.] which means anything except a period).
Just put how ever many of those that you need in a row to do the redirecting and that should do the trick. To make sure there are no misconceptions, the first line would mean that http://www.domain.com/foo/ would become http://m.domain.com/bar.html and because the trailing slash is made optional http://www.domain.com/foo (notice the trailing forward slash is absent) would also redirect to http://m.domain.com/bar.html.
You can play with the syntax a bit to customize it, but hopefully I've pointed you in the right direction. If you need anything else, let me know, I'll do my best to assist.
I don't want to sound like a broken record or anything, but I feel that I could not, in good conscience, end this edit without pointing out that modifying the mobile site would be a much better way to do this. If it is not possible or you feel that a few static redirects are not a big deal versus modifying some pages, then I totally understand, but here are a few things for you to think about:
If the mobile site and desktop site are in separate folders then the exact same name scheme can be used for both making the Rewrites simpler and meaning that as new pages/content are added you will not need more Rewrite statements (making more rewrites means you have to create the new pages and then you have to create the redirects. that's extra work and more files which require your attention.)
If the mobile site is actually hosted from the same directory as the desktop site, then changing the files for one or the other so it becomes something like /desktop-foo/ or /d-foo/ then it is very easy to make the rewrite (redirect) go to something like /m-foo.html. You could forego modifying the desktop pages and make /foo/ become /m-foo.html and make all your mobile versions begin with an 'm'.
The third option that comes to mind is the most difficult and time consuming, depending on the content of the site, but it is a pretty cool one and ultimately would make the site the easiest to work on (after the initial work, of course). It is quite possible to use the same page for desktop, mobile, tablet, etc without the use of mod_rewrite or separate pages. Things like media queries in your CSS would allow you to change the look of the page depending on what the client is viewing it from. I came across a tutorial on the subject earlier which used media queries and the max-width of the screen to determine how the page should look. This would require a good bit of work now, but could save some hassle down the road as well as being an interesting learning experience if you are up to the challenge.
Again, sorry that this veered off topic at the end there, but I got the impression from your original question and your responses that you might find the alternatives interesting if you haven't already considered and dismissed them and that even if the alternatives do not interest you that you aren't going to be like some people and respond with, "Hey, $*%& you, buddy! I asked for Rewrites not all that other garbage!" I hope you take it as nothing more than what it is intended to be...helpful.

How to use a rewrite rule to force calls for "domain.tld/subdir/file.html" to show as "subdir.domain.tld/file.html"?

First time poster. Very new to mod_rewrite. I'm on a shared server and the context of this problem is with a virtual directory under my root account.
The domain (domain.tld) will have subdirectories representing annual mini-sites of static .html files. Subdirectory names (yyyy) will be the 4-digit year (e.g., "2010").
I want any call to domain.tld/yyyy/file.html to appear as yyyy.domain.tld/file.html in the browser address bar, and (of course) for the page to load properly.
I already force dropping “www” by using…
RewriteCond %{HTTP_HOST} ^www\.domain\.tld [NC]
RewriteRule (.*) http://domain.tld/$1 [R=301,L]
So far so good.
But no matter what I try after that, I can’t get the subdomain to force to the front of the domain.
Here’s one of the more complicated examples I’ve tried (no doubt wrong)…
RewriteCond %{HTTP_HOST} ^domain\.tld/([0-9]+)/([a-z-]+)\.html [NC]
RewriteRule (.*) %1.domain.tld/%2.html [NC]
This doesn’t break anything (that I can tell), but it doesn’t do what I want either. I.e., if I type yyyy.domain.tld, I’ll see yyyy.domain.tld in the address bar, and navigating around will give me yyyy.domain.tld/file.html, etc. Fine. But if also type domain.tld/yyyy I’ll see domain.tld/yyyy, etc, which is not how I want people to see it. It doesn’t redirect or mask or alias or whatever you call it.
Is it even possible to force one look over the other like that? Should I be handling this with DNS instead?
Thanks in advance!
HTTP_HOST does only contain the HTTP Host value. So try this:
RewriteCond %{HTTP_HOST} ^domain\.tld$
RewriteRule ^([0-9]+)/([a-z-]+)\.html$ http://$1.domain.tld/$2.html [NC,L,R=301]

Resources