[solved] [makeshift] Apache mod rewrite incompatibility

NiteWave

Administrator
#2
RewriteCond %{ENV:REDIRECT_STATUS} ^$
I'm not test yet, but likely litepeed won't set this environment variable(i.e.,"REDIRECT_STATUS") automatically.

to prevent multiple or recursive rewrite rule.
this is the ultimate goal. I think litespeed is doing better(higher performance and less confusing) in this regards by my experience.

can you give an example rewriterule, which you want it behavior as expected ?
 
#3
Test case

Actually I haven't test this yet.
(for now I'm working on apache server.)

However, this is a simple test case that I come up with.

When I want to allow only specific URI to pass to php script
but block everything else.

So I write it as

Code:
RewriteEngine On

RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{THE_REQUEST} ^(?:post|get)\ /genkey/[0-9a-f]{32}\  [NC]
RewriteRule .* /keygenerator.php [L]

RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule .* /restricted.php [L]
since
RewriteCond %{ENV:REDIRECT_STATUS} ^$
not work
and no other RewriteCond on
RewriteRule .* /restricted.php [L]

when
RewriteRule .* /keygenerator.php
executed
it also execute
RewriteRule .* /restricted.php

and when
RewriteRule .* /restricted.php
executed
It go recursive loop with the rule itself.

note: I haven't actually test this but I had some rewrite module test (When I found this problem during set up my software on LSWS.)
 

NiteWave

Administrator
#4
I did following tests with lsws, it's working as expected:
Code:
RewriteEngine On

RewriteCond %{THE_REQUEST} ^(?:post|get)\ /genkey/[0-9a-f]{32} [NC]
RewriteRule .* /keygenerator.php [L]

RewriteRule .* /restricted.php [L]
no recursive loop. and no need ENV:REDIRECT_STATUS

PHP:
/usr/local/lsws/DEFAULT/html>cat keygenerator.php 
<?php

echo "this is keygenerator.php<br>"; 
echo "\$_SERVER[\"REQUEST_URI\"]=" . $_SERVER["REQUEST_URI"];

?>
/usr/local/lsws/DEFAULT/html>cat restricted.php 
<?php

echo "this is restricted.php<br>"; 
echo "\$_SERVER[\"REQUEST_URI\"]=" . $_SERVER["REQUEST_URI"];

?>
in browser, 192.168.2.101/genkey/01234567890abcdef01234567890abcdef
result:
this is keygenerator.php
$_SERVER["REQUEST_URI"]=/genkey/01234567890abcdef01234567890abcdef
192.168.2.101/p.php?h=1
result:
this is restricted.php
$_SERVER["REQUEST_URI"]=/p.php?h=1
 
#5
Actual test case

Sorry
my bad

Now I remembered the situation.

I have directory say "abc" in document root
Normally if I leave it handle by web server
visitor can access it with
http://www.example.com/abc/...

but I don't want that
this is what I want
http://www.example.com/!/...

Basically I can just rename directory "abc" to "!" but
I have good reason to leave it as "abc" in back-end.

thus I use rewrite module to handle this


first I just rewrite /!/ to /abc/ which pretty simple
Code:
<IfModule rewrite_module>
RewriteEngine On
RewriteRule ^(\/?)\!\/(.*) $1abc/$2 [L]
</IfModule>
Now for security reason I don't want anyone access that content via
http://www.example.com/abc/...
then I add some more rewrite rule to make some kind of null route from that URI
this is when things mess up
Code:
<IfModule rewrite_module>
RewriteEngine On

RewriteCond %{REQUEST_URI} ^\/abc\/.* [NC]
RewriteRule .* /null.txt [L]

RewriteRule ^(\/?)\!\/(.*) $1abc/$2 [L]

</IfModule>
The combination of 2 rewrite rules is not what I expect

LSWS behave like this:
- when people access
http://www.example.com/abc/...
it drop the request with some dummy file which is correct as my expectation.
- when people access
http://www.example.com/!/...
it also redirect to the dummy file.

this code is same for Apache.

However in Apache
I just put
RewriteCond %{ENV:REDIRECT_STATUS} ^$
on each rule
but as you know I can't do that on LSWS.

Now I have to handle the request with PHP or other server side script which is heavyweight and not a good solution.

Probably it may have some other solution but I can't think of good one.
 

NiteWave

Administrator
#6
tested, following rewrite rules meet your requirement:
RewriteCond %{ORG_REQ_URI} ^/abc/ [NC]
RewriteRule .* /null.txt [L,S=1]

RewriteRule ^!/(.*) /abc/$1 [L]
maybe there is other work around, but in above example, have introduced litespeed's special %{ORG_REQ_URI} which differ with %{REQUEST_URI} in that it's the original request URI --- do not change during rewrite process.

and with %{ORG_REQ_URI}, no need ENV:REDIRECT_STATUS
 
#7
Wow
There are very few information about it on the internet.

So the equivalent would be
Code:
RewriteCond %{REQUEST_URI} =%{ORG_REQ_URI}
(I guess)

Now I can solve my problem.
However, still the fact that it incompatibility with apache rewrite module.

Thus Litespeed is not completely Apache interchangeable since users have to tweak something when working with Litespeed.

Anyway, thank you for now.
 

NiteWave

Administrator
#8
it looks like %(ENV:REDIRECT_STATUS} in rewriterule is an undocumented feature in apache. if so, not recommend to use it.

http://httpd.apache.org/docs/current/mod/mod_rewrite.html
apache 2.3.9, introduced a new rewrite flag "END"
Stop the rewriting process immediately and don't apply any more rules. Also prevents further execution of rewrite rules in per-directory and .htaccess context. (Available in 2.3.9 and later)
looks it acts exactly as litespeed's "LAST" or "L" flag.
 
#9
No

No
It is documented in current release of Apache HTTP Server.

REDIRECT_ environment variables are created from the environment variables which existed prior to the redirect. They are renamed with a REDIRECT_ prefix, i.e., HTTP_USER_AGENT becomes REDIRECT_HTTP_USER_AGENT.

REDIRECT_URL, REDIRECT_STATUS, and REDIRECT_QUERY_STRING are guaranteed to be set, and the other headers will be set only if they existed prior to the error condition.
here
_http://httpd.apache.org/docs/current/custom-error.html

However, it not very well document related to rewrite module.
 
Last edited:
Top