Mod_rewrite failing to silently redirect - php

2 days of struggling and about a pound less of hair, I figure it's about time I ask for some help. I've recently migrated my project to a main sub-directory so that the structure is as follows:
-application/
-index.php
-signup/
-index.php
-signup_set.php
-css/
-js/
I've been trying to get mod_rewrite to do my work for me to exclude "application/" from all the urls. Here is where I got in my root .htaccess:
RewriteEngine On
#first round through, prepend 'application/' to request
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !^application
RewriteRule ^(.*)$ application/$1 [L]
#second round through, if the new url is not directory or file, append .php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ $1.php [L]
I may have a terrible understanding of regex/mod_rewrite, but this actually seems to partly work. Partly. The weird part about this is that when I route to a "pretty url" (e.g. www/signup) the url in the top bar is physically rewritten to include the "application/" (e.g. www/application/signup). So somehow this "silent" rewriting process is getting pretty loud...Any suggestions? I realize I could change my root directory but that would require rewriting of code referencing css/js files. I'm more curious than anything, just trying my hand at some htaccess. Any help would be appreciated! Thanks StackOverflow, you rock.
P.S. I'm running Apache on Windows 7 and using a virtual host (in case any of that is relevant)

The rules below work for me running Apache on Windows 7 using a virtual host. All I changed was the second RewriteCond.
RewriteEngine On
# Append trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(?:\.\w+|/)$
RewriteRule ^(.*)$ /$1/ [L]
# First round through, prepend 'application/' to request
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^/application
RewriteRule ^(.*)$ application/$1 [L]
# Second round through, if the new url is not directory or file, append .php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !\.\w+$
RewriteRule ^(.*)/$ $1.php [L]

Related

HTAccess Rewrite Issues

I am writing a website which is dynamically populated through an Oracle database.
I have completed the desktop site and am now required to create a mobile site. Due to how different the sites are planned to look, I have opted to create 2 different "template" like websites for the mobile and desktop sites.
However, for my desktop site, everything is built off the index.php file in order to allow it to be completely dynamic. Pages are therefore look like www.domain.com/index.php/page in the url.
For the desktop site, this works. I am using a generic index.php removal rewrite rule in order to then make the url www.domain.com/page however still display the same page as the previous URL.
My issue, is that now I have a www.domain.com/mobile/index.php. Which has been created and for the most part has been working, however when trying to add addition dynamic pages to the mobile site. www.domain.com/mobile/index.php/about for example just redirects to www.domain.com/mobile/ and it doesn't even include the about part of the URL.
After much debugging, I have discovered it is definitely the .htaccess that is causing the issue.
If you have any insight into my issue, please help me out.
Thanks in advance
EDIT 1
Rewrite Rules are as follows
# Removes index.php from ExpressionEngine URLs
RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
RewriteCond %{REQUEST_URI} !/system/.* [NC]
RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,NE,L]
# Directs all EE web requests through the site index file
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
You can use this code in your /mobile/.htaccess file:
DirectoryIndex index.php
RewriteEngine On
RewriteBase /mobile/
RewriteCond %{THE_REQUEST} /index\.php [NC]
RewriteRule ^index\.php(?:/(.*))?$ $1 [L,R=302,NC,NE]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ index.php/$1 [L]
This will override all the rules present in parent .htaccess for /mobile/ URI path.
Simplified version to make it work in root .htaccess:
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^(mobile)/(.*)$ $1/index.php/$2 [L,NC]
# Directs all EE web requests through the site index file
RewriteRule ^(.*)$ /index.php/$1 [L]
Based on the debugging you mentioned, there is a rule in your .htaccess which is rewriting www.domain.com/mobile/index.php/about to www.domain.com/mobile/. So, if you find which rule this is, you can add one above it that will catch requested URLs for your mobile pages and then not allow the problematic following rule to run. Something like this:
RewriteRule ^mobile/index.php/([a-zA-Z0-9-_]+)$ ^mobile/index.php/$1 [L,QSA]
The L ensures that if the user's request matches this rule, no further rules (including the one causing the issue) will be executed.
Thank you for the answers you've both given, however neither of them worked, I've now solved the issue, it was to do with the final RewriteRule at the end
# Directs all EE web requests through the site index file
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
I needed to change it to
# Directs all EE web requests through the site index file
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !/mobile/.* [NC]
RewriteRule ^(.*)$ /index.php/$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /mobile/.* [NC]
RewriteRule ^(.*)$ mobile/index.php/$1 [L]
So that it would work with both mobile and desktop sites.

Keep URL the same, load index.php

