How to make complex conditions in mod_rewrite? - mod-rewrite

I need to deny access to the whole site for everyone except some IPs.
Also, I need to permit access to one folder of site for everyone:
Options +FollowSymLinks
Options +Indexes
RewriteEngine on
# Allow access only for devs
RewriteCond %{REMOTE_ADDR} !10.10.10.10 [NC] # First dev id
RewriteCond %{REMOTE_ADDR} !11.11.11.11 [NC] # Second dev id
# Allow direct access to files
RewriteCond %{REQUEST_FILENAME} !-f
# Redirecting guests
RewriteRule (.*) /coming/soon/index.html [R=307]
# But where to place this condition?
RewriteRule ^/?preview/?$ /preview/index.html [NC]
# Other rules for main site structure
# ...
So, I need the whole site loading only for devs. Other users (guests) will see the /coming/soon/ page
And also guests are allowed to see /preview/ page of the site.
How to do this?

If your /preview/ rewrite is suitable for all users and does not depend on subsequent rewrite rules, the simplest way is to put this RewriteRule first with the [L] flag, so that subsequent rewrites will not be applied.
Otherwise, exceptions for RewriteRule may be specified as RewriteCond matching with %{REQUEST_URI}:
RewriteCond %{REQUEST_URI} !^/?preview/?$ [NC]
Also note that your suggested rule would rewrite both /preview and /preview/ into /preview/index.html, and the first of these rewrites may break relative links unless a redirect is performed.

Related

Mod-Rewrite - Need two different redirection rules

I would like to have two different redirects; one redirection if a user accesses an index.php-file on my apache-server and one redirection after a user enters a particular url.
So my index.php file lies in "/client/frontend/questionnaire"-folder on my apache. If a user enters "www.test-domain.com" he or she should be redirected to the index.php - file on the server.
The second redirection should be processed if a user enters "www.test-domain.com/news". Then he or she should be redirected to "www.test-domain.com/client/frontend/app/index.php/article-one".
I managed to create the first rewrite rule like this:
Options -Indexes
RewriteEngine On
RewriteBase /
RewriteRule ^$ client/frontend/questionnaire/index.php [L]
But I do not know how to create the second rule.
Any help is very appreciated.
Thanks!
You have to use multiple RewriteCond+RewriteRule. See the mod_rewrite introduction and then the reference documentation (all is explain).
Just the RewriteRule actually rewrite the current request. To execute it, all RewriteCond before must be true.
Samples from the documentation:
RewriteCond %{REMOTE_ADDR} ^10\.2\.
RewriteRule (.*) http://intranet.example.com$1
RewriteCond %{REMOTE_HOST} ^host1 [OR]
RewriteCond %{REMOTE_HOST} ^host2 [OR]
RewriteCond %{REMOTE_HOST} ^host3
RewriteRule ...some special stuff for any of these hosts...
RewriteCond %{HTTP_USER_AGENT} (iPhone|Blackberry|Android)
RewriteRule ^/$ /homepage.mobile.html [L]

301 URL Forwarding with HTACCESS or PHP

Just curious if anyone can help me on this HTACCESS issue.
I have these OLD URLS that need to get forwarded properly.
Previous structure
domain.com/Canada/Accounting
domain.com/Canada/Trades
domain.com/Canada/Sales
Proper structure
CATEGORY - /jobs/accounting-jobs
LOCATION - /jobs/jobs-kelowna
TOGETHER - /jobs/accounting-jobs-kelowna
Domain Structure
domain.com/jobs/[category]-jobs-[location]
Is this possible, either by HTACCES or PHP...just don't want these 404'ed pages.
I have 86+ to do, if there is a good way to forward these.
This is what I have, but i'm unable to successfully forward the bad-urls properly.
OLD
/browse
/Toronto/
/Canada/Administrative
/Vancouver/
/Canada/Trades
/Calgary/
/Canada/Hospitality
This is my HTACCESS right now.
Options +FollowSymlinks
RewriteEngine on
RewriteBase /
#
# Trailing slash check
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
RewriteRule ^(.*)$ $1/ [L,R=301]
#
# PAGES
RewriteRule ^add-job/?$ /add-job.php [L]
RewriteRule ^jobs/?$ /results.php [L]
RewriteRule ^sitemap/?$ /sitemap.php [L]
#
# SEARCH
# CATEGORY - accounting-jobs
# LOCATION - jobs-kelowna
# TOGETHER - accounting-jobs-kelowna
RewriteRule ^jobs/([a-zA-Z0-9_-]+)/([0-9]+)?$ results.php?whatwhere=$1&page=$2
RewriteRule ^jobs/([a-zA-Z0-9_-]+)/([0-9]+)/?$ results.php?whatwhere=$1&page=$2
To 301 redirect your pages you can do something like:
RewriteEngine On
RewriteBase /
RewriteRule ^(\w+)/(\w+)$ /jobs/$2-jobs-$1 [R=301,L]
This only addresses the urls from your previous structure (the combinations, you have not shown any previous urls with just location or category) but note that Canada will stay Canada, it does not become canada. You can change everything to lower case using rewrite as well.
You also have to take care that you don't rewrite any of the current urls but without more information, this should do it.
Edit: For the location-only urls you could use a rule like:
RewriteRule ^(\w+)/$ /jobs/jobs-$1 [R=301,L]
Again, you need to look out that your rewrite rule does not interfere with your current urls. If that is the case, you would need to redirect every old url manually.
For lower-case new urls, you should search SO, there are some questions with good answers about converting a mized-case variable to lower-case.
If you have mod_rewrite, you can add these lines to your .htaccess file:
RewriteEngine on
RewriteRule ^Canada/Accounting$ /jobs/accounting-jobs [R,L]
However, it's not clear from your question exactly what you want mapped. Are the 3 previous URLs supposed to redirect to the 3 new ones? They don't seem to be equivalent.

