szepeviktor / w3-total-cache-fixed

A community driven build of W3 Total Cache. The aim is to continuously incorporate fixes, improvements, and enhancements over the official WordPress release of W3 Total Cache.
https://github.com/szepeviktor/w3-total-cache-fixed/releases
MIT License
237 stars 47 forks source link

minify rewrite bug #417

Open hsntgm opened 7 years ago

hsntgm commented 7 years ago

Hello,

php 7.1.2, apache 2.4.15, fcgid

"Request exceeded the limit of 10 subrequest nesting levels due to probable confguration error. Use 'LimitInternalRecursion' to increase the limit if necessary. "

Maybe i am wrong but i think this issue comes from w3 total cache while trying to rewrite minified files.

You can check rewrite trace level 2 output below. What i understand this is also cause performance degradation.

After 10 subrequest w3 rewrite minified files.

minify bug

Default wp .htaccess;

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

Changed with NS flag (nosubreq)

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [NS,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [NS,L]
</IfModule>

Problem still exist. Best Regards,

nigrosimone commented 7 years ago

Default wp .htaccess isn't the right place.

w3tc manage their minify rewrite rules in \wp-content\cache\minify\.htaccess

# BEGIN W3TC Minify core
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /wp-content/cache/minify/
    RewriteCond %{HTTP:Accept-Encoding} gzip
    RewriteRule .* - [E=APPEND_EXT:.gzip]
    RewriteCond %{REQUEST_FILENAME}%{ENV:APPEND_EXT} -f
    RewriteRule (.*) $1%{ENV:APPEND_EXT} [L]

    RewriteRule ^(.+\.(css|js))$ /index.php [L]
</IfModule>
# END W3TC Minify core

re-try your fix on this place... but w3tc already do that: w3tc add gzip extension and rewrite the url only if the gzipped's file exists (-f):

# if the browser support gzip encoding, set the APPEND_EXT variable with "gzip"
RewriteCond %{HTTP:Accept-Encoding} gzip
RewriteRule .* - [E=APPEND_EXT:.gzip]

# if the REQUEST_FILENAME eg foo.js with APPEND_EXT eg foo.js.gzip exists, rewrite the request on it
RewriteCond %{REQUEST_FILENAME}%{ENV:APPEND_EXT} -f
RewriteRule (.*) $1%{ENV:APPEND_EXT} [L]

now, it seem the same issue as https://github.com/szepeviktor/w3-total-cache-fixed/pull/289

this issue generally happen when MultiViews is enabled or mod_negotiation is disabled in your Apache *.conf, therefore check if:

  1. is mod_negotiation loaded? eg.: LoadModule negotiation_module modules/mod_negotiation.so
  2. is MultiViews disabled? eg.: Options -MultiViews

but, latest w3tc already disable MultiViews if mod_negotiation is loaded in \wp-content\cache\minify\.htaccess:

# if mod_negotiation is loaded
<IfModule mod_negotiation.c>
    # disable MultiViews
    Options -MultiViews
</IfModule>

therefore, if you have latest w3tc you need to check only if mod_negotiation is loaded

Side note: i suppose you use 0.9.5.x generation on Apache

Always thanks.

hsntgm commented 7 years ago

Hello @nigrosimone

I wish i check your edited comment again. I lost one hour to find problem is Options -MultiView :). I spent the next one hour why it doesn't work on .htaccess level.

Yes you are right w3tc adds Options -MultiViews but this isn't work at .htaccess level . First, I had to manually disabled MultiViews at vhost level. Second, i carried rewrite rules to vhost level. This configuration works without extra subreqs.

vhost

But .htaccess level problem is still exist. When i carry rewrite rules from vhost to .htaccess w3 still working with extra subreqs.

I am working on it. Sincerely,

Not:mod_negotiation is also loaded and i am on 0.9.5.x generation

nigrosimone commented 7 years ago

But .htaccess level problem is still exist. When i carry rewrite rules from vhost to .htaccess w3 still working

mhh, two question:

  1. have you at host level Require all granted and AllowOverride All ?

    <Directory /wordpress> AllowOverride All Require all granted

  2. is mod_negotiation.so loaded?

hsntgm commented 7 years ago

Yes, you can check it attached image in my previous post.

nigrosimone commented 7 years ago

right...

other two question

  1. is mod_rewrite.so loaded?

  2. in /wp-content/cache/minify/.htaccess RewriteBase is the right path?

# BEGIN W3TC Minify core
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /wp-content/cache/minify/

i think your server not handle .htaccess

hsntgm commented 7 years ago

path

path2

also mod_rewrite loaded..

nigrosimone commented 7 years ago

i think your web server don't handle .htaccess Try to put a wrong code into .htaccess in a test directory, eg

