Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

<If> statement breaks Rewrite* rules

I'm using standard wordpress htaccess rules with Apache/2.4.34. If I add <If> statement it brakes rewrites.

# DEBUG is set to TRUE
<If "-T env('DEBUG')">
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]

# add a trailing slash to /wp-admin
RewriteRule ^wp-admin$ wp-admin/ [R=301,L]

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^(wp-(content|admin|includes).*) $1 [L]
RewriteRule ^(.*\.php)$ $1 [L]
RewriteRule . index.php [L]
</If>

All pages except / returns: Bad Request Your browser sent a request that this server could not understand.

blog.local 172.20.0.1 - - [30/Sep/2018:17:07:58 +0000] "GET /2018/09/19/popular/ HTTP/1.1" 400 226 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36"
[Sun Sep 30 17:07:58.202467 2018] [rewrite:trace3] [pid 7:tid 140686203255528] mod_rewrite.c(482): [client 172.20.0.1:56856] 172.20.0.1 - - [blog.local/sid#55cd2e1aec50][rid#55cd2e246a80/initial] [perdir *If/] add path info postfix: /var/www/html/web/2018 -> /var/www/html/web/2018/09/19/popular/
[Sun Sep 30 17:07:58.202511 2018] [rewrite:trace3] [pid 7:tid 140686203255528] mod_rewrite.c(482): [client 172.20.0.1:56856] 172.20.0.1 - - [blog.local/sid#55cd2e1aec50][rid#55cd2e246a80/initial] [perdir *If/] applying pattern '^index\\.php$' to uri '/var/www/html/web/2018/09/19/popular/'
[Sun Sep 30 17:07:58.202529 2018] [rewrite:trace3] [pid 7:tid 140686203255528] mod_rewrite.c(482): [client 172.20.0.1:56856] 172.20.0.1 - - [blog.local/sid#55cd2e1aec50][rid#55cd2e246a80/initial] [perdir *If/] add path info postfix: /var/www/html/web/2018 -> /var/www/html/web/2018/09/19/popular/
[Sun Sep 30 17:07:58.202543 2018] [rewrite:trace3] [pid 7:tid 140686203255528] mod_rewrite.c(482): [client 172.20.0.1:56856] 172.20.0.1 - - [blog.local/sid#55cd2e1aec50][rid#55cd2e246a80/initial] [perdir *If/] applying pattern '^wp-admin$' to uri '/var/www/html/web/2018/09/19/popular/'
[Sun Sep 30 17:07:58.202557 2018] [rewrite:trace3] [pid 7:tid 140686203255528] mod_rewrite.c(482): [client 172.20.0.1:56856] 172.20.0.1 - - [blog.local/sid#55cd2e1aec50][rid#55cd2e246a80/initial] [perdir *If/] add path info postfix: /var/www/html/web/2018 -> /var/www/html/web/2018/09/19/popular/
[Sun Sep 30 17:07:58.202570 2018] [rewrite:trace3] [pid 7:tid 140686203255528] mod_rewrite.c(482): [client 172.20.0.1:56856] 172.20.0.1 - - [blog.local/sid#55cd2e1aec50][rid#55cd2e246a80/initial] [perdir *If/] applying pattern '^' to uri '/var/www/html/web/2018/09/19/popular/'
[Sun Sep 30 17:07:58.202619 2018] [rewrite:trace4] [pid 7:tid 140686203255528] mod_rewrite.c(482): [client 172.20.0.1:56856] 172.20.0.1 - - [blog.local/sid#55cd2e1aec50][rid#55cd2e246a80/initial] [perdir *If/] RewriteCond: input='/var/www/html/web/2018' pattern='-f' => not-matched
[Sun Sep 30 17:07:58.202638 2018] [rewrite:trace4] [pid 7:tid 140686203255528] mod_rewrite.c(482): [client 172.20.0.1:56856] 172.20.0.1 - - [blog.local/sid#55cd2e1aec50][rid#55cd2e246a80/initial] [perdir *If/] RewriteCond: input='/var/www/html/web/2018' pattern='-d' => not-matched
[Sun Sep 30 17:07:58.202653 2018] [rewrite:trace3] [pid 7:tid 140686203255528] mod_rewrite.c(482): [client 172.20.0.1:56856] 172.20.0.1 - - [blog.local/sid#55cd2e1aec50][rid#55cd2e246a80/initial] [perdir *If/] add path info postfix: /var/www/html/web/2018 -> /var/www/html/web/2018/09/19/popular/
[Sun Sep 30 17:07:58.202666 2018] [rewrite:trace3] [pid 7:tid 140686203255528] mod_rewrite.c(482): [client 172.20.0.1:56856] 172.20.0.1 - - [blog.local/sid#55cd2e1aec50][rid#55cd2e246a80/initial] [perdir *If/] applying pattern '.' to uri '/var/www/html/web/2018/09/19/popular/'
[Sun Sep 30 17:07:58.202681 2018] [rewrite:trace2] [pid 7:tid 140686203255528] mod_rewrite.c(482): [client 172.20.0.1:56856] 172.20.0.1 - - [blog.local/sid#55cd2e1aec50][rid#55cd2e246a80/initial] [perdir *If/] rewrite '/var/www/html/web/2018/09/19/popular/' -> 'index.php'
[Sun Sep 30 17:07:58.202693 2018] [rewrite:trace3] [pid 7:tid 140686203255528] mod_rewrite.c(482): [client 172.20.0.1:56856] 172.20.0.1 - - [blog.local/sid#55cd2e1aec50][rid#55cd2e246a80/initial] [perdir *If/] add per-dir prefix: index.php -> *If/index.php

The last message is completely strange: add per-dir prefix: index.php -> *If/index.php

What's going wrong?

like image 264
mahnunchik Avatar asked Sep 30 '18 17:09

mahnunchik


1 Answers

I got a similar case with these htaccessrules:

<If "%{REQUEST_URI} =~ m#^/resources/data/character/[0-9]{1,10}/(avatar|refsheet)\.png$#">
    # ... Other stuff here ...
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ resources/generic/default-refsheet.png
</If>

In such conditions, the request is rewritten to the relative path resources/generic/default-refsheet.png when originally requested file does not exist (and when it matches the regex in the <If>), leading to the dumb *If/ prefix being added.

It seems the directory prefix *If/ used by Apache is a pleaceholder, as the content of <If> is always applied first, before the actual directory prefix could be computed.

In such case, I found no way to keep the rewritten URL relative, so I used an "absolute" (absolute is in quotes because it's actually still relative to the DocumentRoot of the virtual host, but not relative to the where htaccess is). Hence changing it the rule to /resources/generic/default-refsheet.png (note the / at first place):

<If "%{REQUEST_URI} =~ m#^/resources/data/character/[0-9]{1,10}/(avatar|refsheet)\.png$#">
    # ...
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ /resources/generic/default-refsheet.png
</If>

In such case, the rewritten URL is not prefixed with the dumb *If/ dir prefix.

So for your issue, I would try puttin a / (or a /path/to/wordpress/from/document_root/) in front of every rewritten rule:

# DEBUG is set to TRUE
<If "-T env('DEBUG')">
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]

# add a trailing slash to /wp-admin
RewriteRule ^wp-admin$ /wp-admin/ [R=301,L]

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^(wp-(content|admin|includes).*) /$1 [L]
RewriteRule ^(.*\.php)$ /$1 [L]
RewriteRule . /index.php [L]
</If>

Still, I'm not 100% sure about whether it will work, nor about why it would work (hence the original bounty I placed)...

like image 68
Xenos Avatar answered Oct 28 '22 23:10

Xenos