0

I am running Apache 2.2.11

.htaccess

RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ $1.php [L,QSA]

The Problem: http://localhost/index gives me the Homepage(index.php) properly, but I can also access the same page through the following urls.

http://localhost/index/
http://localhost/index/blahblah
http://localhost/index/blahblah/blah/blah/blah
http://localhost/index.php/
http://localhost/index.php/blahblah/
http://localhost/index.php/blahblah/blah/blah

I want to ensure that only localhost/index will open localhost/index.php, anything other than localhost/index (even localhost/index.php) should return a 404.

I guess I will have to add another RewriteCond for catching all else but existing Request_Filename.php files. How do I get a 404 for all else but localhost/index?

(This question is on SO too with a bounty, but I guess serverfault might be a better place for it.) Update What does the .htaccess do? The aim of the htaccess files is to enable cleaner urls like localhost/index instead of localhost/index.php more explanation can be found at the source of this code

abel
  • 137
  • 1
  • 8

1 Answers1

0

Given the change in scope of the question, I'm going to take another crack at answering it...

What does the .htaccess do?

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f 
RewriteRule ^(.*)$ $1.php [L,QSA]
  1. Match if the requested URI is not a valid file.
  2. Match if the requested URI is not a valid directory.
  3. Match if the requested URI plus "any single character" plus "php" is a valid PHP file (note that this will match "index-php" just as well as "index.php" - you should escape the period character if you want a literal match).
  4. Pass the request through to "whatever the request string was" (^(.*)$) plus ".php" - append the query string ([QSA]) and stop processing mod_rewrite directives after this rule ([L]).

There are some serious problems with these rules - for example, if you create a directory named "index", users requesting "domain.com/index" will get the directory, not your index.php file.

Given your stated intent:

I want to ensure that only localhost/index will open localhost/index.php, anything other than localhost/index (even localhost/index.php) should return a 404.

... I would recommend the following implementation:

.htaccess

RewriteEngine On
RewriteCond %{REQUEST_URI} ^/index$
RewriteRule .* /index.php [L,QSA]

index.php

if ( $_SERVER['REQUEST_URI'] != '/index' ) {
  header("Status: 404 Not Found");
  require( '404.html' );
  die();
}

Update:

How can I do the same thing without having a script at index.php?

To the best of my knowledge, there is no way that this can be done without invoking a kludge because any rule which applies to /index.php will be triggered when /index is passed on to /index.php

Here's the inelegant kludge:

RewriteEngine On

RewriteCond %{REQUEST_URI} ^/index$
RewriteRule .* /index.php?rw=1 [L,QSA]

RewriteCond %{REQUEST_URI} ^/index\.php$
RewriteCond %{QUERY_STRING} !rw=1 [NC]
RewriteRule .* - [F]

(Anyone can access "/index.php?rw=1" now - it's not as elegant as the script edit)

danlefree
  • 2,923
  • 1
  • 19
  • 20
  • +1 if i had the rep. thanks for the detailed answer. How can I do the same thing without having a script at index.php? – abel Sep 30 '10 at 09:38