开发者

"Spoofing" a 404 not found error with .htaccess

I have .htaccess currently set up to rewrite anything without a period or slash to the equivalent with a .php extension (so "foo" internally pulls up "foo.php") via the following:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !(.*)\.php
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^([^/.]+)$ $1.php [L,NS]

However, I'd like direct requests for "foo.php" come back with a 404 as though the file didn't exist (just as if someone tried "foo.asp" or "foo.blargh"). I know there's the [F] and [G] flags, but I don't want "forbidden" (403) or "gone" (410), as those are different results from what a nonexistent file returns (404).

Is there a way to do this?

UPDATE 1

I've tried

RewriteCond %{REQUEST_FILENAME} \.php$
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*\.php\ HTTP/
RewriteRule ^(.*)$ /error.php?e=404 [R=404,L,NS]

Which works... until I try to use an ErrorDocument handler. Assuming "error.php" at my document root, anything along the lines of ErrorDocument 404 /error?e=404 (i've also tried with error.php, etc) regurgitates the error

Not Found

The requested URL /foo.php was not found on this server.

Additionally, a 500 Internal Server Error error was encountered while trying to use an ErrorDocument to handle the request.

... but only when attempting to access a .php page that actually exists (such as foo.php); any attempt 开发者_如何转开发to access a page that actually doesn't exist (and thus doesn't trigger my second rewrite rule) goes to the page specified by the ErrorDocument handler.


Found a solution:

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ (/.*)\.php
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{REQUEST_URI} !^/error\.php
RewriteRule . - [R=404,L,NS]

ErrorDocument 404 /error.php?e=404

Specifically, the third RewriteCond keeps requests for the error page from triggering the RewriteRule (since the THE_REQUEST still contains the original request (matching the first RewriteCond), and the error page does indeed exist (matching the second RewriteCond).

Note that the third RewriteCond matches the URI format specified for the ErrorDocument. Within error.php, I use $_SERVER["REDIRECT_SCRIPT_URL"] to find out what file the user originally requested (thus making it look like the 404 was served as a direct response to their request).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