htaccess - internal redirects problem - cpu load
markjohnson
Status: New User - Welcome
Joined: 24 Jan 2010
Posts: 3
Reply Quote
I have the following in my .htaccess file:

php_flag magic_quotes_gpc off
Options +FollowSymlinks
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-s
RewriteRule ^admin(.*)$ admin/index.php [L]
RewriteCond %{REQUEST_FILENAME} !-s
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php [L,QSA]

The idea is to fetch the entire URL into index.php, e.g. site.com/page1/page2/3928

index.php would then explode the uri 'page1/page2/3928' into three parts

page1/page2 list all the products (i.e. if $uri[2] is not set, then list all products). This works fine.

page1/page2/3928 is supposed to present product detail, which it does, but for some reason it also runs the query for product listing (page1/page2) not only once but several times.

When I click on page1/page2/3928, mysqyl shows me several instances of product listing query which shouldn't be running at all.

My guess is that /page1/page2/3928 is also internally redirecting about 10 times to /page1 as well.

The rewrite log file show many instances of the following:

127.0.0.1 - - [25/Jan/2010:02:44:58 +0000] [site/sid#1656600][rid#28e14c8/initial] (2) [perdir C:/xampp/htdocs/site/public_html/] trying to replace prefix C:/xampp/htdocs/site/public_html/ with /
127.0.0.1 - - [25/Jan/2010:02:44:58 +0000] [site/sid#1656600][rid#28e14c8/initial] (1) [perdir C:/xampp/htdocs/site/public_html/] internal redirect with /index.php [INTERNAL REDIRECT]
127.0.0.1 - - [25/Jan/2010:02:44:58 +0000] [site/sid#1656600][rid#2c53088/initial/redir#1] (3) [perdir C:/xampp/htdocs/site/public_html/] strip per-dir prefix: C:/xampp/htdocs/site/public_html/index.php -> index.php
127.0.0.1 - - [25/Jan/2010:02:44:58 +0000] [site/sid#1656600][rid#2c53088/initial/redir#1] (3) [perdir C:/xampp/htdocs/site/public_html/] applying pattern '(.*)' to uri 'index.php'
127.0.0.1 - - [25/Jan/2010:02:44:58 +0000] [site/sid#1656600][rid#2c53088/initial/redir#1] (3) [perdir C:/xampp/htdocs/site/public_html/] strip per-dir prefix: C:/xampp/htdocs/site/public_html/index.php -> index.php
127.0.0.1 - - [25/Jan/2010:02:44:58 +0000] [site/sid#1656600][rid#2c53088/initial/redir#1] (3) [perdir C:/xampp/htdocs/site/public_html/] applying pattern '^(.+)$' to uri 'index.php'
127.0.0.1 - - [25/Jan/2010:02:44:58 +0000] [site/sid#1656600][rid#2c53088/initial/redir#1] (1) [perdir C:/xampp/htdocs/site/public_html/] pass through C:/xampp/htdocs/site/public_html/index.php

Any help will be appreciated.

Many thanks!
:: Code ::
:: Code ::

Back to top
markjohnson
Status: New User - Welcome
Joined: 24 Jan 2010
Posts: 3
Reply Quote
*bump*

For further clarification, here are the two queries, only one of which should run:

// This function looks at the uri "/whatever-product-name-id-2039" and extracts the id at the end: 2039
product_id($uri[1]);

// Run only if end of uri is a number
if (product_id($uri[1])) {

//this runs fine, which it should.
$qryDisplayProduct = "SELECT * FROM content WHERE id = ".content_id($path[1]);

} else {
//for some reason, mysql shows several processes for this query which should NOT run. Not only it runs but several instances clogging up the CPU.
$qryListProducts = "SELECT * FROM content ORDER BY `date` DESC";
}

In light of the above from ReWriteLog, am I right in at least assuming that this is due to internal redirects?

What am I doing wrong?
Back to top
techAdmin
Status: Site Admin
Joined: 26 Sep 2003
Posts: 4126
Location: East Coast, West Coast? I know it's one of them.
Reply Quote
If your url is somethign like: site.com/partA/PartB/C
and if Parts A, B, C, are all optional, it's unclear to me exactly what you are doing there, this is how I do it, it's quite standard:

:: Code ::
RewriteCond %{REQUEST_URI} ^/Part(A)$
RewriteRule ^(.*)$ /index.php?partA=$1&partB=''&PartC='' [QSA,L]

RewriteCond %{REQUEST_URI} ^/Part(A)/Part(B)$
RewriteRule ^(.*)/(.*)/$ /index.php?partA=$1&partB=$2&PartC='' [QSA,L]

RewriteCond %{REQUEST_URI} ^/Part(A)/Part(B)/(C)$
RewriteRule ^(.*)/(.*)/(.*)$ /index.php?partA=$1&partB=$2&PartC=$3 [QSA,L]


Or something like that. Obviously, you MUST make the regex pattern in the rewritecond ONLY allow what you expect, otherwise you invite hackers. Like so:

:: Code ::
RewriteCond %{REQUEST_URI} ^/page([0-9]+)/page([0-9]+)/([0-9]{4})$
RewriteRule ^(.*)/(.*)/(.*)$ /index.php?partA=$1&partB=$2&PartC=$3 [QSA,L]


This code isn't tested and working though it is based on working code, doing rewrite rules correctly is not trivial and requires understanding how regex works.

I'm assuming you want the variables set as null if they are null, but of course you could make that however you wanted.

Basically that rule would cascade down: if only partA, then use rule 1, if PartA and partB, use rule 2, and if partA, partB, and C, then use rule 3.

Note that these rules will only process urls that match the pattern, otherwise the urls will go through as expected to the page request, no query string append.
Back to top
markjohnson
Status: New User - Welcome
Joined: 24 Jan 2010
Posts: 3
Reply Quote
Hello techAdmin and thank you for writing back.

The script I have written is much simpler.

This is what index.php does right in the beginning:
:: Code ::

$uri = preg_replace("/\/+/", "/", substr($_SERVER["REQUEST_URI"], strlen($cms_path)));
if(substr($uri, 0, 1) == "/") $uri = substr($uri, 1);
if(strpos($uri, "?"))
$uri = substr($uri, 0, strpos($uri, "?"));
if ($uri=="") $uri="/";

$path=explode("/",$uri);


It just takes a url like site.com/categoryA/categoryB/product-name-id-1234 and breaks it down like:

$path[0]=categoryA
$path[1]=categoryB
$path[2]=product-name-id-1234

OR, sometimes:

site.com/categoryA/product-name-id-5678

which is broken down as:

$path[0]=categoryA
$path[1]=product-name-id-5678

The php script then checks $path[1] for a pattern like this: 'id-1234' If it finds it, it runs the query for displaying product details.

If the pattern doesn't match, it simply lists all the products in categoryA.

The problem that I am encountering now is that when it is given this URL:

site.com/categoryA/product-name-id-5678

It is showing the product details page, which is fine, but it is also running Product list query several times, raising CPU usage to 100%.

I think it is quite obvious, looking at the ReWriteLog that it is due to internal redirects to index.php

And if I am right, I need to know how to stop internal redirection.

Thanks
Back to top
techAdmin
Status: Site Admin
Joined: 26 Sep 2003
Posts: 4126
Location: East Coast, West Coast? I know it's one of them.
Reply Quote
with all due respect, by bypassing the native apache mod rewrite and assigning it to php, you're not at all making it simpler in my opinion, as the problems you're encountering clearly show. The only way I can see you thinking the method you selected is simpler is if you simply don't know how to do mod rewrite and have avoided learning it.

There's nothing complicated at all about what I posted, not sure why you think there is. You're just assigning values to variables using QSA, totally standard apache mod rewrite practice. Those variables of course you want to test properly in php to make sure no clever hacker kiddies are trying something naughty, but the method of using mod rewrite to assign the values is totally standard, it's how I l earned to do it, and it's how most urls are processed as far as I know when they use this method.

If you wanted it in one single line, you can simply assign, I think, the second and third options as optional, ie, zero or one occurances, but I prefer to keep it more readable re regex.

I can't really help or suggest anything re your method, since I don't believe it's a particularly good idea, as your experience should be, but doesn't seem to be, showing you.

You can try webmasterworld Apache forums, make sure to post the actual working code from .htaccess/config files + the php, all of it, minus the website actual name, and see if the guy there likes the idea, he's the best around, and if he suggests it's an odd thing you're doing, and you still want to do it that way, I'd rethink your approach.
Back to top
Display posts from previous:   

All times are GMT - 8 Hours