Forum Moderators: phranque

Message Too Old, No Replies

.htaccess rewrite condition help

         

globex

4:05 am on Jun 21, 2010 (gmt 0)

10+ Year Member



I'm using RewriteRule to send all requests through a PHP file, but I'd like to add a few directories to an exception (for now just '/test'), so that for some directories it doesn't do a write. However, it doesn't seem to work. Here's what I have:

# Rewrite pages through index.php via ?gdUrl
RewriteCond %{REQUEST_URI} !^/test/
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?gdUrl=$1 [QSA,L]


With the idea being that if I go to any page on the site, it rewrites it to index.php, however, I'd like it not rewrite at all when I go to www.mysite.com/test and go directly to the index.html inside of test.

Any help would be greatly appreciated. Thank you.

g1smd

7:43 am on Jun 21, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



The pattern is (almost) correct.

Did you clear your browser cache before retesting?

Requests for exactly "example.com/test" will be rewritten to the script.

Notice that in your question you said "/test" and in the code you have "/test/".

globex

8:17 pm on Jun 21, 2010 (gmt 0)

10+ Year Member



Cache cleared, but it's still not working. Do I need to do some kind of wildcard after /test/? Since I'm actually trying to access www.mysite.com/test/blah.php

I want all files to be free from the rewrite rule inside of /test/ not just index.php

jdMorgan

3:11 pm on Jun 22, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I'd suggest the following in example.com/.htaccess:

# Rewrite requests for all URL-paths to "/index.php? with URL-path passed in "gdUrl" query
# variable, unless the requested URL-path has already been rewritten to the script, resolves
# to the /test subdrectory, or resolves to an existing file or directory.
RewriteCond $1 !^index\.php$
RewriteCond $1 !^test/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?gdUrl=$1 [QSA,L]

The additional RewriteCond is for efficiency -- It prevents rewritten requests for /index.php from invoking two more "exists" checks, which may require a disk access, and are therefore very inefficient.

Note that as g1smd pointed out, requests for example.com/test/ will not be rewritten to the script, and requests for example.com/test/something will not be rewritten, but requests for example.com/test will be rewritten. If you don't want requests for example.com/test to get rewritten, then I'd suggest changeing the RewriteCond pattern to !^test(/.*)?$

However, be aware that technically, example.com/test/ refers to a subdirectory of your root directory, and example.com/test refers to a file in your root directory, so you really should require that trailing slash and NOT use this modified pattern.

Jim

globex

11:44 pm on Jun 22, 2010 (gmt 0)

10+ Year Member



Using jdMorgan's suggestion didn't work. It still rewrites requests to example.com/test/asd.php

However, after I changed the RewriteCond from $1 to ${REQUEST_URI} example.com/test/asd.php now gives me: [an error occurred while processing this directive]

Any ideas?

jdMorgan

12:48 am on Jun 23, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Changing from $1 to %{REQUEST_URI} is a trivial change, affecting nothing as long as you prepended a slash to the excluded URL-path as required for use with %{REQUEST_URI}. Actually, the whole bit of code is trivial...

Where is this code located in the URL-space of your site (I specified /example.com/.htaccess, is that correct?) Where is it located in the file-space on the server?

Do you have any other mod_rewrite or mod_alias code in this file?

Are you using a non-default RewriteBase?

Are MultiViews or AcceptPathInfo enabled on this server?

Jim

globex

2:44 am on Jun 23, 2010 (gmt 0)

10+ Year Member



Here's what I got:

# Use PHP5 Single php.ini as default
AddHandler application/x-httpd-php5s .php

# CACHE CONTROL
# 480 weeks
<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf|jgz)$">
Header set Cache-Control "max-age=290304000, public"
</FilesMatch>

# 2 DAYS
<FilesMatch "\.(xml|txt)$">
Header set Cache-Control "max-age=172800, public, must-revalidate"
</FilesMatch>

# 2 HOURS
<FilesMatch "\.(html|htm|php)$">
Header set Cache-Control "max-age=7200, must-revalidate"
</FilesMatch>

# DISABLE E TAGS
<ifModule mod_headers.c>
Header unset ETag
</ifModule>
FileETag None

# COMPRESS
# DEFLATE
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript

# REDIRECTS
RewriteEngine On

# Rewrite pages through index.php via ?gdUrl
RewriteCond %1 !^index\.php$
RewriteCond %1 !^converge/
RewriteCond %1 !^converge_local/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?gdUrl=$1 [QSA,L]



I just can't seem to be able to get /converge_local/ to work.

.htaccess is located in the root. www.mysite.com/.htaccess

