Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

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

share|improve this question
add comment

1 Answer 1

up vote 0 down vote accepted

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)

share|improve this answer
    
+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 9:38
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.