My question might be dumb, but I googled it and didn't find an answer...
Let's say I want to access my website in this given url: www.mywebsite.com/something/something_else/?some_query_string=true
(I put the query string because it is going to be there, and I don't know if it makes any difference in the htaccess file)
I want it to keep the URL the same, but load the index file for no matter what URL, which is not in the root of the server.
My server has an "application" folder, where all the code is.
How can I do this?
Thanks!
use htaccess to re-write all request to index.php (except for when a file/dir/link is requested and it exists):
<IfModule mod_rewrite.c>
Options +FollowSymLinks
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule .* index.php [L]
</IfModule>
If you want to use Rewrite to have your requests handled by a file outside the DocumentRoot, then you can combine with an Alias directive.
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule .* application/index.php [PT]
Alias application /path/to/application
Note the [PT] on the RewriteRule which means 'pass through' - it ensures the rewritten url is passed through to other apache modules which might be interesting in processing it.
This turned out to answer my own question:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ application/index.php?url=$1 [QSA,L]
If the URL doesn't exist, it loads the index.php file inside of the folder "application", and it keeps the URL the same, which was exactly what I needed...
Thanks for the answers!

mod_rewrite overriding second RewriteRule

I'm running in to a mod_rewrite issue where the second rule in my .htaccess file is overriding the first. The .htaccess file in question looks like the one below:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /path/appname
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule /api/v1/(.*)$ api/v1/index.php?rquest=$1 [QSA,NC,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php
</IfModule>
The issue that I'm seeing is this:
If I go directly to http://example.com/path/appname/api/v1/valid/endpoint the first RewriteRule triggers correctly and I get the result back from the API.
However, say I visit http://example.com/path/appname/app - a page which has been rewritten according to the second RewriteRule. This page makes AJAX requests to the api/v1 page. Those requests are instead directed through the second RewriteRule and send to my base index.php page.
I'm confused on how this could be, as my understanding is that the [L] flag prevents any further rules from being run once it matches and thus once any request that has 'api/v1' in it should catch that and stop checking for any further matches. What do I need to change in order for this to work correctly?
Thanks!
You should exclude the segment path for the previous rule-set, so it is not processed again. Like this:
# Don't redirect/map when folders or files exist
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Exclude the previous path
RewriteCond %{REQUEST_URI} !api/v1/? [NC]
# Prevent loops
RewriteCond %{REQUEST_URI} !index\.php [NC]
RewriteRule . index.php [L]
</IfModule>
Replace the last 4 lines in you question with the above lines.

Removing file extension apache server

today i wanted to achieve this thing where .htaccess automatically removes any sort of file extension from the url on the browser.
Lets say for example user clicks a link to take the user to
mylink.php
It should take him there but remove the .php
i tried using a few .htaccess code but they did not do much.
Also i can access the pages like so
localhost/register << this one works fine but i want the extension to be removed auto
localhost/register/ << this one looses all styling because it behaves like a page in new folder
The .htaccess code is
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^([^/]+)/$ $1.html
# Forces a trailing slash to be added
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
RewriteRule (.*)$ /$1/ [R=301,L]
Any ideas people?
RewriteEngine On
# Change this to the appropriate base (probably just / in your case)
RewriteBase /stackoverflow/9762238/
# Any url that requests a .php file on the base will be redirected to dir with same base name
# The condition is important to prevent redirect loops!
RewriteCond %{ENV:REDIRECT_STATUS} !=200
RewriteRule ^(.*)\.php$ $1/ [R=301,L]
# Requests for directories that do not actually exist will be be translated into php file requests
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.+)/$ $1 [L]

mod_rewrite not working as it should

I'm trying to rewrite URLs as follows:
www.example.com/module-name(/) => handler.php?module=module-name
www.example.com/module-name/list/of/arguments(/) => handler.php?module=module-name&args=list/of/arguments (which I explode later in the script)
If module-name is missing or not allowed, it loads the home page of the website. No problems here.The problem is that mod_rewrite isn't working as it should. I wrote these rewrite rules...
RewriteEngine On
RewriteRule ^([^/]*)/?$ handler.php?module=$1
RewriteRule ^([^/]+)/(.+)/?$ handler.php?module=$1&args=$2
...but instead of passing module-name as module to the handler, the rewrite engine passes the name of the script itself, handler.php. I tried with different regex in the last two days, but the result is always the same. I don't know what to do anymore!
The rewrite rules are inside an .htaccess, placed in the document root (together with handler.php), and I'm running xampp on an Ubuntu 11.10 64-bit machine.
Thanks in advance!
Yep, after rewrite occurs, it goes to next cycle instead of existing immediately as you would expect.
You need to alter your rule (or add separate condition) to ignore requests to handler.php file. For example:
RewriteRule ^(?!handler\.php)([^/]*)/?$ handler.php?module=$1 [L]
RewriteRule ^(?!handler\.php)([^/]+)/(.+)/?$ handler.php?module=$1&args=$2 [L]
or with extra separate condition:
RewriteCond %{REQUEST_URI} !/handler\.php$
RewriteRule ^([^/]*)/?$ handler.php?module=$1 [L]
RewriteCond %{REQUEST_URI} !/handler\.php$
RewriteRule ^([^/]+)/(.+)/?$ handler.php?module=$1&args=$2 [L]
or even like that:
# do not touch requests to handler.php
RewriteRule ^handler\.php$ - [L]
# our rewrite rules
RewriteRule ^([^/]*)/?$ handler.php?module=$1 [L]
RewriteRule ^([^/]+)/(.+)/?$ handler.php?module=$1&args=$2 [L]
You can also go even this way (it really depends on your rewriting logic)
# do not do anything for requests to existing files
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .+ - [L]
# our rewrite rules
RewriteRule ^([^/]*)/?$ handler.php?module=$1 [L]
RewriteRule ^([^/]+)/(.+)/?$ handler.php?module=$1&args=$2 [L]
A problem could be that existing file-names get rewritten as well. To avoid that, you can add:
RewriteCond %{REQUEST_FILENAME} !-f # ignore existing files
RewriteCond %{REQUEST_FILENAME} !-d # ignore existing directories
So for you it would be:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f # ignore existing files
RewriteCond %{REQUEST_FILENAME} !-d # ignore existing directories
RewriteRule ^([^/]*)/?$ handler.php?module=$1
RewriteCond %{REQUEST_FILENAME} !-f # ignore existing files
RewriteCond %{REQUEST_FILENAME} !-d # ignore existing directories
RewriteRule ^([^/]+)/(.+)/?$ handler.php?module=$1&args=$2

Categories