Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 581
  • Last Modified:

mod_rewrite: Meaning of [OR] in RewriteCond

How is the following rewrite rule interpreted by apache?

RewriteCond      A
RewriteCond      B      [OR]
RewriteCond      C
RewriteRule       X

Is it:

    (A and B) or C
    A and (B or C)
    A or B or C

or something else altogether?  How about for more complex rules.  I have not found any info on the web.
0
FartingUncle
Asked:
FartingUncle
  • 4
  • 4
  • 2
  • +1
2 Solutions
 
HackneyCabCommented:
According to this site:

    http://abates.tetrap.com/archives/2006/05/08/optimising_mod_rewrite_part_1.html

the [OR] operator has a higher precedence than the default (silent) AND operator.

So your example above should be equivalent to

A AND (B OR C)

But you'd have to test that, because you're right: there seems to be nothing on Apache's on mod_rewrite page about precedence.
0
 
periwinkleCommented:
It would be:

A and (B or C)
0
 
periwinkleCommented:
we must have been posting at the same time. B or C wouldn't be encountered unless A happened, so A must be resolved first.  If A, then it looks at B  OR C.
0
NEW Veeam Backup for Microsoft Office 365 1.5

With Office 365, it’s your data and your responsibility to protect it. NEW Veeam Backup for Microsoft Office 365 eliminates the risk of losing access to your Office 365 data.

 
ravenplCommented:
[OR] means ornext, therefore
A and (B or C)
0
 
FartingUncleAuthor Commented:
OK - so what about a slightly more complex example?

RewriteCond     A
RewriteCond     B     [OR]
RewriteCond     C
RewriteCond     D
RewriteRule      X


From what you say, I would guess that that would give:

A and (B or C) and D

Is that right?

Is there an easy way to test?   I don't have root access so I can't change the debug level, and I found it hard to tell what was happening just by the result, which is why I posted here.
0
 
ravenplCommented:
Yes, it's right.
Set some conditions on QUERY_STRING, then test...
0
 
ravenplCommented:
like
RewriteCond %{QUERY_STRING} var1
RewriteCond %{QUERY_STRING} var2 [OR]
RewriteCond %{QUERY_STRING} var3
RewriteCond %{QUERY_STRING} var4
RewriteRule .* /very_well.html

then enter various URLs in Your browser like
http://your.host.tld/original.html?var1=1&var3=1&var4=1
0
 
ravenplCommented:
Of course upload two html's (static pages)
very_well.html
original.html
and verify which one is displayed in browser
0
 
FartingUncleAuthor Commented:
I found an interesting hint at http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html#InternalRuleset, which I hadn't noticed previously.  It doesn't offer quite enough information but it backs up what you've been saying and gives a little more detail about the inner workings of the process.

Am currently testing using the example suggested by ravenpl.  I will post my findings and award points when done.

This is the code I am using to test (with variants to the middle lines):

RewriteCond %{REQUEST_URI}       !^/?rewritten\.php$
RewriteCond %{QUERY_STRING} a
RewriteCond %{QUERY_STRING} b [OR]
RewriteCond %{QUERY_STRING} c
RewriteCond %{QUERY_STRING} d
RewriteRule .* /rewritten.php [L]

I then call /unchanged.php?abcd, where abcd is replaced by the letters I want to test for.

Note that despite using the [L] parameter, this (as the only rule) causes an infinite redirect, so I had to add the first condition to stop this.  Not sure why that's going on there...

Will get back to you with my findings.
0
 
FartingUncleAuthor Commented:
OK - that didn't take long.  It looks like everything functions as expected.  The processor starts at the top and works through the conditions until it finds one that fails (in which case the rule is skipped) or reaches the end (in which case the substitution takes place).

Groups of [OR]ed lines are evaluated as a single entity, with lines that are not part of the [OR] treated as separate statements ANDed together.

For example:

RewriteCond %{QUERY_STRING} a
RewriteCond %{QUERY_STRING} b [OR]
RewriteCond %{QUERY_STRING} c
RewriteCond %{QUERY_STRING} d [OR]
RewriteCond %{QUERY_STRING} e [OR]
RewriteCond %{QUERY_STRING} f

yields:

a AND (b OR c) AND (d OR e OR f)
0
 
FartingUncleAuthor Commented:
I gave HackneyCab 25 points and the accept for being the first of the bat with the correct answer and a very useful link.  I gave 50 points to ravenpl for good advice in helping me answer the question in the general sense, which was the second and more tricky part of my question.

Thanks for all your help.  I hope this question gets indexed well enough for other people to find!
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 4
  • 4
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now