Using Apache mod_rewrite for conditional redirection if URL exists - apache

I'm migrating a large site (with significant changes to each page), and want a test group of users to be automatically redirected from the current site to the new site as each page is completed.
What was
www.mysite.com/admin/somefile.php
will become
admin.mysite.com/somefile.php
As each page is migrated to the new site, I want users from a specific IP address to be automatically redirected to it. This looks like a case for the '-U' (existing URL) flag of RewriteCond. The mod_rewrite statements (for www.mysite.com) would be something along the lines of
RewriteEngine On
RewriteCond %{REMOTE_ADDR} 123\.123\.123\.123 # for test users only
RewriteCond http://admin.mysite.com/$1 -U # if new page exists
RewriteRule /admin/(.*) http://admin.mysite.com/$1 [R=302,L] # then redirect
However, this doesn't seem to work - perhaps because the $1 parameter is being referenced before being defined?
Can anyone advise how this can be achieved?
Thanks, Chris

Thanks, LazyOne – you gave me confidence to pursue it (if you make it an answer I'll accept it).
I think the problem was simply in using /admin instead of ^admin; my final mod_rewrite statements are:
RewriteEngine On
RewriteCond %{REMOTE_ADDR} 123\.123\.123\.123 # for test users only
RewriteCond http://admin.mysite.com/$1 -U # if new page exists
RewriteRule ^admin/(.*) http://admin.mysite.com/$1 [R=302,L] # then redirect
...which seems to correctly serve the page from the new site if it exists, otherwise serves the page from the old site.

You could use it this way to manipulate URI
RewriteCond %{REQUEST_URI} ^/admin/(.*)$
RewriteRule .* http://admin.mysite.com/#1 [R=302,L]
Hope this works. BTW, you can test your rewrite online here http://martinmelin.se/rewrite-rule-tester/

Related

How to setup request proxy using URL rewriting

I have an e-commerce site that resides in:
http://dev.gworks.mobi/
When a customer clicks on the signin link, the browser gets redirected to another domain, in order for authentication:
http://frock.gworks.mobi:8080/openam/XUI/#login/&goto=http%3A%2F%2Fdev.gworks.mobi%3A80%2Fcustomer%2Faccount%2Flogin%2Freferer%2FaHR0cDovL2Rldi5nd29ya3MubW9iaS8%2C%2F
I'm trying to rewrite http://dev.gworks.mobi/* to http://frock.gworks.mobi:8080/openam/*, without redirection.
I've tried this in the .htaccess of the dev.gworks.mobi site:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/openam(.*)$ [NC]
RewriteRule ^(.*)$ http://frock.gworks.mobi:8080/$1 [P,L]
</IfModule>
But when I access http://dev.gworks.mobi/openam, it shows a 404 page not found page.
Can anyone help me to achieve my use case?
Try this:
RewriteEngine on
RewriteBase /
# Make sure it's not an actual file being accessed
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Match the host
RewriteCond %{HTTP_HOST} ^dev\.gworks\.mobi
# Rewrite the request if it starts with "openam"
RewriteRule ^openam(.*)$ http://frock.gworks.mobi:8080/$1 [L,QSA]
This will rewrite all the requests to dev.gworks.mobi/openam to frock.gworks.mobi:8080.
If you want to mask the URI in a way that it's not visible to the visitor that she's visiting the authentication app, you need to add a P flag. Please note that it needs Apache's mod_proxy module in place:
RewriteRule ^openam(.*)$ http://frock.gworks.mobi:8080/$1 [P,L,QSA]
Feel free to drop the L flag, if it's not the last rewrite rule. See RewriteRule Flags for more information.
The 404
If it's all in place and you're still getting a 404 error, make sure that the target URL is not throwing 404 errors in the first place.
Second, check if you're still getting the error with the correct referrer URI set. It might be designed in a way to throw a 404, if the referrer is not correctly set. If that's the case, which I suspect, you need to use the R flag and redirect instead of proxying the request.
Last thing that comes to my mind, some webapps are not built in a way to figure out the URI address. The host, as well as the port number, might be hard-coded somewhere in the config files. Make sure that the authentication app is able to be run from another URL without the need to edit the configs.
Test
You can test the rewriterule online:

RewriteRule Redirects paths not working

I moved my website to a new server with a new CMS so I had to make a lot of 301 Redirects. 'Normal' 301 redirects didn't recognize the url path of my old urls so I tried to make RewriteRules, this is what it looks like now:
Options -MultiViews
RewriteEngine On
RewriteBase /
RewriteRule ^Category http://www.example.com/category [R=301,L]
RewriteRule ^Category/Subcategory http://www.example.com/category-subcategory [R=301,L]
The first RewriteRule works, but as soon as there is a second path in the old url (the second example) the redirect will point to the main cateagy and not the subcategory. So it's basically ignoring the url paths...
Try to invert your rules, or to add a $ at the end of the first one :
RewriteRule ^Category$ http://www.example.com/category [R=301,L]
RewriteRule ^Category/Subcategory http://www.example.com/category-subcategory [R=301,L]
Explanation : Category/Subcategory is also matching the first rule, and as you have use a L flag in the first one, Apache will just use this first rule and don't bother to look further.
For general purpose solution, quoting from apache rewrite guide:
Move Homedirs to Different Webserver Description:
Many webmasters have asked for a solution to the following situation:
They wanted to redirect just all homedirs on a webserver to another webserver. They usually need such things when establishing a newer webserver which will replace the old one over time.
Solution:
The solution is trivial with mod_rewrite. On the old webserver we just
redirect all /~user/anypath URLs to http://example.com/~user/anypath.
RewriteEngine on
RewriteRule ^/~(.+) http://example.com/~$1 [R,L]
In your case URL structure has changed so ôkio's suggestion would work.

htaccess redirect for global subdomains system - all subdomains redirected to one php file to handle them all

i really could use some advices related to subdomains.
recently we decide to make every subdomain of main portal to be available for blogs (something similar to lets say any blog platform)
so what i cant achieve is to make redirection to certain folder of main portal site or php file like:
xxxxx.domain.com/index.php?get=xx&get2=xx -> to be run by actual php file located on main portal account, lets say subdomains.php?get=x&get2=xx, alternatively - to be run by mainportal/subdomains/index.php?get=x&get2=xx
i tried with
RewriteCond %{HTTP_HOST} ^(.*)\.domain\.pl$ [NC]
RewriteRule (.*) subdomain.php [L]
effect was almost correct but get parameters are missing:(
on the other hand it can be entirely wrong... i simply dont understand or that rewrite rules:(
thanks for any help/tips
You can try with QSA (query string append):
RewriteCond %{HTTP_HOST} ^.*\.domain\.pl$ [NC]
RewriteRule . subdomain.php [QSA]

Codeigniter 2 and .htaccess - how to implement "down for maintenance" mode?

I know this question might have been asked a few times already, but I need a specific solution for CodeIgniter, using an .htaccess file that would send every request to an index_failsafe.php file instead of the normal index.php but ONLY if the url doesn't start with 'admin'. Example:
www.myhost.com/admin -> work as usual
www.myhost.com/welcome -> sent to failsafe page
in case 1:
RewriteRule ^.*$ index.php/$1 [L]
in case 2:
RewriteRule ^.*$ index_failsafe.php/$1 [L]
My rewrite conditions are:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
Is it possible to do this?
Personally I do it by IP - so I can take my site offline, but I still have full access to it (to test new functions and make sure it is working before bringing back up)
RewriteEngine on
# For maintenance:
# If your IP address is 1.1.1.1 - then dont re-write
RewriteCond %{REMOTE_ADDR} !^1\.1\.1\.1
# If the person is requesting the maintenance page, also dont rewrite (prevent loops)
RewriteCond %{REQUEST_URI} !/maintenance.html$
# Otherwise rewrite all requests to the maintenance page
RewriteRule $ /maintenance.html [R=302,L]
# do not rewrite links to the documentation, assets and public files
RewriteCond $1 !^(assets)
# do not rewrite for php files in the document root, robots.txt or the maintenance page
RewriteCond $1 !^([^\..]+\.php|robots\.txt|maintenance\.html)
# but rewrite everything else
RewriteRule ^(.*)$ index.php/$1 [L]
just change !^1.1.1.1 to your current IP. i.e. !^121.65.56.65
If your not sure what your IP is - just google "what is my IP" - and it will show up as the first hit
But in terms of your specific question - this should work:
RewriteCond %{REQUEST_URI} !/admin$
RewriteRule $ /index_failsafe.php [R=302,L]
edit:
If you use cookies to store session data for users then it might be simpler to change the cookie name to force everyone to log out, then change the login page controller to load a view that says "down for maintenance" or whatever.
When you're done just change the cookie name back to what it was and everyone will still be logged in, and make sure to change back the view that the login page controller loads so users can log in normally.
To change the session cookie for CI, open up config.php and change the value for:
$config['sess_cookie_name']
You can take it a step further by creating an alternate login controller and view titled "maintenance login" or something like that, and then you can still log in for testing.
This is the method that I use when I need to take my saas down for maintenance, and it works great. Our public facing sales page is unaffected, and I don't have to mess with htaccess.

Redirecting all traffic based on Host name

An external server (I'll call it "sub.origin.edu") redirects all traffic to my webpage. I want to take all traffic from this host, and redirect it to a different site (which I'll call "http://foo.target.edu/board/").
My .htaccess file is:
RewriteEngine On
RewriteCond ${HTTP_HOST} sub\.origin\.edu [NC]
RewriteRule ^(.*)$ http://foo.target.edu/board/ [R=302]
This doesn't seem to be working. I've confirmed (using PHP) that the host is indeed sub.origin.edu, and the .htaccess file is in the right directory, but this rule just doesn't come into effect. Any suggestions? Thanks.
(If I remove the RewriteCond, the redirect happens, so I can confirm that everything but the rewrite condition is working.)
Use this:
RewriteEngine On
RewriteCond %{HTTP_HOST} sub\.origin\.edu [NC]
RewriteRule ^(.*)$ http://foo.target.edu/board$1 [R=302]
You used the wrong substition character ($ instead of %)
I found this question while trying to complete a re-derict for specific hostnames.
This link was of great help to understand how RewriteCond and RewriteRule work.
http://httpd.apache.org/docs/2.4/rewrite/intro.html
If sub.origin.edu is doing a 3xx redirect, then the browser will issue a new request to your server using your.server.edu as the host name. So this rule will never match that. If this is the case, there's no easy way to tell where the request was redirected from.
If they're using a CNAME, Femi has the correct answer.