in _/my_testfolder/.htaccess insert:

THIS DON'T COMPILE!!!  AND CAUSE  500 INTERNAL SERVER ERROR
(IF APACHE HANDLE THE HTACCESS)

in _/my_testfolder/index.html insert:

 .htaccess doesn't works!

now in the browser open

http://mywebsite.com/my_test_folder/index.html

if you see " .htaccess doesn't works!" the web server don't handle .htaccess

hsntgm commented 7 years ago

@nigrosimone if my server doesn't handle .htaccess i think my wp pretty links don't work too? I think there is no issue at that point.

Also tried your solution wrong htaccess files give me 500 internal server error. Also as expected true one forbidden.

nigrosimone commented 7 years ago

i think my wp pretty links don't work too?

nope, my suspect is your server handle only the htaccess on the root directory and ignore htaccess on the sub-directory, but from the test isn't your case.

now, your webserver handle all htaccess and the same rule works when you copy them in the vhost level, maybe, isn't a w3tc issue.

nigrosimone commented 7 years ago

same issue:

https://wordpress.org/support/topic/request-exceeded-the-limit-of-10-subrequest-nesting-levels-due-to-probable/

http://stackoverflow.com/questions/39740737/error-caused-by-htaccess-wrong-rule-ah00125-request-exceeded-the-limit-of-10

https://wordpress.org/support/topic/request-exceeded-the-limit-of-10/

nigrosimone commented 7 years ago

@hsntgm this issue makes me crazy... i can't reproduce it... but i think something it's wrong in the w3tc multiview handling. I'm reading this useful guide about content negotiation https://kevinlocke.name/bits/2016/01/20/serving-pre-compressed-files-with-apache-multiviews/ and it suggest to use Options +MultiViews instead of Options -MultiViews. Any news on this issue?

hsntgm commented 7 years ago

@nigrosimone I gave up after you closed the issue. What i remember the last thing is i was suspecting something like re-write/directory issue. Get rid of the .htaccess in the subfolder if it is possible with plugin structer and carry it to main root .htaccess. If not possible maybe this can be a good attempt to solve it.

And what i remember is ;

This code not trigger. Maybe in sub-folder !? Paste it to main root .htaccess.

# BEGIN W3TC Minify cache
<IfModule mod_negotiation.c>
    Options -MultiViews
</IfModule>
# END W3TC Minify cache

** Then try if it is working this code now !?

# BEGIN W3TC Minify cache
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /wp-content/cache/minify/
    RewriteCond %{HTTP:Accept-Encoding} gzip
    RewriteRule .* - [E=APPEND_EXT:.gzip]
    RewriteCond %{REQUEST_FILENAME}%{ENV:APPEND_EXT} -f
    RewriteRule (.*) $1%{ENV:APPEND_EXT} [L]
    RewriteRule ^(.+\.(css|js))$ /index.php [L]
</IfModule>
# END W3TC Minify core

If still it has subrequest nesting, give a chance it in subfolder with that re-write structer maybe.

# BEGIN W3TC Minify cache
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
    Options -MultiViews
</IfModule>
    RewriteEngine On
    RewriteBase /home/domain/public_html/wp-content/cache/minify/
    RewriteCond %{HTTP:Accept-Encoding} gzip
    RewriteRule .* - [E=APPEND_EXT:.gzip]
    RewriteCond %{REQUEST_FILENAME}%{ENV:APPEND_EXT} -f
    RewriteRule (.*) $1%{ENV:APPEND_EXT} [L]
    RewriteRule ^(.+\.(css|js))$ /index.php [L]
</IfModule>
# END W3TC Minify core

I completly changed my production env. to nginx so i am not able to test these rules now. If i make a time to build test vps i will inform you.

Sincerely,

adbario commented 7 years ago

Having the same issue here. Turning off "Rewrite URL structure" fixes this and also this code from previous comment works:

# BEGIN W3TC Minify cache
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /wp-content/cache/minify/
    RewriteCond %{HTTP:Accept-Encoding} gzip
    RewriteRule .* - [E=APPEND_EXT:.gzip]
    RewriteCond %{REQUEST_FILENAME}%{ENV:APPEND_EXT} -f
    RewriteRule (.*) $1%{ENV:APPEND_EXT} [L]
    RewriteRule ^(.+\.(css|js))$ /index.php [L]
</IfModule>
# END W3TC Minify core

This issue surely should have a permanent solution.

adbario commented 7 years ago

Actually, my issue was found somewhere else. For some reason we had the "Optimize disk enhanced page and minify disk caching for NFS" turned on and because of that \wp-content\cache\minify\.htaccess had -F at the end of RewriteCond instead of -f.

After turning off disk caching for NFS everything works perfectly (as we don't use network drives).