3

I want the following:

  1. www.bla-bla.com/ --> www.bla-bla.com/php/index.php
  2. www.bla-bla.com/php/index.php --> www.bla-bla.com/php/error.php

I have tried the following but doesn't work

RewriteEngine on
RewriteRule ^/?$  /php/index.php [S=1]
RewriteCond %{REQUEST_URI} =/php/index\.php
RewriteRule (.*)? /php/error.php [R=404]

What can I do to deny access from real path?


URL=http://localhost
 (3) [perdir C:/xampp/htdocs/] strip per-dir prefix: C:/xampp/htdocs/ -> 
 (3) [perdir C:/xampp/htdocs/] applying pattern '/php/index\.php' to uri ''
 (3) [perdir C:/xampp/htdocs/] strip per-dir prefix: C:/xampp/htdocs/ -> 
 (3) [perdir C:/xampp/htdocs/] applying pattern '^(/?)$' to uri ''
 (2) [perdir C:/xampp/htdocs/] rewrite '' -> '/php/index.php'
 (1) [perdir C:/xampp/htdocs/] internal redirect with /php/index.php [INTERNAL REDIRECT]
 (3) [perdir C:/xampp/htdocs/] strip per-dir prefix: C:/xampp/htdocs/php/index.php -> php/index.php
 (3) [perdir C:/xampp/htdocs/] applying pattern '/php/index\.php' to uri 'php/index.php'
 (3) [perdir C:/xampp/htdocs/] strip per-dir prefix: C:/xampp/htdocs/php/index.php -> php/index.php
 (3) [perdir C:/xampp/htdocs/] applying pattern '^(/?)$' to uri 'php/index.php'
 (1) [perdir C:/xampp/htdocs/] pass through C:/xampp/htdocs/php/index.php
URL=http://localhost/php/index.php
 (3) [perdir C:/xampp/htdocs/] strip per-dir prefix: C:/xampp/htdocs/php/index.php -> php/index.php
 (3) [perdir C:/xampp/htdocs/] applying pattern '/php/index\.php' to uri 'php/index.php'
 (3) [perdir C:/xampp/htdocs/] strip per-dir prefix: C:/xampp/htdocs/php/index.php -> php/index.php
 (3) [perdir C:/xampp/htdocs/] applying pattern '^(/?)$' to uri 'php/index.php'
 (1) [perdir C:/xampp/htdocs/] pass through C:/xampp/htdocs/php/index.php

Options +FollowSymlinks RewriteEngine on

RewriteRule /php/index\.php /php/error.php [L]
RewriteRule ^(/?)$ /php/index.php [QSA,L]