No other mod_rewrites being used.

Not sure about "non-default RewriteBase, MultiViews or AcceptPathInfo". How would I check that?

globex

6:44 am on Jun 23, 2010 (gmt 0)

10+ Year Member



Apache is returning the following error:

[Wed Jun 23 00:43:39 2010] [error] [client 70.79.50.44] SoftException in Application.cpp:601: Directory "/home1/globexde/public_html/converge_local" is writeable by group [Wed Jun 23 00:43:39 2010] [error] [client 70.79.50.44] Premature end of script headers: index.php 

jdMorgan

2:21 pm on Jun 23, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



With that most-recently-posted code, none of the exceptions that you require will be made, because the variable being tested in the first three RewriteConds is now incorrect. To work, those RewriteConds must be in one of two forms:

 RewriteCond $1 !^converge_local/ 

-or-
 RewriteCond %{REQUEST_URI} !^/converge_local/ 


Note that the variable in the first versions is "$1" not "%1" and that in the second versions, the path-testing pattern must start with a slash. The function of these two lines is identical if used exactly as shown.

Something, somewhere must be being used to rewrite requests for "/converge_local" to a script for processing.

Why? Well, because without such a rewrite, the "/converge_local" request would by default be handled by 'mapping' it to a filepath of "/converge_local", which does not end with a valid filetype. So that's unlikely to to access an existing script.

Failing to find an existing script named "/converge_local", the server will invoke mod_dir, which will add a trailing slash, making the requested URL-path "/converge_local/". Mod_dir will then apply any DirectoryIndex rules defined in the server config (there are no additional DirectoryIndex rules in your present .htaccess file, so these need not be considered). Therefore, if there is a directory index page (e.g. "index.php") at "/converge_local/" it should get invoked.

I'm not sure if you will be able to tell if this is the case, but fix the code as described above, and then test again to see if you can tell. Please don't try to 'improve' the code suggested here without telling us about it first. Doing so makes it impossible for us to 'follow along' and additional errors may be introduced (as above). I should also state that mod_rewrite code cannot be 'guessed at' -- The chances of success with that method are essentially zero.

Once the mod_rewrite code is put back into working order, the next steps involve trying to find ways in which the .htaccess file might be getting pre-empted and to attempt to modify those preemptions. If an Alias is defined in the server config (e.g. perhaps using control panel) that (for example) maps certain URL-requests to a commercial script, then your .htaccess may not run at all for those requests.

Two of the other things I mentioned, MultiViews and AcceptPathInfo, can be turned off using
 Options -MultiViews 

-and-
 AcceptPathInfo off 


However, some scripts and sites depend on these two functions, so disabling them may cause other problems. And unfortunately, if that happens, then the 'quick fix' turns into a big project, and you'll have to move the site to a VPS hosting account in order to get server-config access in order to have sufficient control to fix it... :(

Jim

globex

5:44 pm on Jun 23, 2010 (gmt 0)

10+ Year Member



Thank you for taking the time to help me out with this Jim, I really appreciate it. Here's what I've got now:

# REDIRECTS
RewriteEngine On

# Rewrite pages through index.php via ?gdUrl
RewriteCond $1 !^index\.php$
RewriteCond $1 !^converge_local/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?gdUrl=$1 [QSA,L]


However the rewrite is still not working for /converge_local/

I tried adding:

Options -MultiViews
AcceptPathInfo off


Above the rewrite rules and it made no difference either.

Is there some way I can debug the process to see what could potentially be the culprit? There are no other .htaccess files in any of the directories of my site (if that helps).

jdMorgan

10:21 pm on Jun 23, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



If you are still seeing requests for example.com/coverge_local/xyz getting rewritten to /index.php?gdUrl=converge_local/xyz, then either there are some directives in your server config files doing this, or your server installation or configuration is bad (possibly corrupt) and needs to be re-done.

I can't comment on the 'premature end of script headers' here, as that is a PHP coding problem -- and not my forte.

Jim

globex

12:39 am on Jun 24, 2010 (gmt 0)

10+ Year Member



Looks like the requests to example.com/converge_local/ are getting rewritten to /index.php?gdUrl=500.shtml

The 500.shtml seems like a custom error page that my host is using, but why would it be returning a 500 error in the first place?

jdMorgan

2:45 am on Jun 24, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Look at your server error log to find out...

Jim

globex

5:46 am on Jun 24, 2010 (gmt 0)

10+ Year Member



For the record, the solution to the problem was that my directory's permissions were set to 777. Once I set the directory to 755 and the files to 644, everything started to work properly.