Forum Moderators: phranque

Message Too Old, No Replies

Painful RewriteRule Issues

No access to script args?

         

riscit

6:09 am on Jan 20, 2004 (gmt 0)

10+ Year Member



Hello all.

Could use some help sorting this out... I'd appreciate any suggestions.

I started with this:

DirectoryIndex /cgi-bin/masterscript.cgi

Which meant that any requests such as these:


http://www.domain.com/?page=pagename
http://www.domain.com/?product=12345
http://www.domain.com/?brand=acme
http://www.domain.com/?category=pencils

were translated to:

http://www.domain.com/cgi-bin/masterscript.cgi?page=pagename
http://www.domain.com/cgi-bin/masterscript.cgi?product=12345
http://www.domain.com/cgi-bin/masterscript.cgi?brand=acme
http://www.domain.com/cgi-bin/masterscript.cgi?category=pencils

And it was good. Or at least it was until my masterscript.cgi got way too big and had way too much code in it to be the jack of all trades (yes I know it was a stupid plan. Thank you. Where were you 3 years ago when the site wasn't getting any traffic.....). ;)

So I've written smaller scripts to do the specialized tasks.

Now what I'm trying to do is route the requests to the appropriate scripts. Such that these requests:


http://www.domain.com/?page=pagename
http://www.domain.com/?product=12345
http://www.domain.com/?brand=acme
http://www.domain.com/?category=pencils

would end up translated like this:

http://www.domain.com/cgi-bin/pages.cgi?page=pagename
http://www.domain.com/cgi-bin/products.cgi?product=12345
http://www.domain.com/cgi-bin/brands.cgi?brand=acme
http://www.domain.com/cgi-bin/categories.cgi?category=pencils

The parameters are the same, they just end up at a different script.

The problem I'm having is that:


RewriteEngine On
RewriteBase /
RewriteRule ^(\?page.+)$ cgi-bin/pages.cgi$1
RewriteRule ^(\?product.+)$ cgi-bin/products.cgi$1
RewriteRule ^(\?brand.+)$ cgi-bin/brands.cgi$1
RewriteRule ^(\?category.+)$ cgi-bin/categories.cgi$1

Doesn't seem to work.

I have other rewrite rules, such as:


RewriteRule ^product-([0-9]+)\.html$ cgi-bin/products.cgi?product=$1
RewriteRule ^brand-(.+)\.html$ cgi-bin/brands.cgi?brand=$1

...that work fine, so I know that mod_rewrite is on and working normally.

Is it simply that mod_rewrite only sees the uri, and not the script parameters, and thus they can not be searched?

If this is so, does anyone have an idea for workarounds?

Thanks in advance for any help.

jdMorgan

7:23 am on Jan 20, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



riscit,

Welcome to WebmasterWorld [webmasterworld.com]!

The problem is that mod_rewrite does not consider anything after a "?" to be part of the URL, it considers it to be part of a query string. Therefore, you have to use RewriteCond %{QUERY_STRING} in order to test or back-reference the query string.

This search [google.com] will turn up dozens of threads on the subject, if you need examples to look at.

JIm

riscit

7:32 am on Jan 20, 2004 (gmt 0)

10+ Year Member



thanks jd. Will have a look in the morning. Need sleep. =)

riscit

7:54 pm on Jan 20, 2004 (gmt 0)

10+ Year Member



Thanks JD. That helped a little and gave me some more insight, but I'm still stuck.

The best I've come up with is this:


rewritecond ${query_string} ^(product.+)$
RewriteRule .* cgi-bin/product.cgi?$1

If I understand this correctly, that should apply to all requests with a query string that starts with "product", and rewrite any and all requests (because .* should match everything, including nothing) to cgi-bin/product.cgi?product<whatever>.

If this is the case, then this:

http://www.domain.com/?product=12345

should be re-written to this:

http://www.domain.com/cgi-bin/product.cgi?product=12345

(which is what I'm trying to accomplish) But it isn't working. Am I missing something? I have a feeling it has something to do with the .* in the rewrite rule, but I don't know what to do about it - there isn't anything to compare it to.

Also, I see some inconsistencies on this forum between %1 and $1.... I tried both just in case, with no luck. I know $1 is the standard perl regex substitution string, but I've never seen %1 used in such a place. Did I miss something here as well?

riscit

9:31 pm on Jan 20, 2004 (gmt 0)

10+ Year Member



ha! and then I learned to read.....

it's %{QUERY_STRING} not ${QUERY_STRING}

% as opposed to $.

I really, REALLY hate it when I spend more than an hour looking at something to find out it's an issue of one little character. oh well.

Just for the sake of being thourough, this is what works perfectly:


RewriteCond %{QUERY_STRING} ^product=
RewriteRule ^$ cgi-bin/product.cgi [L]

Thanks JD. You got me pointed in the right direciton. It's my own stupid fault for not knowing how to read. =)

jdMorgan

9:45 pm on Jan 20, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Riscit,

Another point is that back-references to RewriteCond patterns are done using "%n" as opposed to the "$n" used to back-reference RewriteRule patterns.

So just as an example of that, you might use:


RewriteCond %{QUERY_STRING} ^product=(.*)
RewriteRule ^$ /cgi-bin/product.cgi?prodcode=%1 [L]

mod_rewrite is difficult in many ways, and one of them is that it requires absolutely-correct coding. While many languages support minor variations of syntax "style", mod_rewrite does not. Throw in the complexity of Regular-Expressions syntax, and the learning curve is rather steep. Once you get it, though, you get it, and everything is a lot easier after that. :)

Keep learning!
Jim

riscit

3:56 pm on Jan 21, 2004 (gmt 0)

10+ Year Member



Once you get it, though, you get it, and everything is a lot easier after that.

heh.. that can't be true, because I thought I had got it. ;)