Forum Moderators: phranque

Message Too Old, No Replies

URL rewrote fine, but cant browse dirs

See code

         

xKillswitchx

5:45 pm on Dec 6, 2008 (gmt 0)

10+ Year Member



I've got a small problem. I've gotten my URL's rewritten cleanly and even have site.com/something rewrote to site.com/something/. Problem is that I cannot now browse to site.com/images or another directory.

This is for a small CMS in which I gather URL parameters and decide the task from there, so I always get the message that the component of page could not be loaded.

Here is my htaccess...
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteCond %{REQUEST_URI} !.html$
RewriteRule ^(.*)$ [localhost...] [L,R=301]
## The above is what is ading the slash to the end of a non-slashed URL.

RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(.*) $1 [L]
RewriteCond %{REQUEST_URI} !-d
RewriteRule ^(.*)$ index.php?category=$1/ [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-z_]+)/([^/]+/)$ index.php?category=$1

I'm not too good with regex or too experienced with htaccess, so I really am clueless as to how to fix this. I've tried several things to no avail. Any help?

xKillswitchx

6:02 pm on Dec 6, 2008 (gmt 0)

10+ Year Member



OK, seem to have gotten it by moving a -d statement up a line or two.

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteCond %{REQUEST_URI} !.html$
RewriteRule ^(.*)$ /$1/ [L,R=301]

RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(.*) $1 [L]
RewriteCond %{REQUEST_URI} !-d
RewriteCond %{REQUEST_FILENAME} !-d <-- TO HERE
RewriteRule ^(.*)$ index.php?category=$1/ [L]
#RewriteCond %{REQUEST_FILENAME} !-d <-- MOVED HIM
RewriteRule ^([a-z_]+)/([^/]+/)$ index.php?category=$1

jdMorgan

11:01 pm on Dec 6, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You can also remove the line above the new RewriteCond location, since a REQUEST_URI will never exist as a filename (the format is all wrong) and so that RewriteCond will always be true since it is negated.

Also, your last RewriteRule can be removed, because it will never be executed; Any requested URL-path that might match the last RewriteRule's pattern will have already matched the previous RewriteRule's pattern and will have been rewritten to /index.php. So the last RewriteRule will never execute.

There are several problems with the first rule as well: "!.html$" means "If URL does not end with any single characterfollowed by 'html'." That is, an unescaped period is interpreted as a regular-expressions token meaning "match any single character."

However, even correcting that leaves you with unnecessary "file exists" checks on requests for files with extensions, such as all images, CSS and JS files, robots.txt, etc. What is probably wanted is to add a slash if the requested URI does not end with a slash or a filetype and if it does not resolve to an existing file.

Note also that you should always include your canonical hostname in the substitution URL of any external redirect to prevent some potentially-serious problems on servers that are configured with "UseCanonicalName on".

The second RewriteRule is not needed, since once the last rule is removed, its RewriteCond can be moved (after negation) into the next rule for efficiency.

Here's the whole thing cleaned up:


RewriteEngine on
#
# Redirect to add a trailing slash if requested URL does not end with
# a slash or a filetype and does not resolve to an existing file
# Note: Resource-intensive "file exists" check moved to last step for efficiency
RewriteCond %{REQUEST_URI} !/$
RewriteCond %{REQUEST_URI} !^/([^/]+/)*[^.]+\.[0-9a-z]+$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) http://www.example.com/$1/ [R=301,L]
#
# If the requested URL does not resolve to an existing file or directory, rewrite
# it to index.php, passing the URI-path to the script as variable "category"
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php?category=$1/ [L]

Jim

[edited by: jdMorgan at 2:27 am (utc) on Dec. 7, 2008]