localhost directs to www.domains.tld after adding .htaccess in codeigniter folder

I just started using Codeigniter to develop a simple static website using a local server (MAMP). Initially my local address to access my homepage was http://localhost/index.php/home. Even a simple localhost would redirect to my homepage. I wanted to remove the 'index.php' from the URL and hence I copy pasted the .htaccess code which I found online. The code looked like the following:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
### Canonicalize codeigniter URLs
# If your default controller is something other than
# "welcome" you should probably change this
RewriteRule ^(welcome(/index)?|index(\.php)?)/?$ / [L,R=301]
RewriteRule ^(.*)/index/?$ $1 [L,R=301]
# Removes trailing slashes (prevents SEO duplicate content issues)
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ $1 [L,R=301]
# Enforce www
# If you have subdomains, you can add them to
# the list using the "|" (OR) regex operator
#RewriteCond %{HTTP_HOST} !^(www|subdomain) [NC]
#RewriteRule ^(.*)$ http://www.domain.tld/$1 [L,R=301]
# Enforce NO www
RewriteCond %{HTTP_HOST} ^www [NC]
RewriteRule ^(.*)$ http://localhost/$1 [L,R=301]
###
# Removes access to the system folder by users.
# Additionally this will allow you to create a System.php controller,
# previously this would not have been possible.
# 'system' can be replaced if you have renamed your system folder.
RewriteCond %{REQUEST_URI} ^system.*
RewriteRule ^(.*)$ /index.php/$1 [L]
# Checks to see if the user is attempting to access a valid file,
# such as an image or css document, if this isn't true it sends the
# request to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
</IfModule>
<IfModule !mod_rewrite.c>
# Without mod_rewrite, route 404's to the front controller
ErrorDocument 404 /index.php
</IfModule>
Initially I copy-pasted the code without changing it at all (which was foolish on my part) So the 'localhost' in the code above was initially 'www.domains.tld'. When I then ran localhost on my browser, it directed to www.domains.tld'. I noticed the blunder and changed it to what it is above and localhost still directs to 'www.domains.tld' I deleted the .htaccess file to reverse the effect but it still does the same thing.
I also changed my root folder for localhost but whatever I do localhost points to 'domains.tld'. When I type 127.0.0.1 on the address bar of my browser, it directs correctly to my website. I have spent hours reading up on the reason for this behavior but am unsuccessful to find a solution.
Any help will be greatly appreciated.
Thanks,
H.
Clear your DNS cache and restart your browser. Certain browsers cache redirects with DNS so that you end up at what it thinks is the correct site more quickly.
Firefox is particularly annoying with this, so I disable its internal DNS caching every time I install. In about:config, create the following two integer type settings (NOTE: you MUST create these, they do not exist by default):
network.dnsCacheEntries set to 0
network.dnsCacheExpiration set to 0
In Chrome, you would need to turn off DNS prefetching under your Privacy settings.
The reason they do this is to make the internet "seem" faster to casual browsers. For developers, it can be quite a hindrance.

Using mod_rewrite to redirect old urls with Codeigniter

