KBD

Keith Devens .com

Tuesday, October 14, 2008 Flag waving
Of course, that's just my opinion. I could be wrong. – Dennis Miller
← Dual bootingStructured templating →

Daily link icon Sunday, May 23, 2004

Does mod_rewrite's last flag do anything?

Does mod_rewrite's last flag do anything? These rules wind up giving a forbidden error:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . dispatcher.php [L]
RewriteRule . - [f]

That says: "If the requested filename doesn't exist, forward any URL to dispatcher.php and stop processing rules". Yet instead of stopping at the dispatcher line, it continues onto the next and makes the page forbidden. Why?

← Dual bootingStructured templating →

Comments XML gif

Adam Langley (http://www.imperialviolet.org) wrote:

I'm not sure why [L] isn't working, but you need to be careful with the !-f flag. Don't you need to prefix it with /path/to/docroot, or replace !-f with !-U?

You have got "RewriteEngine on" in there?

Otherwise, try:
RewriteCond /path/to/docroot/%{REQUEST_FILENAME} !-f
RewriteRule . dispatcher.php [L]
RewriteCond /path/to/docroot/%{REQUEST_FILENAME} -f
RewriteRule . - [f]

AGL

∴ Adam Langley | 23-May-2004 6:23am est | http://www.imperialviolet.org | #4654

Phil Ringnalda (http://philringnalda.com) wrote:

Does [L] say "stop right now, and start pushing bits down the wire" or does it say "stop processing this pass through .htaccess, and start over as a new request with the filename you have now"? After all, if instead of dispatcher.php you rewrote it to /foo/bar/dispatcher.php, you would want the request to obey .htaccess in /foo and /foo/bar, right? I haven't had enough coffee yet to come up with a test, but I think you're failing on the second pass through, when it has started a new request for dispatcher.php, which is a regular file, and is thus forbidden. Either way, making the last line RewriteRule !^dispatcher.php$ - [f] seems to work (unless a direct request for dispatcher.php ought to be forbidden as well?).

∴ Phil Ringnalda | 23-May-2004 1:24pm est | http://philringnalda.com | #4657

Ronaldo (http://reflectivesurface.com/weblog/) wrote:

That has to do with the way mod_rewrite works, especially when the rules are in a .htaccess file.

When a request is processed by mod_rewrite and it causes a sub-request to be initiated, the file is parsed again and all rules that apply to the new request are processed. In the case above, that's what causing all files to be marked as forbidden. You can solve the problem making the rule more that forbids requests more specific.

Also, use (.*) instead of . in the regular expression that match the entire filename. Using a single . means you're matching any file containing at least one character and will cause problems if you use the group when replacing parts of the URL.

You can debug mod_rewriting adding those two directives in httpd.conf:

RewriteLogLevel 9
RewriteLog "<path-to-log-file"

∴ Ronaldo | 23-May-2004 1:24pm est | http://reflectivesurface.com/weblog/ | #4658

Keith (http://keithdevens.com/) wrote:

but you need to be careful with the !-f flag. Don't you need to prefix it with /path/to/docroot, or replace !-f with !-U?

REQUEST_FILENAME is "The full local filesystem path to the file or script matching the request." So, that's not the problem. (Although, after looking, the mod_rewrite guide treats it both ways in different cases. It might differ depending on the RewriteBase. In any case, I'm pretty sure it's what I want.)

RewriteEngine is on, and I know that the dispatcher line is being executed because, well, because this page works. All of my pages run through the dispatcher.

Keith | 23-May-2004 1:27pm est | http://keithdevens.com/ | #4659

Keith (http://keithdevens.com/) wrote:

I think you're failing on the second pass through, when it has started a new request for dispatcher.php, which is a regular file, and is thus forbidden.

When a request is processed by mod_rewrite and it causes a sub-request to be initiated, the file is parsed again and all rules that apply to the new request are processed.

I didn't realize it restarts the request and makes a second pass. That must be what's happening. Any way to stop it from doing that? Maybe I have to replace dispatcher.php with the full path to the file so it's absolute instead of relative.

Using a single . means you're matching any file containing at least one character and will cause problems if you use the group when replacing parts of the URL.

I know, but I'm indescriminately replacing the whole url with dispatcher.php, and I don't need to use any captures.

You can debug mod_rewriting adding those two directives in httpd.conf:

I actually can't because I have to test live on my (shared) server. I've had problems testing mod_rewrite on Windows before (known bugs, it seemed, when I checked, though given my gap in knowledge about mod_rewrite I just discovered, it could have been my fault).

Keith | 23-May-2004 1:35pm est | http://keithdevens.com/ | #4660

Keith (http://keithdevens.com/) wrote:

Maybe I have to replace dispatcher.php with the full path to the file so it's absolute instead of relative.

Ok, that totally didn't work. Is there any way to stop it from doing a sub-request?

Keith | 23-May-2004 1:37pm est | http://keithdevens.com/ | #4661

Ronaldo (http://reflectivesurface.com/weblog/) wrote:

I don't think it's possible to prevent Apache from going into a sub-request since that would probably break things. But it's possible to check if you're in a sub-request in at least two ways:

1) using the %{IS_SUBREQ} variable, which is set to true of false according the type of the request.

2) using the NS flag, which prevents a rule from being processed if it's matched inside a sub-request.

Keep in mind that using any of those methods can cause unintended results :-) As someone said once: "Despite the tons of examples and docs, mod_rewrite is voodoo. Damned cool voodoo, but still voodoo."

By the way, check those two URLs. They have lots of useful info on mod_rewrite:

http://httpd.apache.org/docs/mod/mod_rewrite.html
http://httpd.apache.org/docs/misc/rewriteguide.html

∴ Ronaldo | 23-May-2004 1:55pm est | http://reflectivesurface.com/weblog/ | #4662

Ronaldo (http://reflectivesurface.com/weblog/) wrote:

Ops... After refreshing the page I realized you're aware of the URLs I posted. Sorry about posting them again :-)

∴ Ronaldo | 23-May-2004 1:58pm est | http://reflectivesurface.com/weblog/ | #4663

Keith (http://keithdevens.com/) wrote:

I was able to log mod_rewrite locally. I remembered that the last time I tried using it locally when I ran into bugs I was using Apache 1, and I currently have Apache 2 installed.

Given these rules:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . /dispatcher.php [L]

Here are the log results when visiting the url 'URL':

  1. [rid#8825d8/initial] (3) [per-dir C:/keith/projects/WEB/public_html/] strip per-dir prefix: C:/keith/projects/WEB/public_html/URL -> URL
  2. [rid#8825d8/initial] (3) [per-dir C:/keith/projects/WEB/public_html/] applying pattern '.' to uri 'URL'
  3. [rid#8825d8/initial] (4) RewriteCond: input='C:/keith/projects/WEB/public_html/URL' pattern='!-f' => matched
  4. [rid#8825d8/initial] (2) [per-dir C:/keith/projects/WEB/public_html/] rewrite URL -> /dispatcher.php
  5. [rid#8825d8/initial] (1) [per-dir C:/keith/projects/WEB/public_html/] internal redirect with /dispatcher.php [INTERNAL REDIRECT]
  6. [rid#87b948/initial/redir#1] (3) [per-dir C:/keith/projects/WEB/public_html/] strip per-dir prefix: C:/keith/projects/WEB/public_html/dispatcher.php -> dispatcher.php
  7. [rid#87b948/initial/redir#1] (3) [per-dir C:/keith/projects/WEB/public_html/] applying pattern '.' to uri 'dispatcher.php'
  8. [rid#87b948/initial/redir#1] (4) RewriteCond: input='C:/keith/projects/WEB/public_html/dispatcher.php' pattern='!-f' => not-matched
  9. [rid#87b948/initial/redir#1] (1) [per-dir C:/keith/projects/WEB/public_html/] pass through C:/keith/projects/WEB/public_html/dispatcher.php

So, it starts over from the beginning and matches the whole darn thing again. I thought that was what the 'next' flag was supposed to be for.

Keith | 24-May-2004 3:17am est | http://keithdevens.com/ | #4668

Keith (http://keithdevens.com/) wrote:

By the way, here's a post I found about the bug I referred to above.

Keith | 24-May-2004 4:16pm est | http://keithdevens.com/ | #4678

Norb Beaver wrote:

So did you actually find a solution to that problem?

∴ Norb Beaver | 19-Jun-2008 10:05pm est | #10700

Keith (http://keithdevens.com/) wrote:

Don't remember, this was years ago. Here's what I use now fwiw:

RewriteEngine On

RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule . %{REQUEST_FILENAME}.php%{PATH_INFO} [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . /dispatcher.php [L]
Keith | 19-Jun-2008 10:50pm est | http://keithdevens.com/ | #10701

Feel free to post a comment below. Please see my comment policy.

Formatting Rules (No HTML):

  • **bold**, *italic*, _underlined_, --strikeout--
  • "text"="url" creates a link, and URLs are auto-highlighted
  • Blockquote: Like e-mail, begin paragraph with > (greater-than sign)
  • Lists: begin paragraph with *,-, or + (unordered), or # (ordered)
  • Code block: ?!code:language=perl|php|sql|javascript|etc.{\n}...{\n}?!/code

:
(will be your IP address if blank)
: (optional)
(Will not be shown on site)

: (optional)
:

October 2008
SunMonTueWedThuFriSat
 1234
567891011
12131415161718
19202122232425
262728293031 



RSS feed RSS feed for Keith's Weblog
Atom feed Atom feed for Keith's Weblog
Weblog archive
Recent comments
  on 6 posts

Recent comments XML

Spider solitaire

I have now won, at the "Difficult"​level, 186 games of Spider​Solitaire.  I...

75.179.28.113: Oct 13, 9:34am

Girls, please don't get breast implants

Please, don't marry him.

You​want to get surgery to make​yourself more i...

gigi: Oct 12, 11:47pm

I hate PHP

Elliot Anderson,

Dude!! You the​man! The reverse replacement for​array_u...

Alex Ndungu: Oct 11, 1:35am

Call a function from a string in Python

?!code:
some_object.__getattribute​__('method_name')()
?!/code

is​the s...

Patrick Corcoran: Oct 8, 3:53pm

Sed one-liners

Hi.

I wanted to let you know​that I wrote an article "Famous Sed​One-Lin...

Peteris Krumins: Oct 8, 3:05am

Generated in about 0.249s.

(Used 8 db queries)

mobile phone