Forum Moderators: phranque

Message Too Old, No Replies

mod_rewrite and index.html

rule working unless filename not specified

         

skyeflye

4:50 pm on Mar 14, 2005 (gmt 0)

10+ Year Member



Hi!

Hopefully this will be easy for someone to answer.

I have a RewriteRule in a .htaccess file working great. It is sends any requests for .html files to a 'wrapper' script that inserts the header footer, etc. Here is the rule, and it is working well.

RewriteRule ^(.*)\.html$ /includes/wrapper.php?p=/$1.html [QSA]

The only time it does not work is when the file name is not specified in the URI. So, it works if the I load the following URL:

[mydomain.com...]

...but if I load the following URL,

[mydomain.com...]

...the index.html file loads directly and the RewriteRule is not invoked.

The strange thing is that the same exact RewriteRule works fine in both cases on a different web server server. So I am thinking that there must be some other Apache option that I need to set in order to make it so that the "implied" index.html files get the RewriteRule applied to them as well.

Does anyone have the 5-second solution? :)

jdMorgan

6:02 pm on Mar 14, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



skyeflye,

You'll have to allow for a blank URL-path, then:


RewriteRule ^$¦^(.+\.html)$ /includes/wrapper.php?p=/$1 [QSA,L]

Jim

[edit] Change the broken pipe "¦" character to a solid pipe character (usually Shift-\) before trying to use this code. Posting on this board modifies the pipe character displayed. [/edit]

sitz

4:52 am on Mar 15, 2005 (gmt 0)

10+ Year Member



Of course, the problem with that is that 'index' won't get placed in the query string if the request was just for /foo/, but *will* if the request is for /foo/index.html. Spent a few minutes playing stuff, and can offer the following:

This does what you want:


RewriteRule ^/([^\.]+)\.html$ /foo.php?bar=$1 [L,QSA]

This does not:

RewriteRule ^/foo/([^\.]+)\.html$ /foo.php?bar=$1 [L,QSA]

However, *this* will...

RewriteRule ^/foo/([^\.]+)\.html$ /foo.php?bar=$1 [L,QSA,PT]

*PROVIDED THAT* ${DOCUMENT_ROOT}/foo/ exists as a directory; the directory needs to exist in order for mod_dir's DirectoryIndex functionality to be invoked, and the 'PT' flag is necessary so that (some) other handlers get a crack at the request (see the 'flags' section of [httpd.apache.org ] for details).

There may be other (potentially unwanted) side-effects in using the PT flag for this. Additionally, note that the processing overhead increases significantly for each additional element in your DirectoryIndex line, since each element in that line will be run through your RewriteRule; from my RewriteLog:


go-ahead with /path/to/php/foo.php
pass through /index.php
init rewrite engine with requested uri /index.htm [^\.]+)\.html$' to uri '/index.htm'
pass through /index.htm
init rewrite engine with requested uri /index.shtml [^\.]+)\.html$' to uri '/index.shtml'
pass through /index.shtml
init rewrite engine with requested uri /index.cgi [^\.]+)\.html$' to uri '/index.cgi'
pass through /index.cgi
init rewrite engine with requested uri /HEADER [^\.]+)\.html$' to uri '/HEADER'
pass through /HEADER
init rewrite engine with requested uri /README [^\.]+)\.html$' to uri '/README'
pass through /README
init rewrite engine with requested uri /icons/blank.gif [^\.]+)\.html$' to uri '/icons/blank.gif'
pass through /icons/blank.gif
init rewrite engine with requested uri /icons/back.gif

Note that despite the go-ahead being issued for foo.php on line 1 of my log output, the request is handed off to a couple of other modules, each of which does processing on the request and feeds things /back/ to mod_rewrite, which declines to perform actions. The end result (with my httpd.conf, anyway) is what you were going for; just be aware of the price you pay for the 'PT' flag.

Ultimately, you have a decision to make; jdMorgan's solution has far less processing overhead than this, but won't pass 'index' to your script if 'index.html' isn't in the user-requested URL. This solution handles that eventuality, but at the cost of more CPU-time. The PHP could be coded to compensate for the lack of an 'index' in jdMorgan's solution, but that may have other pitfalls. Good luck. =)

jdMorgan

6:42 am on Mar 15, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I'll offer a simpler solution if variable "p" must be set to "=/index.html" even when the requested local URL-path is blank: Just use two RewriteRules.

RewriteRule ^(.+)\.html$ /includes/wrapper.php?p=/$1.html [QSA,L]
RewriteRule ^$ /includes/wrapper.php?p=/index.html [QSA,L]

Or, you could use two stacked rules:

RewriteRule ^$ /index.html
RewriteRule ^(.+)\.html$ /includes/wrapper.php?p=/$1.html [QSA,L]

And finally, if the missing "index.html" might be requested from a subdirectory, you'll need to use a slightly-trickier version for use in .htaccess:

RewriteRule (^$¦^.+/$) /$1index.html
RewriteRule ^(.+)\.html$ /includes/wrapper.php?p=/$1.html [QSA,L]

Use [PT] only if absolutely necessary, for the reasons that sitz has cited above. In almost all cases, the other modules which manipulate URLs are executed before mod_rewrite, and [PT] is not needed.

There are often subtle differences in code intended for use in httpd.conf versus that for use in .htaccess: In an .htaccess per-directory context, the leading slash is stripped from the local URL-path "seen" by RewriteRule. Beware of these differences when reviewing mod_rewrite code posted as examples.

Change the broken pipe "¦" characters to solid pipe characters (usually Shift-\) before trying to use any code posted on WebmasterWorld.

Jim

skyeflye

11:34 pm on Mar 21, 2005 (gmt 0)

10+ Year Member



Hi All!

I am really sorry for taking so long to get back to you all. My main workstation's hard drive failed last weekend and I have been rebuilding a new drive. "The drive is dead! Long live the drive!" Luckily everything was backed up!

Anyway, thank you all so very, very much for your time and assistance. JDMorgan, your solution was the one I finally was able to implement properly. It makes perfect sense to me now. I went with the "stacked rules" approach, and used the slightly more complex solution for the first Rule with the "pipe" character since there are numerous "index.html" files throughout subdirectories of the site I am working on.

The scary thing is that (thanks to you guys) I am starting to feel almost like I understand how mod_rewrite is really working now! (...which surely means I don't have clue #1...but such is life!)

Thanks again for everything. You guys have helped better my understanding of what is (to me) a complex subject, and also saved me a lot of 'splainin' to do with a client! :D

Hopefully I might be of some assistance to you all at some point in the future.

Cheers!