I'm redeveloping a website using the codeigniter framework.
When we go live, we want to ensure a few of the old URLs will be redirected to the appropriate pages on the new site.
So I put what I thought would be the correct rules into the existing htaccess file, above the other rules that CodeIgniter applies.
However, they are not taking affect. Can anyone suggest what I'm missing here?
# pickup links pointing to the old site structure
RewriteRule ^(faq|contact)\.php$ /info/ [R=301]
RewriteRule ^registration\.php$ /register/ [R=301]
RewriteRule ^update_details\.php$ /change/ [R=301]
# Removes access to the system folder by users.
RewriteCond %{REQUEST_URI} ^_system.*
RewriteRule ^(.*)$ /index.php?/$1 [L]
# This snippet prevents user access to the application folder
# Rename 'application' to your applications folder name.
RewriteCond %{REQUEST_URI} ^myapp.*
RewriteRule ^(.*)$ /index.php?/$1 [L]
# This snippet re-routes everything through index.php, unless
# it's being sent to resources
RewriteCond $1 !^(index\.php|resources)
RewriteRule ^(.*)$ index.php/$1
Try adding a [L]ast flag to your R=301 flag => [L,R=301] that makes sure no other rules are applied, and, just to be sure, try to redirect to a complete URL and, to be even more sure you haven't deleted anything, add RewriteEngine On to the top and set the RewriteBase.
Make your first rows look like
RewriteEngine On
RewriteBase /
RewriteRule ^(faq|contact)\.php$ http://www.YOURDOMAIN.XYZ/info/ [L,R=301]
and check if the URL in your browser changes when you call for instance the faq page.

Rewrite Rule(s) for domain aliases

Situation: I have a single (main) domain, which has several aliased domains, each of which are pointing at the same Plesk-based server (for instance, I have example.com as main, with something.net, anotherone.co.uk, and several others all as aliases of the main domain account). This means that whenever I enter the domain name into my address bar of any of the aliases, it goes directly to the account of the main domain (example.com).
Problem: Based on the domain name of the alias(es), I have an index.php that redirects each domain differently (for instance, requests to domain A redirects to a corporate site, domain b goes to a thanks site etc.) Which works great, but if a directory is added after the domain URL (i.e. somealias.com/something) then it gives a 404 not found error.
What I would really appreciate, if someone can help me out, is a (single if possible) rewrite ruleset that would essentially strip off ALL trailing directories and/or GET requests, and only leave the typed-in base URL, so then the php script sitting in the main domain document root can take over and deal with the request appropriately.
Strangely enough, I've not been able to find a (simple) solution for this anywhere. Is it a case of having to define a rule for each of the aliased domains individually?
Try the following,
#Options +FollowSymLinks
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www.olddomain.com$[OR]
RewriteCond %{HTTP_HOST} ^olddomain.com$
RewriteRule ^(.*)$ http://www.newdomain.com/$1 [R=301,L]
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !=/
RewriteCond %{REQUEST_URI} !=/index.php
RewriteRule .* http://%{HTTP_HOST}/? [L]
This will take ALL requests except root folder / (e.g. http://example.com/) or index file (e.g. http://example.com/index.php) and redirect them to the root folder (e.g. http://example.com/some-url will be redirected to http://example.com/).
You may need to replace index.php by the file that is get executed when you hit the root folder (Apache will silently rewrite http://example.com/ to http://example.com/index.php (depending on your actual settings) as it needs to have a file to execute otherwise it may show an error).
Alternatively (possibly even better -- depends on your actual setup and requirements) you may use these rules -- this will redirect only non-existing URLs. So if you have an image meow.png on your site, these rules will allow you to access it (http://example.com/meow.png):
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* http://%{HTTP_HOST}/? [L]
UPDATE:
If you going to place this into config file (httpd-vhost.conf or httpd.conf) then use these rules:
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
RewriteCond %{REQUEST_URI} !=/index.php
RewriteRule .* http://%{HTTP_HOST}/? [L]
It seems to me that all the sites are hosted on the same server (probably using the same code base).
If your index.php is a front controller you can redirect everything to your index.php and decide in the first lines of index.php what front controller to load (like backend.php).
If you don't mind having to maintain a list of the aliases you can define a hash of [alias] => path-to-front-controller.
In the front controller of you main domain you check the alias name (using $_SERVER['SERVER_NAME'] for example) against the hash and load the appropriate file.
You will have to add and entry to the hash each time you add anew alias. If they are not generated dynamically maintaining this hash is not a lot of hassle.

Resources