Mod-rewrite problems with REQUEST_FILENAME - mod-rewrite

I have a problem with server interpreting domain.com/index as domain.com/index.php. This screws with my URL structure.
I have created a .htaccess file with the following:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?url=$1 [PT,L]
</IfModule>
So if I type in the URL domain.com/index/about I want to get index/about from $_GET['url']. But instead it is blank. If I type any other URL not starting with index, like domain.com/foo/bar I get the expected results.
I understand that this is due to RewriteCond %{REQUEST_FILENAME} !-f which ignores any Rewrite if a file with same filename exist.
So my RewriteRules gives me the results I want as long as URL doesn't involve the word index or other dir- or filename. And that is all fine, since I have no other dirs or files in the current dir.
So question is; Can I make it more specific, as to say ignore filename.php instead of just filename? Meaning that domain.com/index/about should work but not domain.com/index.php/about.
Side question: And why does domain.com/index/about not work anyways? I have no dir called index/about and no file called index/about. Why does it interpret index/something as index.php/something which makes no sense, as I cannot have a dir inside a file.

Related

.htaccess works in local but not on server (but no 404 error)

I have a .htaccess that is supposed to rewrite my URL. My host has told me that it supports URL rewriting, and I verified that by using phpinfo() and checking.
Anyways, this is my .htaccess:
RewriteEngine On
RewriteRule ^([_a-zA-Z0-9]+)$ index.php?page=$1 [R]
It works like a charm in local, but on my server, it doesn't do anything.
I checked this before on the internet and some people had it, but they all had a 404 error, while I don't have a 404 error. It simply doesn't redirect, it doesn't do anything, so I get all kind of error messages.
RewriteRule ^([_a-zA-Z0-9]+)$ index.php?page=$1 [R]
The regex in your rule doesn't match strings with slashes at any position. I am not sure that's acceptable and you don't give any request examples, but I don't think it is.
You may try this rule-set in one .htaccess file at root directory:
Options +FollowSymlinks -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !index\.php [NC]
RewriteRule ^([^/]+)/?$ index.php?page=$1 [L]
For permanent redirection replace [L] with [R=301,L].
You can make sure that the file (!-f) or directory (!-d) that you're matching doesn't exist before the rewrite. That way you don't end up with a 500 loop with something like /index.php?page=index. Additionally the ^ character is matching the beginning of the string, so if your original test was in a subdirectory it would not rewrite since you weren't allowing slashes.
This should work for any instance, however it will ONLY make the page variable the last string in the URI.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ([_a-zA-Z0-9]+)$ /index.php?page=$1 [R,L]

Moving symfony2 htaccess file into vhost

I wanted to move .htaccess content into vhost for performance, and am trying to solve an issue.
This is in .htaccess:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ app.php [QSA,L]
I tried this in Vhost:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /app.php [QSA,L]
The problem is that second one redirects /app_dev.php/ controller to app.php and it shoud not, like in first example.
Any tips are greatly appreciated.
From RewriteCond Directive Apache Docs:
REQUEST_FILENAME:
The full local filesystem path to the file or script matching the request, if this has already been determined by the server at the time REQUEST_FILENAME is referenced. Otherwise, such as when used in virtual host context, the same value as REQUEST_URI.
So what you are actually testing for is not a file has the path /app_dev.php which is not the absolute path i.e. without the DocumentRoot path prepended. So, you have to do this:
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
RewriteRule ^ /app.php [L]
^(.*)$ there is no need for this as you are just rewriting without consideration for URI.
Flag QSA also not required as you are not manipulating any query string.

mod_rewrite - trouble with combination of rules

I've got the following rules to work which:
only act on files that exist
exclude any files that contain images|js|css in their uri
add trailing slash to request uri
Rewrite rules:
RewriteEngine on
DirectorySlash Off
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !/(images|js|css)$
RewriteRule ^(.*[^/.])$ /$1/ [R=301,L]
I now need to correctly redirect my home uri's like so:
http://www.example.com/sitemap/ -> http://www.example.com/index.php?page=sitemap
I've tried the following approach:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*[^/.])$ index.php?page=$1 [R=301,L,NC]
But I get a page not found, presumably because $1 is being fed something with a slash in it. I thought [^/] would remove it but apparently not.
Could someone explain where I am going wrong here please?
Use this rule -- it will rewrite /sitemap/ into /index.php?page=sitemap:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/$ /index.php?page=$1 [QSA,L]
Put it into .htaccess into website root folder. If placed elsewhere it need to be tweaked a bit.
URL will stay the same. Existing query string will be preserved.
The trailing slash / must be present (i.e. /sitemap will not trigger this rule).
It will only rewrite if there is no such folder or file (i.e. if you have a folder named sitemap in your website root folder then no rewrite will occur).
It will only work for 1-folder deep URLs (e.g. /sitemap/, /help/, /user-account/ etc). It will not work for 2 or more folders in path (e.g. /account/history/).
RE: this line: RewriteCond %{REQUEST_URI} !/(images|js|css)$.
You said you want "exclude any files that contain images|js|css in their uri". Unfortunately the above pattern work differently -- it will match /something/css but will not match /css/something or /something/file.css.
If you want to match images|js|css ANYWHERE in URL straight after a slash, then remove $.

Rewrite only if Folder exists but file doesn't

I am trying to rewrite all requests to a file that doesn't exist but the folder does.
What I mean is:
Say I have this folder structure:
foo
'-bar1
'-bar2
'-bar2.html
'-shared
'-shared.html
What I am looking for the rewrite rule to do is to serve up example.com/foo/bar2/bar2.html as normal. Serve example.com/foo/bar1/bar1.html as /foo/shared/shared.html and to no serve example.com/foo/bar3/bar3.html.
So in summary. I am trying to develop a RewriteCond that hits only when the directory exists but the file doesnt exist in that directory.
The problem with:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
is that it will rewrite www.example.com/bar3/bar3.html even though /foo/bar3 directory doesn't exist.
Thanks for the help!
These rules should do the job:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}/$1/ -d
RewriteRule ^(.+)/([^/]+)$ /foo/shared/shared.html [L,QSA]
These rules intended to be placed in .htaccess file in root folder. If you need to place them in config file (e.g. httpd-vhost.conf) then you will need to modify it a bit (remove some slashes in 2nd RewriteCond .. or add leading slash in RewriteRule -- testing is actually required).
These rules will only work if requested resource has at least 1 folder (obvious -- as requested).

What does this Mod Rewrite do?

Can anybody tell me what this does?
RewriteRule .* .main.php [QSA,L]
From what I understand it will rewrite ANYTHING to main.php correct? But not so sure what the QSA,L does.
This is the whole .htaccess file, when I hit the main directory I get a 400 Bad Request error. Edit: Bad request went away when I added an ending slash in the browser to the root directory of this script.
RewriteEngine On
# Transfering to the main tranfer file
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !\.css$
RewriteCond %{REQUEST_FILENAME} !\.js$
RewriteRule .* .main.php [QSA,L]
# nobody is allowed to access the access the INI file
<FilesMatch "\.inc.php$">
Order allow,deny
Deny from all
</FilesMatch>
QSA = Query String Append: append the existing query string to the re-written rule
L = Last Rule: last rule of the set, don't process any following RewriteRule
Check out the documentation for more.
Do you have a file that is named .main.php? The dot prefix worries me. Your rules read that unless the request is an exists, symbolic link, or it has a CSS or JS extension it goes to .main.php

Resources