• Hey,
    When I switch on Gzip compression and (manual) Minify, the first visit to my site after an “empty cache” shows a broken page without JS/CSS. Chrome throws a bunch of net::ERR_CONNECTION_REFUSED; Firefox silently fails decoding (you can see that bytes were transferred in the Network Panel, but the response is empty).
    This doesn’t happened when I switch off Gzip compression.

    Further inspection with curl shows that on the first visit there is an extra byte, a new line at the beginning of the gzipped content. The length is actually the same, seems like the last byte is trimmed off (or not transferred as Content-length is the same).

    I’m on WordPress 4.5.3; W3TC version 0.9.4.1.
    The error occurs on two different hosts (OSX and Debian), running different Apaches.

    Let me know if I can provide any more info/configs.

    I would appreciate – well, a fix, obviously ?? – but any pointers on where else to look.

    Thanks!

    https://www.ads-software.com/plugins/w3-total-cache/

Viewing 9 replies - 1 through 9 (of 9 total)
  • Ashok

    (@bappidgreat)

    Hello jkbk

    Would you please post your htaccess here? And could you recall if you installed wordpress using any one-click installer or installed manually?

    Have a good day!

    Cheers
    Ash

    Thread Starter jkbk

    (@jkbk)

    hey ash, thanks for the quick response.
    it’s not any one-click installer. iirc, i downloaded WP 4.5.2 and it updated itself once.
    here’s the .htaccess:


    # BEGIN W3TC Browser Cache
    <IfModule mod_deflate.c>
    <IfModule mod_headers.c>
    Header append Vary User-Agent env=!dont-vary
    </IfModule>
    <IfModule mod_filter.c>
    AddOutputFilterByType DEFLATE text/html text/richtext image/svg+xml text/plain text/xsd text/xsl text/xml image/x-icon application/json
    <IfModule mod_mime.c>
    # DEFLATE by extension
    AddOutputFilter DEFLATE js css htm html xml
    </IfModule>
    </IfModule>
    </IfModule>
    # END W3TC Browser Cache
    # BEGIN W3TC Page Cache core
    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteCond %{HTTP:Accept-Encoding} gzip
    RewriteRule .* - [E=W3TC_ENC:_gzip]
    RewriteCond %{HTTP_COOKIE} w3tc_preview [NC]
    RewriteRule .* - [E=W3TC_PREVIEW:_preview]
    RewriteCond %{REQUEST_METHOD} !=POST
    RewriteCond %{QUERY_STRING} =""
    RewriteCond %{REQUEST_URI} \/$
    RewriteCond %{HTTP_COOKIE} !(comment_author|wp\-postpass|w3tc_logged_out|wordpress_logged_in|wptouch_switch_toggle) [NC]
    RewriteCond "%{DOCUMENT_ROOT}/wp-content/cache/page_enhanced/%{HTTP_HOST}/%{REQUEST_URI}/_index%{ENV:W3TC_PREVIEW}.html%{ENV:W3TC_ENC}" -f
    RewriteRule .* "/wp-content/cache/page_enhanced/%{HTTP_HOST}/%{REQUEST_URI}/_index%{ENV:W3TC_PREVIEW}.html%{ENV:W3TC_ENC}" [L]
    </IfModule>
    # END W3TC Page Cache core
    # BEGIN WordPress
    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteRule ^index\.php$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]
    </IfModule>

    # END WordPress

    Quick question regarding this is it possible your server has GZIP enabled through another manner? For instance, CPANEL has its own tools to enabling GZIP under its “optimize website” option. Try and see what happens if you add the GZIP rules yourself?

    Thread Starter jkbk

    (@jkbk)

    Well, one server actually does have GZIP enabled (though there is no switch in the configuration tool); the other (a vanilla XAMPP) doesn’t. I checked both the conf files and did some curl’ing.
    Here’s what phpinfo() says:


    Apache Version Apache/2.4.18 (Unix) OpenSSL/1.0.2g PHP/5.6.20 mod_perl/2.0.8-dev Perl/v5.16.3

    Loaded Modules core mod_so http_core prefork mod_authn_file mod_authn_dbm mod_authn_anon mod_authn_dbd mod_authn_socache mod_authn_core mod_authz_host mod_authz_groupfile mod_authz_user mod_authz_dbm mod_authz_owner mod_authz_dbd mod_authz_core mod_authnz_ldap mod_access_compat mod_auth_basic mod_auth_form mod_auth_digest mod_allowmethods mod_file_cache mod_socache_shmcb mod_socache_dbm mod_socache_memcache mod_dbd mod_bucketeer mod_dumpio mod_echo mod_case_filter mod_case_filter_in mod_buffer mod_ratelimit mod_reqtimeout mod_ext_filter mod_request mod_include mod_filter mod_substitute mod_sed mod_charset_lite mod_mime util_ldap mod_log_config mod_log_debug mod_logio mod_env mod_mime_magic mod_cern_meta mod_expires mod_headers mod_usertrack mod_unique_id mod_setenvif mod_version mod_remoteip mod_proxy mod_proxy_connect mod_proxy_ftp mod_proxy_http mod_proxy_fcgi mod_proxy_scgi mod_proxy_ajp mod_proxy_balancer mod_proxy_express mod_session mod_session_cookie mod_session_dbd mod_slotmem_shm mod_ssl mod_lbmethod_byrequests mod_lbmethod_bytraffic mod_lbmethod_bybusyness mod_lbmethod_heartbeat mod_unixd mod_dav mod_status mod_autoindex mod_info mod_suexec mod_cgi mod_cgid mod_dav_fs mod_vhost_alias mod_negotiation mod_dir mod_actions mod_speling mod_userdir mod_alias mod_rewrite mod_php5 mod_perl

    Here’s the response headers of a corrupt file (GZIP enabled via W3TC):


    HTTP/1.1 200 OK
    Date: Tue, 12 Jul 2016 07:10:48 GMT
    Server: Apache/2.4.18 (Unix) OpenSSL/1.0.2g PHP/5.6.20 mod_perl/2.0.8-dev Perl/v5.16.3
    Vary: Accept-Encoding
    X-Powered-By: PHP/5.6.20
    Pragma: private
    Last-Modified: Thu, 07 Jul 2016 13:25:58 GMT
    Content-Length: 37162
    Content-Encoding: gzip
    Keep-Alive: timeout=5, max=99
    Connection: Keep-Alive
    Content-Type: text/css; charset=utf-8

    And here’s the response of the following request


    HTTP/1.1 200 OK
    Date: Tue, 12 Jul 2016 07:12:32 GMT
    Server: Apache/2.4.18 (Unix) OpenSSL/1.0.2g PHP/5.6.20 mod_perl/2.0.8-dev Perl/v5.16.3
    Vary: Accept-Encoding
    Last-Modified: Tue, 12 Jul 2016 07:10:49 GMT
    ETag: "912a-5376af7eb3040"
    Accept-Ranges: bytes
    Content-Length: 37162
    Keep-Alive: timeout=5, max=99
    Connection: Keep-Alive
    Content-Type: text/css
    Content-Encoding: gzip

    Note: I have not enabled eTags, that’s Apache’s doing, which I can’t turn off for some reason.

    This is the same file, with W3TC’s GZIP disabled:


    Accept-Ranges:bytes
    Connection:Keep-Alive
    Content-Length:243454
    Content-Type:text/css
    Date:Tue, 12 Jul 2016 07:35:25 GMT
    ETag:"3b6fe-5376b12ae6280"
    Keep-Alive:timeout=5, max=99
    Last-Modified:Tue, 12 Jul 2016 07:18:18 GMT
    Server:Apache/2.4.18 (Unix) OpenSSL/1.0.2g PHP/5.6.20 mod_perl/2.0.8-dev Perl/v5.16.3

    Thread Starter jkbk

    (@jkbk)

    I just checked the minified, gzipped file in the disk cache (wp-content/cache/minify/000000/01234/default.include.012345.css.gzip), and it is OK, as expected. I guess minification is triggered on request, this is where the extra newline gets tossed in; as soon as the file is served from disk, it’s gone.

    Thread Starter jkbk

    (@jkbk)

    I managed to stumble over the solution!

    This bug is essentially a duplicate of this, which is caused in lib/W3/Environment/WpLoader.php in line 26/27, which in some cases (like a separated wp/wp-content setup) generates wp-content/plugins/w3tc-wp-loader.php. Here’s the offending part, note the weird line break:

    $file_data = "
    <?php
        if (W3TC_WP_LOADING)

    If used together with gzip, it’s not just headers/warnings (as in the linked post above), it really corrupts the compressed asset files.

    Until this is fixed, here’s a workaround, which i found through a different issue (with a smilar setup – capistrano / “own wordpress directory”):

    1. add define('DONOTVERIFY_WP_LOADER', true); to wp-config.php – this prevents the automatic creation of w3tc-wp-loader.php
    2. create/modify w3tc-wp-loader.php and point it to wp-load.php

    Mine looks like this:

    <?php
        if (W3TC_WP_LOADING)
            require_once dirname(__FILE__).'/../../wp/wp-load.php';

    Make sure there’s no newlines or whitespace before the opening php tag ??

    /wp-content/plugins/w3-total-cache/lib/W3/Environment/WpLoader.php

    remove the blank line after $file_data = “

    /**
         * @throws FilesystemWriteException
         * @throws FilesystemWriteException
         */
        public function create() {
            $path = trim(w3_get_wp_sitepath() ,"/");
            if ($path)
                $path .= '/';
            $file_data = "<?php
        if (W3TC_WP_LOADING)
            require_once '" . w3_get_document_root() . '/' . $path . "wp-load.php';
    ";
            $filename = W3TC_WP_LOADER;
            $data = $file_data;
    
            w3_require_once(W3TC_INC_DIR . '/functions/rule.php');
            $current_data = @file_get_contents($filename);
            if (strstr(w3_clean_rules($current_data), w3_clean_rules($data)) !== false)
                return;
    
            w3_require_once(W3TC_INC_DIR . '/functions/activation.php');
            w3_wp_write_to_file($filename, $data, '', $_SERVER['REQUEST_URI']);
        }
    Thread Starter jkbk

    (@jkbk)

    Well, duh, that’s exactly what I said, when you take the original post about an extra line break in account; note “note the weird line break” ??
    I proposed the workaround to avoid messing with the plugin’s source file, as they will be overwritten when updated.

    @jkbk, are you interested to collaborate at community edition of w3tc on github?

    https://github.com/szepeviktor/fix-w3tc

Viewing 9 replies - 1 through 9 (of 9 total)
  • The topic ‘Corrupt gzipped JS/CSS on first visit after empty cache’ is closed to new replies.