WordPress, Apache, and mod_rewrite. Oh my!

I spent today (re)learning mod_rewrite, but I’m quite confused about a couple of things. See if you can pick them out of the .htaccess file:

# .htaccess
# Redirects all search queries to a nice URL.
# Paired with a robots.txt, guarantees no indexing of search.

Options -Indexes

# BEGIN Custom

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} ^(/|/index.php)$
RewriteCond %{QUERY_STRING} (.*(?:^|&))s=([^&]*)&?(.*)&?$
RewriteRule . /search/%2?%1%3 [NE,R,L]

# END Custom

# BEGIN WordPress

RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

# END WordPress

I didn’t think so. Unfortunately, this little bit of seemingly correct code has a few interesting problems.

Weird behavior with DirectoryIndex

First, the entire custom block doesn’t work as expected. The code is “correct,” but mod_rewrite never fires for requests made to “/?s=asdf”. However, if I modify it to “/index.php?s=asdf”, it works like a champ. In fact, at one point, I even did this ridiculous test as my entire .htaccess file:

# .htaccess
# DirectoryIndex Test

RewriteEngine On
RewriteBase /

# "Guaranteed" to be true in this case.

# Expected: 100% of requests go to example.com.
# Reality: Every request except for "/" goes to example.com.
RewriteRule . http://example.com/#%{REQUEST_URI} [NE,R,L]

The first code listing above matches what is presently in my .htaccess file if you want to poke at it.

Devious Information Leaking

Being a website, there are additional folders in my webroot whose presence I may not wish to advertise. For example, this setup reveals that there is a folder at /user/files. Compare the results to this 404: /does/not/exist. We have manifested a trailing slash for existing folders!


I don’t know the solution for either of these two issues. Even if I add DirectoryIndex disabled or DirectorySlash Off it doesn’t play nicely. Maybe this is an issue with DreamHost and what they will AllowOverride?