mod_rewrite to php file unless directory exists - .htaccess

I have a mod_rewrite rule working to direct non-existing directories to a php file which does a database get based on the $1.
Everything works fine unless the directory does exist, which displays the proper directory, but it also appends the query string when it's not necessary.
I have been scouring the web for the past few hours and trying different methods with no luck.
Does anyone know how to keep this functioning as-is, but get rid of the query string?
Thanks much.
Here is my code:
RewriteEngine On
Options +FollowSymlinks
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([0-9a-zA-Z\-]+)/$ $1 [R]
RewriteRule ^([0-9a-zA-Z\-]+)$ product.php?product=$1
What ends up happening is the browser displays the URL as http://domain.com/existing_dir/?product=existing_dir

try that, it removes / on its own without repeating whole process
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*?)/?$ product.php?product=$1
if You insists on limiting special characters, that would do:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([0-9a-zA-Z\-]+?)/?$ product.php?product=$1
+ is 1 or more repeatition, * is 0 or more, and +?, *? are modifiers for not hungry matching - it allows /? to match anything
Additionally in Your example, first RewriteRule is been executed conditionally (when directory does not exists), the second one is executed always (if first whould not break the process) so even if directory exists

Mod_rewrite doesn't affect the query string, it will always be tagged on to the end of the new URL unless you tell mod_rewrite to have an empty query string. This is done by adding just a ? at the end of the new string. So the first line should look like this:
RewriteRule ^([0-9a-zA-Z\-]+)/$ $1? [R]

Related

url rewriting with htaccess not working

I am trying to rewrite my urls in my site so whatever is after the slash is passed as an argument (example.com/Page goes to example.com/index.php?page=Page)
here is the code that isn't working (it gives a Forbidden):
RewriteEngine On
RewriteRule ^/(.+)/$ /index.php?page=$1 [L]
Any Help will be appreciated
This is what I suggested in the comment to your question:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/index\.php
RewriteRule ^(.+)$ /index.php?page=$1 [L,B]
The leading slash does not make sense in .htaccess style files, since you do not process an absolute oath in there, but a relative one. About the trailing slash: your example does not show such a slash, so why do you want to have it in the regular expression? It results in your pattern not matching anything but a request terminated by a slash. Which is not what you want.
The RewriteCond lines are there to still allow access to physical existing files and directories and to prevent an endless loop, though that should not occur with an internal-only rewriting. And you need the B flag to escape the part of the request url you want to specify as GET argument.
The last condition is actually obsolete, since obviously /index.php should be a file. I leave it in for demonstration purposes.
In general it is a very good idea to take a look at the documentation of apaches rewriting module: httpd.apache.org/docs/current/mod/mod_rewrite.html
It is well written, very precise and contains lots of really good examples. It should answer all your questions.

Page without extension with disregarded text before

My current .htaccess allows me to view the page as follows:
http://www.test.com/test.php as http://www.test.com/test
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ $1.php [NC,L]
How it poissible to add anything text before the file name which will be disregarded such as:
http://www.test.com/test34566/test or http://www.test.com/anything/test
In terms of a regular expression, your URL would split in to everything before the last backslash, and everything after it.
^(.*)/([^/]*)/?$
This should allow you to ignore everything before ($1) and use everything after ($2).
Beware though if you are using directories such as in your example, you need to use a rewritecondition that also checks to make sure that the requested URL isn't an actual directory, as well as it not being a file.

Redirect HTTP request to file only if it exists

I'm trying to (internally) redirect a call like /server123/get_file.php?file=frame-38-227113.jpg to /server123/cache/2/2/7/227113/frame-38-227113.jpg.
Of course, only if that file actually exists. Otherwise it will need to go through the get_file script in order to fetch the file.
But I failed to create the correct rewrite rules.
What I have till now:
RewriteEngine On
RewriteCond %{REQUEST_URI} =/get_file.php
RewriteRule ^.*$ /server063/get_file.php [L]
RewriteCond %{QUERY_STRING} file=(frame-[0-9]+-([0-9])([0-9])([0-9])[0-9]+.jpg)
RewriteCond %{REQUEST_URI} ^/(server[0-9]+)/get_file.php
RewriteCond %6/cache/%2/%3/%4/%1 -f
RewriteRule ^.*$ /$6/$5/cache/%2/%3/%4/%1 [L]
But that doesn't work.
I'm hoping someone could give me some insight?
Also when trying to prevent endless looping here I tried using IS_SUBREQ, but that seems to not do much (as in: it always re-tries to loop).
I see 2 issues in your rules:
your groups and file name don't seem to match what you say you want. See the directory structure carefully, you seem to have a dir containing the full 6-digits id of the file, which you are not capturing;
the %N replacements only contain matches for the last RewriteCond statement (per documentation, see: http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewritecond); which means you cannot access matches over multiple RewriteConds.
I think with some environment variable magic, you might be able to do what you want in multiple statements, but given that your file names look safe, I think in your case, you can use the variable THE_REQUEST, which lets you access both the uri and the query string in one go like this:
RewriteCond %{THE_REQUEST} ^GET\ /(server[0-9]+)/get_file\.php\?file=(frame-[0-9]+-(([0-9])([0-9])([0-9])[0-9]+).jpg)
RewriteCond %{DOCUMENT_ROOT}/%1/cache/%4/%5/%6/%3/%2 -f
RewriteRule . %1/cache/%4/%5/%6/%3/%2 [L]
Beware: THE_REQUEST is not escaped!