Wtf is going on here?

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
Chris P
  • 2,059
  • 4
  • 34
  • 68
  • 1
    Do you mean to say that everything in `bla-bla.com/` should rewrite to the same thing in `bla-bla.com/php/` , but you don't want users to be able to access anything by directly going to `bla-bla.com/php/`? – Levi Morrison Nov 18 '11 at 02:27
  • this is allmost, my main goal But especially i want that i asked Thx for reply – Chris P Nov 18 '11 at 02:30
  • When visitors wants to browse bla-bla.com/ apache executes and send php/index.php file, but when a visitor want to browse bla-bla.com/php/index.php apache executes and seand bla-bla.com/php/error.php file.. – Chris P Nov 18 '11 at 02:38
  • possible duplicate of [Is there a way to force apache to return 404 instead of 403?](http://stackoverflow.com/questions/1486304/is-there-a-way-to-force-apache-to-return-404-instead-of-403) - and you might be looking for the `L` flag. – hakre Nov 18 '11 at 02:48
  • RewriteRule ^/?$ /php/index.php [L] RewriteRule ^/?php/index\.php$ /php/error.php Even this lines solvee the problem..I have a xampp installation right now.. – Chris P Nov 18 '11 at 02:58

3 Answers3

1

use

ErrorDocument 404 /php/error.php

in .htaccess file

Shailesh Jangir
  • 395
  • 2
  • 10
0

Try this:

# If the actual request is for /php/index.php, rewrite to error.php
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /php/index.php  [NC]
RewriteRule ^php/index\.php /php/error.php  [L]

# Otherwise check if root request and rewrite to /php/index.php
RewriteRule ^$ /php/index.php  [L]

EDIT: responding to comments:

Without the[L] flag, it will try to apply the next rule. mod_rewrite will always send it back through the rewrite engine after a URI has been rewritten. It will continue to do so until the URI went through the engine unchanged. The first condition checks that the actual request is for /php/index.php, so that the rewritten URI won't match. Example:

  1. Someone requests http://bla-bla.com/
  2. first rule doesn't match because the HTTP Request is GET / HTTP/1.1
  3. second rule rewrites to /php/index.php
  4. mod_rewrite sends the rewritten URI back through the rewrite engine
  5. first rule doesn't match because eventhough the URI is now "/php/index.php", the original HTTP Request is still the same: GET / HTTP/1.1
  6. second rule doesn't match because the URI is now "/php/index.php" and not "/".
  7. rewrite engine stops because base URI is unchanged.

Example 2:

  1. Someone requests http://bla-bla.com/php/index.php
  2. first rule matches because the HTTP Request is GET /php/index.php HTTP/1.1
  3. URI is rewritten to /php/error.php
  4. second rule doesn't match
  5. URI is sent back through the rewrite engine
  6. first rule's condition matches because the HTTP Request is still the same
  7. however, the URI isn't '/php/index.php' now so the actual rule doesn't match
  8. second rule still doesn't match
  9. reiwrte engine stops because base URI is unchanged.
Jon Lin
  • 142,182
  • 29
  • 220
  • 220
  • http://httpd.apache.org/docs/current/rewrite/flags.html#flag_l says: It is possible that as the rewritten request is handled, the .htaccess file or section may be encountered again, and thus the ruleset may be run again from the start. – Chris P Nov 18 '11 at 14:48
  • So, [L] flag means: GO to end, then start again with the new URL If any of rules doesn't match stop proccessing..angryyyyy – Chris P Nov 18 '11 at 14:51
  • See my edit to explain what's going on. Also note that the first rule needed to be tweaked. Try it again and see if you still get errors. – Jon Lin Nov 18 '11 at 18:02
  • very good expplanation, what's going wrong.. RewriteCond %{THE_REQUEST} ^[A-Z]+ /php/index.php [NC] must be RewriteCond %{THE_REQUEST} ^[A-Z]+/php/index.php [NC] ? The above code doesn't do my job.. Thx for reply.. – Chris P Nov 18 '11 at 18:46
  • Sorry, forgot a backslash on that line – Jon Lin Nov 18 '11 at 18:54
  • I want to make 1 more things. 1)404 Redirect for all .php files (the request wouldn't be a subrequest) I try this: RewriteCond %{THE_REQUEST} ^[A-Z]+\ (.+)\.php [NC] RewriteRule ^(.+)$ /php/error.php?url=$1 [L,NS] but i see a 500 internal server error – Chris P Nov 18 '11 at 23:56
  • try adding a `RewriteCond %{REQUEST_URI} !^/php/error.php` before that rewrite rule, otherwise it will loop. – Jon Lin Nov 19 '11 at 00:01
  • you are right THis also works fine: RewriteCond %{THE_REQUEST} ^[A-Z]+\ (.+)\.php [NC] RewriteRule [^/php/error\.php] /php/error.php [L,NS] THx – Chris P Nov 19 '11 at 00:02
0

Jon: I don't understand your solution.

Here's mine: first check if there's a try to access what you don't want (i.e. /php/index.php) and if so, redirect to error and stop everything. Then after (only after), you're sure it's not /php/index.php so apply your redirection:

RewriteRule /php/index\.php /php/error.php [L]
RewriteRule / /php/index.php [QSA,L]

Keep in mind that the [L] directive will stop immediately RewriteRules, so remove le last one if you want to add other RewriteRules.

Of course, if you want to redirect ALL the incoming requests to php/index.php and pass the URL as an argument here is the solution that should work (I say "should" because I haven't tested):

RewriteRule /php/index\.php /php/error.php [L]
RewriteRule (.*) /php/index.php?url=$1 [QSA,L]

Olivier

Olivier Pons
  • 15,363
  • 26
  • 117
  • 213