Apache mod_rewrite - unwanted redirect instead of rewrite - apache

I have an issue with mod_rewrite and I can't seem to solve it. I stripped the example down to the bare bones and I don't understand why a specific rule forces my browser to redirect instead of rewrite:
RewriteEngine on
#if request is for a physical-file OR for one of the language paths - skip (return as-is)
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{REQUEST_URI} ^/de [OR]
RewriteCond %{REQUEST_URI} ^/en-US
RewriteRule ^ - [L]
#otherwise: rewrite to en-US folder
RewriteRule ^(.*)$ /en-US/$1 [NC,L,QSA]
I read the documentation very carefully and it seems like this should actually rewrite every call, so https://example.com/fuBar.html should actually retrieve the file /en-US/fuBar.html from my server - the users browser shouldn't know about it.
What's really happening is that for some reason the browser is redirected to https://example.com/en-US/fuBar.html. While this does display the correct content, it's just not what I want or what I thought this RewriteRule should do. What am I doing wrong?
*add - the .htaccess of the subfolders de and en-US:
RewriteEngine On
# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
# If the requested resource doesn't exist, use index.html
RewriteRule ^ /index.html

There's nothing in the code you've posted that would trigger an external "redirect".
Make sure you have cleared your browser (and any intermediary) cache(s) to ensure you are not seeing an earlier/erroneous 301 (permanent) redirect. (301 redirects are cached persistently by the browser.)
Check the "network traffic" in the browser's developer tools to see the precise nature of this redirect to see what it redirects from/to, and well as the 3xx HTTP status code of the redirect (if indeed this is an external redirect).
It would seem the front-end (JavaScript/Angular) is manipulating the URL in the address bar (there is no redirect). From comments:
Actually there was no redirect happening at all! Rather since I set <base href="/en-US"> somehow my frontend (Angular) seems to have outsmarted me, manipulating the address without me realizing it. Turns out I don't even need to change the base href, I just need the rewrites.

Related

How do I make a custom URL parser with Apache?

I heard this can be done with the web.config file. I want to make it so, for instance, my URL http://help.BHStudios.org/site might go to http://BHStudios.org/help.php?section=site, or http://i.BHStudios.org/u3Hiu might redirect to some other URL stored in a database with the hash u3Hiu as the key, or if something goes wrong and the internal file structure is exposed like http://Kyli.BHStudios.org/http/bhstudios/v2/self/index.php (something that happens with GoDaddy's servers for whatever reason) it'll change it to its intended URL http://Kyli.BHStudios.org before that's exposed tot he user.
Since I've never done this before, could you please also explain why you gave the answer you did?
A few Apache mod_rewrite rules in either your servers httpd.conf or in a .htaccess file, in your htdocs directory will do the majority of what you want e.g.
RewriteEngine On
RewriteBase /
# Default Rule - for non physical objects (not a file or directory):
# Internally rewrite (user won't see the URL) to /index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ /index.php [L]
#If the Browser request contains a .php, instruct the browser to remove it.
RewriteCond %{THE_REQUEST} \.php [NC]
RewriteRule ^/?(.*)\.php$ http://%{HTTP_HOST}/$1 [R=301,NC,L]
# Specific rule
RewriteRule ^/?site /help.php?section=site
The masking of real file system objects will not be perfect, and slightly pointless, as a user just needs to right click and view source on any served page, to obtain the actual URL's.

Apache Mod_Rewrite Seems to be Causing Javascript Reloads

I'm setting up URL rewrite rules for an application I'm developing so that I can use nice clean URLs. I want the URLs to look like http://app.com/page/agency/ and to be equivalent to http://app.com/index.php?p=page&agency=agency. The agency selector is optional, so I want the URLs to redirect, even if the agency is not present. I have created the following mod_rewrite rules for this purpose:
RewriteRule ^/?([a-z]+)/$ /index.php?p=$1 [PT]
RewriteRule ^/?([a-z]+)/([a-z]+)/$ /index.php?p=$1&agency=$2 [PT]
This is working fine for redirecting the pages. However, it seems to me that my javascript files are being re-loaded with each page, as if the browser thinks that it's in a different directory and needs to re-load the JS files. The JS files are linked using a hard-coded URL, such as http://app.com/scripts/dostuff.js.
Is it possible that the browser is reloading the javascript files each time? If so, have I done something wrong?
Try this code:
RewriteEngine On
# skip rewrite rules below it is a valid file or a valid directory
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# write single path
RewriteRule ^([a-z]+)/?$ /index.php?p=$1 [L,QSA]
# write 2 paths
RewriteRule ^([a-z]+)/([a-z]+)/?$ /index.php?p=$1&agency=$2 [L,QSA]

problems getting mod_rewrite working

I've not done much with mod_rewrite, but I can't seem to get anywhere with this. I'm wondering if perhaps it is not enabled on my server(even though my host says it is).
I have the following url: http://dev.website.com/folder1/translate/horse and I want that to redirect to: http://dev.website.com/folder1/translate.php?word=horse
My .htaccess starts with RewriteEngine on and I've tried various attempts to get it working, but no matter what, it just shows my home page (the default 404 redirect).
Things I've tried:
RewriteRule ^translate/.*$ translate.php?word=$1
RewriteRule ^translate translate.php
and some other things I don't remember, but I can't get anything to work.
The .htaccess file I am using is located in folder1. I have also tried putting random characters in the file to make it throw an error, and it does.
Anything I'm missing? How would I properly create this redirect?
As per request, this is my file structure.
I have the domain www.website.com, and a subdomain dev.website.com. The subdomain is set so that it redirects to www.website.com/dev. So, in this case, dev.website.com/folder1/translate.php = www.website.com/dev/folder1/translate.php. I am not sure how that masking is done, as it is accomplished via my web host's cpanel.
You aren't capturing $1 in brackets so this should work:
In DOCUMENT_ROOT/.htaccess:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^folder1/translate/(.*)$ /folder1/translate.php?word=$1 [L,QSA]
In DOCUMENT_ROOT/folder1/.htaccess:
RewriteEngine On
RewriteBase /folder1/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^translate/(.*)$ translate.php?word=$1 [L,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.

PHP URL Rewriting

I am setting up some rewrite rules on an Apache server using mod_rewrite. I was wondering if it was possible to write a rule that will basically re-direct the user to the home page if the page is not found i.e.
http://example.com/test <-- does not exist
However, I would like if the user was to navigate to this domain they are automatically re-directed to:
http://example.com/
With this in mind, I don't want the URL to still display "http://example.com/test" I would like the URL to update itself to become "http://example.com/".
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ http://domain.com/ [L,R=301]
Essentially, "if the requested filename is not a file or directory, redirect".
I wouldn’t use a HTTP redirection but instead send an error document together with the proper error status code.