How to make a clean .htaccess?

i have problem with htaccess and not quite good at it. I want to know how to make a url clean.
Here is the original
http://site.com/page.php?p=index1/index2
and i want this type of url
http://site.com/page/index/index2
and how do i get the p value which is index1/index2 if i what to $_get it from the database?
The pattern ([^/]+) matches everything up to but not including / into $1 and the remainder is captured in (.*) into $2.
RewriteEngine On
# Don't rewrite real existing files & directories (like css,js,img)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Add .php to the first group (like page.php) and stick the rest into p
RewriteRule ^([^/]+)/(.*)$ $1.php?p=$2
Inside of PHP, retrieve the value of p via:
$_GET['p']

.htacces RewriteRule not working

Hi people#stackoverflow,
Maybe I have a fundamental misconception about the working of RewriteRule. Or maybe not. Nevertheless, I'm trying to figure this out now for two days, without any progress.
This is the currrent situation:
I have a Joomla website with SEF and mod_rewrite turned on.
This results in the URL:
mysite.com/index.php?option=com_remository&Itemid=7
being rewritten to:
mysite.com/sub-directory/sub-directory/0000-Business-files/
These are the lines that are currently used in my .htaccess (all standard Joomla)
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^([^\-]*)\-(.*)$ $1 $2 [N]
RewriteCond %{QUERY_STRING} mosConfig_[a-zA-Z_]{1,21}(=|\%3D) [OR]
RewriteCond %{QUERY_STRING} base64_encode.*\(.*\) [OR]
RewriteCond %{QUERY_STRING} (\<|%3C).*script.*(\>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})
RewriteRule ^(.*)$ index.php [F,L]
# RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{REQUEST_URI} (/|\.php|\.html|\.htm|\.feed|\.pdf|\.raw|/[^.]*)$ [NC]
RewriteRule (.*) index.php
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
This is what I want to achieve:
When a visitor uses this URL
mysite.com/sub directory/sub directory/0000 Business files/
it should lead him to the right page.
Although I know it's not the best idea to use spaces in a URL, I'm confronted with the fact that these 'spacious' URL's are used in a PDF, that's already been issued.
I thought I could use mod_rewrite to rewrite these URL's. But all I get is 'page not found'
I've added this rule on top of the .htaccess file:
RewriteRule ^([^\-]*)\-(.*)$ $1 $2 [N]
But this is not working. What am I doing wrong? Or, also possible, am I missing the point on when and how to use mod_rewrite?
rgds, Eric
First off, the default behavior of apache is usually to allow direct URLs that map to the underlying file system (relative to the document root), and you should use RewriteRule when you want to work around that. Looking at your question, it seems like you want to browse the filesystem and so you should not use a RewriteRule.
If mysite.com/sub+diretory/sub+directory/0000+Business+files/ doesn't work (without your rule), I'm wondering: do you have that directory structure on your server? I.e. does it look like this?
[document root]/index.php
[document root]/sub directory/sub directory/0000 Business files/
If not, I'm not sure I understand what you're trying to achieve, and what you mean by the visitor being "lead to the right page". Could you provide an example URL that the user provides, and the corresponding URL (or file system path) that you want the user to be served.
Regarding your rewrite rule, I'm not even sure that it is allowed, and I'm surprised you don't get a 500 Internal Server Error. RewriteRule takes two arguments (matching pattern and substitution) and optionally some flags, but because of the space between $1 and $2 you're supplying three arguments (+ flags).
EDIT: I got the pattern wrong, but it still doesn't make much sense. It matches against any URL that has at least one dash in it, and then picks out the parts before and after the first dash. So, for a URL like "this-is-a-url-path/to-a-file/on-the-server", $1 would be "this" and $2 would be "is-a-url-path/to-a-file/on-the-server". Again, if I had some example URLs and their corresponding rewrites, I could help you find the right pattern.
On a side note, spaces aren't allowed in URLs, but the browser and server probably does some work behind the scenes, allowing your PDFs to be picked up correctly.

Resources