apache / incubator-pagespeed-cpanel

mod_pagespeed module for CPanel WHM
Other
144 stars 50 forks source link

CSS/JS is encoded and breaks #30

Open JewrassicPark opened 9 years ago

JewrassicPark commented 9 years ago

I installed the mod_pagespeed module with easy apache.

In my conf file i can toggle ModPagespeed on/off and it does turn on and off

However when it's on, no matter what I change in the config file (so far) all the js/css on my site breaks

and is output like:

‹������ì=iwÛF’Ÿ©Ñ=½Ø“ÂÁSÊ:k[Rì·¾VòLöÛ<„D<S�%+|üïÛwW$@)³™ÄI,5Õ]ÝuuuUáøú”ޣLJe6MÇIñ5Fh=ÍÊå<y8Yä‹ôts€ÿ9~®ª‡yZ’έq>}@ëq2ùvSä«Å´=Éçyqrx}}»·:÷E²\¦Z£ÛlѾϦÕì$Ëï§h™L§Ùâæ$¤¿Ué÷ªÌ³›Å š¤‹-N‘K¢Ën—yQ%‹êtÓÂÿ´çyB€œewx1YDg‹–y™UYŽ&ã2Ÿ¯_Üö[;[LÓï'(ê"6ÁÑ)š¥Ùͬ¿ñɵ«|yt†’¨¸'Ï¢^ï%Rÿ :ƒç6{Ƙ2›ñ5~XÌÓëJLN›

I posted on the other google groups forum and provided a private link to someone answering questions there and aside from telling me that the content wasn't being sent with the Content-Encoding gzip header, there wasn't much else to go off.

Let me know there's anything that can be done.

Thanks, -Derek

JewrassicPark commented 9 years ago

I should note that manually adding the header "Content-Encoding:gzip" (and I can see it in the request) doesn't seem to solve the issue

jeffkaufman commented 9 years ago

I'm sorry I dropped this; looking at it again now.

jeffkaufman commented 9 years ago

Loading the page on your test server with ?PageSpeedFilters=+collapse_whitespace I do still see the bug, with CSS not loading properly.

Looking at the responses from the server in my browser I see /css-master-test?v=1.0 being served gzip encoded but without a 'Content-Encoding: gzip' response header.

Copying the exact request from the browser, this reproduces with curl:

IP=[supplied via email]
HOST=[supplied via email]
curl 'http://'$IP'/css-master-test?v=1.0' \
   -H 'Host: '$HOST \
   -H 'Cookie: __qca=P0-1226274354-1432913988559; exp_tracker=a%3A0%3A%7B%7D; __utmt=1; __utma=75130772.917503079.1432913988.1432913988.1433943720.2; __utmb=75130772.1.10.1433943720; __utmc=75130772; __utmz=75130772.1432913988.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)' \
   -H 'Accept-Encoding: gzip, deflate, sdch' \
   -H 'Accept-Language: en-US,en;q=0.8,es;q=0.6' \
   -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.81 Safari/537.36' \
   -H 'Accept: text/css,*/*;q=0.1' \
   -H 'Cache-Control: max-age=0' \
   -H 'If-None-Match: W/"PSA-wZeYN4uezT"' \
   -H 'Connection: keep-alive' \
   -H 'If-Modified-Since: Wed, 10 Jun 2015 13:41:55 GMT' \
   -H 'Referer: http://'$HOST'/?PageSpeedFilters=+collapse_whitespace' \
   -D- \
   -o ~/tmp.css

This gives me response headers of:

HTTP/1.1 200 OK
Date: Wed, 10 Jun 2015 13:46:25 GMT
Server: Apache/2.2.29 (Unix) mod_ssl/2.2.29 OpenSSL/1.0.1e-fips mod_bwlimited/1.4
Content-Length: 23959
X-Powered-By: PHP/5.3.29
Expires: Sat, 13 Jun 2015 20:13:52 GMT
Cache-control: max-age=345600, public
Pragma: public
Vary: Accept-Encoding
Etag: W/"PSA-wZeYN4uezT"
Last-Modified: Wed, 10 Jun 2015 13:46:25 GMT
X-Content-Type-Options: nosniff
Connection: close
Content-Type: text/css

And saves a file that is gzip-encoded css.

jeffkaufman commented 9 years ago

Reducing that response, I still get gzipped data that's not properly labeled if I simply request:

curl 'http://'$IP'/css-master-test?v=1.0' -H 'Host: '$HOST

This means PageSpeed has stored css-master-test in its cache as "non-gzip" and so is happy to send it to both gzip and non-gzip supporting requests.

What I haven't figured out yet is how PageSpeed came to store a gzip-encoded response body in its cache with non-gzip-indicating response headers.

jeffkaufman commented 9 years ago

Testing with /css-master-test?v=1.0&PageSpeed=off I see, without Accept-Encoding: gzip:

HTTP/1.1 200 OK
Date: Wed, 10 Jun 2015 14:00:57 GMT
Server: Apache/2.2.29 (Unix) mod_ssl/2.2.29 OpenSSL/1.0.1e-fips mod_bwlimited/1.4
X-Powered-By: PHP/5.3.29
Expires: Sun, 14 Jun 2015 14:00:57 GMT
Cache-control: max-age=345600, public
Pragma: public
Set-Cookie: exp_tracker=a%3A0%3A%7B%7D; path=/; domain=.DOMAIN
Last-Modified: Wed, 10 Jun 2015 14:00:57 GMT
Connection: close
Transfer-Encoding: chunked
Content-Type: text/css

[not gzipped]

And with Accept-Encoding: gzip:

HTTP/1.1 200 OK
Date: Wed, 10 Jun 2015 14:02:03 GMT
Server: Apache/2.2.29 (Unix) mod_ssl/2.2.29 OpenSSL/1.0.1e-fips mod_bwlimited/1.4
X-Powered-By: PHP/5.3.29
Expires: Sun, 14 Jun 2015 14:02:03 GMT
Cache-control: max-age=345600, public
Pragma: public
Content-Encoding: gzip
Vary: Accept-Encoding
Set-Cookie: exp_tracker=a%3A0%3A%7B%7D; path=/; domain=.DOMAIN
Last-Modified: Wed, 10 Jun 2015 14:02:03 GMT
Connection: close
Transfer-Encoding: chunked
Content-Type: text/css

[gzipped]

These are correct, so it's not an issue there.

jeffkaufman commented 9 years ago

This is strange: normally max-age counts down when re-requesting a file with IPRO, but here I'm seeing it stay constant at 345600.

jeffkaufman commented 9 years ago

@JewrassicPark I have your pagespeed.conf from before; could you send me the rest of your Apache config?

JewrassicPark commented 9 years ago

Emailed to you

jeffkaufman commented 9 years ago

Looking through the apache config, I don't see much unusual. mod_ruid2 looks to be installed and could be causing trouble, but I don't see how.

Where is your 4 day (345600s) cache lifetime coming from?

Do you have other servers (caches, load balancers, etc) involved?

Is css-master-test?v=1.0 just a file on the local filesystem? At /home/jeremy/public_html/css-master-test?

JewrassicPark commented 9 years ago

The 4 day cache headers is php outputted at the top of the css-master-test page

We have three servers, the one I gave you the ip for is off the load balancer right now. The other two are in but don't have pagespeed enabled. We were caching through pagspeed service until today, we just switched to edgecast.

css-master-test is a template pulled up by our cms (expressionengine).

jeffkaufman commented 9 years ago

Could you send me the source for css-master-test?

JewrassicPark commented 9 years ago

it's everything you see in http://live.trendhunter.com/css-master-test

plus

<? 
$expires = 4*24*60*60; //One Day
@header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); //Last modified date to
@header('Expires: ' . gmdate('D, d M Y H:i:s', time()+$expires) . ' GMT');
@header("Cache-control: max-age=$expires, public");
@header("Pragma: public");
?>

at the top

jeffkaufman commented 9 years ago

Thanks! I'll see if I can reproduce this.

jeffkaufman commented 9 years ago

Where does the Content-Type: text/css come from? That is, css-master-test is served with Content-Type: text/css but I don't see anything that would do this in your php file or in your configs.

JewrassicPark commented 9 years ago

It's a setting in the template, it outputs somewhere in the cms code im trying to track it down exactly right now

JewrassicPark commented 9 years ago

this is the specific block settings the template type

        switch ($this->out_type)
        {
            case 'webpage': $this->set_header("Content-Type: text/html; charset=".$EE->config->item('charset'));
                break;
            case 'css':     $this->set_header("Content-type: text/css");
                break;
            case 'js':      $this->set_header("Content-type: text/javascript");
                            $this->enable_profiler = FALSE;
                break;
            case '404':     $this->set_status_header(404);
                            $this->set_header("Date: ".gmdate("D, d M Y H:i:s")." GMT");
                break;
            case 'xml':     $this->set_header("Content-Type: text/xml");
                            $output = trim($output);
                break;
            case 'feed':    $this->_send_feed($output);
                break;
        }

and this is the set_header function

    function set_header($header, $replace = TRUE)
    {
        $EE =& get_instance();

        // We always need to send a content type

        if ($EE->config->item('send_headers') != 'y' && strncasecmp($header, 'content-type', 12) != 0)
        {
            return;
        }

        parent::set_header($header, $replace);
    }

which just puts them in an array

when the page is getting sent out to display it just sets those headers in php like

        if (count($this->headers) > 0)
        {
            foreach ($this->headers as $header)
            {
                @header($header[0], $header[1]);
            }
        }
JewrassicPark commented 9 years ago

Is there a way to completely disable the gzip functionality of pagespeed? I've tried a few directives with no effect.

jeffkaufman commented 9 years ago

@JewrassicPark There's not a way to turn off PageSpeed's gzipping, sorry!

I'm still debugging and working through the code trying to figure out where this is going wrong.

JewrassicPark commented 9 years ago

Are there any updates on this? I was planning to remove that server at some point from our installation and if I can't get pagespeed to work I might just forgo it .