You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@httpd.apache.org by Dragon <dr...@crimson-dragon.com> on 2007/03/31 18:56:41 UTC
Re: [users@httpd] Mod RewriteRule Help : Accepting Variable
Number Of Arguments
Kristopher Yates did speak thusly:
>Hello,
>
>Here is an example URL I'm trying to create a RewriteRule for:
>
>index.php?section=help&page=test&mode=IN&item=4&action=edit
>
>I have a rule that works when the request URL contains the
>appropriate number of arguments but does not work when there are
>fewer arguments than the Rule expects. I thought by creating
>multiple (similar) rules would resolve but no luck. Here is what I
>have that works as long as I pass all required arguments:
>
>RewriteRule ^(.*)/(.*)/(.*)/(.*)/(.*)$
>/index.php?section=$1&page=$2&mode=$3&item=$4&action=$5
>
>The above rule correctly passes
>http://domain.com/help/test/IN/4/edit to my script as
>/index.php?section=help&page=test&mode=IN&item=4&action=edit .
>
>I tried creating 5 rules so that, if Apache saw fewer arguments, it
>would go down to the next rule but that didnt work like I thought it would:
>
>RewriteRule ^(.*)/(.*)/(.*)/(.*)/(.*)$
>/index.php?section=$1&page=$2&mode=$3&item=$4&action=$5
>RewriteRule ^(.*)/(.*)/(.*)/(.*)$
>/index.php?section=$1&page=$2&mode=$3&item=$4
>RewriteRule ^(.*)/(.*)/(.*)$ /index.php?section=$1&page=$2&mode=$3
>RewriteRule ^(.*)/(.*)$ /index.php?section=$1&page=$2
>RewriteRule ^(.*)$ /index.php?section=$1
>
>How do I write the rule(s) so that, if fewer arguments are passed,
>it will still work?
>
>Any help would be greatly appreciated.
---------------- End original message. ---------------------
OK, I will take a shot at this... though I am not very experienced
with mod_rewrite, I do know fair amount about regular expressions.
mod_rewrite documentation is here:
http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html
First off, from the documentation of mod_rewrite, the rules are
applied in order as defined so they should fall through from one to
the next if a higher one does not apply. So it seems like your scheme
should work, why it doesn't is unknown to me. I am not sure about
this but you might want to try reversing the order of your tests, do
the smallest number of arguments first.
I think you probably ought to also use the last flag on each rule too
so it does not skip to the next if it matches. (Now that I think
about it, this may well be the problem here).
One thing you probably ought to account for is that you are making a
big assumption in your RE here. That assumption is that there will
never be a trailing slash on any of the URLs, this may not be a valid
assumption. To fix that you need to make a change to each RE prior to
the end of line anchor to indicate either 0 or 1 slashes may exist.
For example:
RewriteRule ^(.*)/?$ /index.php?section=$1
This rule would match both of these:
http://domain.com/help
http://domain.com/help/
So here is how I suggest you try the rules:
RewriteRule ^(.*)/?$ /index.php?section=$1 [L]
RewriteRule ^(.*)/(.*)/?$ /index.php?section=$1&page=$2 [L]
RewriteRule ^(.*)/(.*)/(.*)/?$ /index.php?section=$1&page=$2&mode=$3 [L]
RewriteRule ^(.*)/(.*)/(.*)/(.*)/?$
/index.php?section=$1&page=$2&mode=$3&item=$4 [L]
RewriteRule ^(.*)/(.*)/(.*)/(.*)/(.*)/?$
/index.php?section=$1&page=$2&mode=$3&item=$4&action=$5 [L]
Let me know if this helps. I am curious to see if I was on the right track.
Dragon
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Venimus, Saltavimus, Bibimus (et naribus canium capti sumus)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---------------------------------------------------------------------
The official User-To-User support forum of the Apache HTTP Server Project.
See <URL:http://httpd.apache.org/userslist.html> for more info.
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
" from the digest: users-digest-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org
Re: [users@httpd] Mod RewriteRule Help : Accepting Variable Number Of Arguments
Posted by Kristopher Yates <kr...@hotmail.com>.
Hi Eric,
Changing to .+ seems to work fine. I have only one issue left. The issue
is a server error when only one argument is passed. Here is what I have
that works when more than one argument is passed:
RewriteRule ^(.+)/(.+)/(.+)/(.+)/(.+)$
/index.php?section=$1&page=$2&mode=$3&item=$4&action=$5 [L]
RewriteRule ^(.+)/(.+)/(.+)/(.+)$
/index.php?section=$1&page=$2&mode=$3&item=$4 [L]
RewriteRule ^(.+)/(.+)/(.+)$ /index.php?section=$1&page=$2&mode=$3 [L]
RewriteRule ^(.+)/(.+)$ /index.php?section=$1&page=$2 [L]
I thought that, by creating one last rule at the bottom of my list,
mod_rewrite would catch all instances of when only one argument is passed:
RewriteRule ^(.+)$ /index.php?section=$1 [L]
Adding this final rule breaks everything, resulting in ye olde 'endless
loop' error for all requests.
I found the following rule as a solution at
http://forums.searchenginewatch.com/showthread.php?t=3925 but I still get
the same problem, though the documentation I found said it should work:
RewriteRule ^([^/]+)/?$ /index.php?section=$1 [L]
Any ideas?
Thank you,
Kris
>From: "Eric Covener" <co...@gmail.com>
>Reply-To: users@httpd.apache.org
>To: users@httpd.apache.org
>Subject: Re: [users@httpd] Mod RewriteRule Help : Accepting Variable Number
>Of Arguments
>Date: Sat, 31 Mar 2007 22:16:09 -0400
>
>On 3/31/07, Kristopher Yates <kr...@hotmail.com> wrote:
>>Hi Dragon,
>>RewriteRule ^(.*)/(.*)/(.*)/(.*)/(.*)/?$
>>/index.php?section=$1&page=$2&mode=$3&item=$4&action=$5 [L]
>>
>>Parsing http://domain.com/section/page/mode/item/action/
>>
>>Results:
>>_REQUEST[section] = "section/page"
>>_REQUEST[page] = "mode"
>>_REQUEST[item] = "action"
>>_REQUEST[action] = empty
>
>All the asterisks are greedy, and the one you expect to be 'action'
>doesn't have anything left to match but the forward slash but the 0
>characters after the slash following "action". Try making the
>previous expressions non greedy, and maybe use + instead of *
>
>--
>Eric Covener
>covener@gmail.com
>
>---------------------------------------------------------------------
>The official User-To-User support forum of the Apache HTTP Server Project.
>See <URL:http://httpd.apache.org/userslist.html> for more info.
>To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
> " from the digest: users-digest-unsubscribe@httpd.apache.org
>For additional commands, e-mail: users-help@httpd.apache.org
>
_________________________________________________________________
Get a FREE Web site, company branded e-mail and more from Microsoft Office
Live! http://clk.atdmt.com/MRT/go/mcrssaub0050001411mrt/direct/01/
---------------------------------------------------------------------
The official User-To-User support forum of the Apache HTTP Server Project.
See <URL:http://httpd.apache.org/userslist.html> for more info.
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
" from the digest: users-digest-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org
Re: [users@httpd] Mod RewriteRule Help : Accepting Variable Number Of Arguments
Posted by Eric Covener <co...@gmail.com>.
On 3/31/07, Eric Covener <co...@gmail.com> wrote:
> Try making the previous expressions non greedy, and maybe use + instead of *
Sorry, as in /(.+?)/
--
Eric Covener
covener@gmail.com
---------------------------------------------------------------------
The official User-To-User support forum of the Apache HTTP Server Project.
See <URL:http://httpd.apache.org/userslist.html> for more info.
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
" from the digest: users-digest-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org
Re: [users@httpd] Mod RewriteRule Help : Accepting Variable Number Of Arguments
Posted by Eric Covener <co...@gmail.com>.
On 3/31/07, Kristopher Yates <kr...@hotmail.com> wrote:
> Hi Dragon,
> RewriteRule ^(.*)/(.*)/(.*)/(.*)/(.*)/?$
> /index.php?section=$1&page=$2&mode=$3&item=$4&action=$5 [L]
>
> Parsing http://domain.com/section/page/mode/item/action/
>
> Results:
> _REQUEST[section] = "section/page"
> _REQUEST[page] = "mode"
> _REQUEST[item] = "action"
> _REQUEST[action] = empty
All the asterisks are greedy, and the one you expect to be 'action'
doesn't have anything left to match but the forward slash but the 0
characters after the slash following "action". Try making the
previous expressions non greedy, and maybe use + instead of *
--
Eric Covener
covener@gmail.com
---------------------------------------------------------------------
The official User-To-User support forum of the Apache HTTP Server Project.
See <URL:http://httpd.apache.org/userslist.html> for more info.
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
" from the digest: users-digest-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org
Re: [users@httpd] Mod RewriteRule Help : Accepting Variable Number Of Arguments
Posted by Kristopher Yates <kr...@hotmail.com>.
Hi Dragon,
Thank you for the reply. Greatly appreciated.
Your suggestion was helpful in this learning process. Unfortunately the
result is the same error I have been getting.
mod_rewrite: maximum number of internal redirects reached. Assuming
configuration error. Use 'RewriteOptions MaxRedirects' to increase the limit
if neccessary.
It looks like it should work, but alas, no dice.
What is interesting to note is that if *ONLY* the longest rule exists, and I
pass it the expected number of arguments, it is incorrectly parsed by
mod_rewrite:
RewriteRule ^(.*)/(.*)/(.*)/(.*)/(.*)/?$
/index.php?section=$1&page=$2&mode=$3&item=$4&action=$5 [L]
Parsing http://domain.com/section/page/mode/item/action/
Results:
_REQUEST[section] = "section/page"
_REQUEST[page] = "mode"
_REQUEST[item] = "action"
_REQUEST[action] = empty
Its as if there is some bug in parsing the first argument where it passes
the first and second argument to $1.
So then I changed it so I have all five rules modified where the first
argument is staticly defined and pass it a new URL that I thought would
match. This also give unexpected results:
RewriteRule ^superuser/(.*)/?$ /index.php?section=superuser&page=$1 [L]
RewriteRule ^superuser/(.*)/(.*)/?$
/index.php?section=superuser&page=$1&mode=$2 [L]
RewriteRule ^superuser/(.*)/(.*)/(.*)/?$
/index.php?section=superuser&page=$1&mode=$2&item=$3 [L]
RewriteRule ^superuser/(.*)/(.*)/(.*)/(.*)/?$
/index.php?section=superuser&page=$1&mode=$2&item=$3&action=$4 [L]
Parsing: http://domain.com/superuser/page/mode/item/action/
It redirects section=superuser&page=page/mode/item/action/
In all cases, the second rule catches all tests.
I reverse the order of the Rewrite Rules in .htaccess, once again it resorts
to the other strange parsing:
RewriteRule ^superuser/(.*)/(.*)/(.*)/(.*)/?$
/index.php?section=superuser&page=$1&mode=$2&item=$3&action=$4 [L]
RewriteRule ^superuser/(.*)/(.*)/(.*)/?$
/index.php?section=superuser&page=$1&mode=$2&item=$3 [L]
RewriteRule ^superuser/(.*)/(.*)/?$
/index.php?section=superuser&page=$1&mode=$2 [L]
RewriteRule ^superuser/(.*)/?$ /index.php?section=superuser&page=$1 [L]
Parsing http://domain.com/superuser/page/mode/item/action/
results in redirecting to
section=superuser&page=page/mode&mode=item&item=action&action=empty
where it mis-parses the first argument and passes what I consider $1 and $2
together as $1, leaving the last item blank.
Seems like a bug to me but don't quote me on that. I have been around and
not a 'noob' but then again I am no mod_rewrite/Apache module guru. I
wonder if the last /? in the rule is causing that.
THE GOOD NEWS
I get closest to working with the following rules in this order.
RewriteRule ^superuser/(.*)/(.*)/(.*)/(.*)/?$
/index.php?section=superuser&page=$1&mode=$2&item=$3&action=$4 [L]
RewriteRule ^superuser/(.*)/(.*)/(.*)/?$
/index.php?section=superuser&page=$1&mode=$2&item=$3 [L]
RewriteRule ^superuser/(.*)/(.*)/?$
/index.php?section=superuser&page=$1&mode=$2 [L]
RewriteRule ^superuser/(.*)/?$ /index.php?section=superuser&page=$1 [L]
Though http://domain.com/superuser/page/mode/item/action/ gets misdirected,
If I take off the trailing slash, the rule works as expected. Also, the
shorter rules work when I start deleting things from the end of the URL
request regardless of the trailing /. To surmise:
http://domain.com/superuser/page/mode/item/action/ gets misdirected
http://domain.com/superuser/page/mode/item/action works
http://domain.com/superuser/page/mode/item/ works
http://domain.com/superuser/page/mode/item works
http://domain.com/superuser/page/mode/ works
http://domain.com/superuser/page/mode works
http://domain.com/superuser/page/ works
http://domain.com/superuser/page works
For the record, My Apache is Apache/1.3.37 (Unix) mod_fastcgi/2.4.2
mod_perl/1.29 PHP/5.2.1
My initial config when I set Apache was a no-frills DSO:
./configure --prefix=/usr/local/apache --enable-module=so
Final note, it seems taking /? out of the rules seems to make no difference,
as rules function the same when it is removed.
Any ideas?
Thanks for your time,
Kris
>From: Dragon <dr...@crimson-dragon.com>
>Reply-To: users@httpd.apache.org
>To: users@httpd.apache.org
>Subject: Re: [users@httpd] Mod RewriteRule Help : Accepting Variable
>Number Of Arguments
>Date: Sat, 31 Mar 2007 09:56:41 -0700
>
>Kristopher Yates did speak thusly:
>>Hello,
>>
>>Here is an example URL I'm trying to create a RewriteRule for:
>>
>>index.php?section=help&page=test&mode=IN&item=4&action=edit
>>
>>I have a rule that works when the request URL contains the appropriate
>>number of arguments but does not work when there are fewer arguments than
>>the Rule expects. I thought by creating multiple (similar) rules would
>>resolve but no luck. Here is what I have that works as long as I pass all
>>required arguments:
>>
>>RewriteRule ^(.*)/(.*)/(.*)/(.*)/(.*)$
>>/index.php?section=$1&page=$2&mode=$3&item=$4&action=$5
>>
>>The above rule correctly passes http://domain.com/help/test/IN/4/edit to
>>my script as /index.php?section=help&page=test&mode=IN&item=4&action=edit
>>.
>>
>>I tried creating 5 rules so that, if Apache saw fewer arguments, it would
>>go down to the next rule but that didnt work like I thought it would:
>>
>>RewriteRule ^(.*)/(.*)/(.*)/(.*)/(.*)$
>>/index.php?section=$1&page=$2&mode=$3&item=$4&action=$5
>>RewriteRule ^(.*)/(.*)/(.*)/(.*)$
>>/index.php?section=$1&page=$2&mode=$3&item=$4
>>RewriteRule ^(.*)/(.*)/(.*)$ /index.php?section=$1&page=$2&mode=$3
>>RewriteRule ^(.*)/(.*)$ /index.php?section=$1&page=$2
>>RewriteRule ^(.*)$ /index.php?section=$1
>>
>>How do I write the rule(s) so that, if fewer arguments are passed, it will
>>still work?
>>
>>Any help would be greatly appreciated.
>---------------- End original message. ---------------------
>
>OK, I will take a shot at this... though I am not very experienced with
>mod_rewrite, I do know fair amount about regular expressions.
>
>mod_rewrite documentation is here:
>http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html
>
>First off, from the documentation of mod_rewrite, the rules are applied in
>order as defined so they should fall through from one to the next if a
>higher one does not apply. So it seems like your scheme should work, why it
>doesn't is unknown to me. I am not sure about this but you might want to
>try reversing the order of your tests, do the smallest number of arguments
>first.
>
>I think you probably ought to also use the last flag on each rule too so it
>does not skip to the next if it matches. (Now that I think about it, this
>may well be the problem here).
>
>One thing you probably ought to account for is that you are making a big
>assumption in your RE here. That assumption is that there will never be a
>trailing slash on any of the URLs, this may not be a valid assumption. To
>fix that you need to make a change to each RE prior to the end of line
>anchor to indicate either 0 or 1 slashes may exist. For example:
>
> RewriteRule ^(.*)/?$ /index.php?section=$1
>
>This rule would match both of these:
> http://domain.com/help
> http://domain.com/help/
>
>So here is how I suggest you try the rules:
>
>RewriteRule ^(.*)/?$ /index.php?section=$1 [L]
>RewriteRule ^(.*)/(.*)/?$ /index.php?section=$1&page=$2 [L]
>RewriteRule ^(.*)/(.*)/(.*)/?$ /index.php?section=$1&page=$2&mode=$3 [L]
>RewriteRule ^(.*)/(.*)/(.*)/(.*)/?$
>/index.php?section=$1&page=$2&mode=$3&item=$4 [L]
>RewriteRule ^(.*)/(.*)/(.*)/(.*)/(.*)/?$
>/index.php?section=$1&page=$2&mode=$3&item=$4&action=$5 [L]
>
>
>Let me know if this helps. I am curious to see if I was on the right track.
>
>
>Dragon
>
>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> Venimus, Saltavimus, Bibimus (et naribus canium capti sumus)
>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
>
>---------------------------------------------------------------------
>The official User-To-User support forum of the Apache HTTP Server Project.
>See <URL:http://httpd.apache.org/userslist.html> for more info.
>To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
> " from the digest: users-digest-unsubscribe@httpd.apache.org
>For additional commands, e-mail: users-help@httpd.apache.org
>
_________________________________________________________________
Watch free concerts with Pink, Rod Stewart, Oasis and more. Visit MSN
Presents today.
http://music.msn.com/presents?icid=ncmsnpresentstagline&ocid=T002MSN03A07001
---------------------------------------------------------------------
The official User-To-User support forum of the Apache HTTP Server Project.
See <URL:http://httpd.apache.org/userslist.html> for more info.
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
" from the digest: users-digest-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org