views:

34

answers:

2

After a day or two, I am still fighting with Mod Rewrite. It seems that 60% of my development time is spent battling the server.

My current URL structure is such that all http://example.com/xyz and http://example.com/xyz/abc should be handled by index.php. The problem is I have a http://example.com/admin/ section, which is a real directory which I need to be accessible via HTTP request (it's the CMS directory)

When I try to browse to the CMS http://example.com/admin/, It changes my URL to http://example.com/admin/?n=admin and returns a 404. My index.php is receiving n=admin as it's argument.

What I cant understand is why these two conditions are being ignored:

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !^admin(?:\/)?$

And why I'm getting that redirect to http://example.com/admin/?n=admin (Rather than just stopping at http://example.com/admin/.

Options +FollowSymlinks
RewriteEngine On
RewriteBase /

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !^admin(?:\/)?$

# allow access to certain subdirectories.
RewriteRule ^admin(?:\/)?$ /admin/ [L,NC]

# redirect all old URLs to new pages (or 404 sitemap page if no analog?).
RewriteRule ^company/about(?:\/)?$ /company [R=301,L,NC]

# catch any others and try to serve them right
RewriteRule ^/?(.+).html$ /$1 [R=301,L]

RewriteRule ^/?([0-9]+)(?:\/)?$ /index.php?p=$1 [L]
RewriteRule ^/?([-a-zA-Z0-9_+]+)(?:\/)?$ /index.php?n=$1 [L]
RewriteRule ^/?([-a-zA-Z0-9_+]+)/([-a-zA-Z0-9_+]+)(?:\/)?$ /index.php?n=$2 [L]

Can anyone offer any ideas or point out any flaws in the .htaccess?

A: 

Each RewriteCond only applies the the next RewriteRule.

so only your first Rule has a condition.

Your options are to repeat the rules, or make then final and exiting (cannot remember flag for this off my head)

Simeon Pilgrim
That would suggest that this would work:RewriteCond %{REQUEST_FILENAME} -fRewriteCond %{REQUEST_FILENAME} -dRewriteCond %{REQUEST_FILENAME} ^admin(?:\/)?$RewriteRule ^(.?)$ $1 [L]But it doesnt?
Antony Carthy
In fact, this should work, but doesn't:RewriteCond %{REQUEST_FILENAME} -f [OR]RewriteCond %{REQUEST_FILENAME} -d [OR]RewriteCond %{REQUEST_FILENAME} ^admin(?:\/)?$RewriteRule ^(.?)$ $1 [L]
Antony Carthy
I'm still very sure that your first rule will never match, as you condition it with "if path is not a file and the path is not a directory and the path is not admin/ or admin" then if the path is "admin/ or admin" rewrite it to "/admin/"Thus no net change, due to the previous not.
Simeon Pilgrim
A: 

Try this rule before your other rules:

RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]

This will end the rewrite process if the requested path can be mapped to an existing directory. The same applies when using -f instead.

Gumbo