Php – Apache/2.2.20 (Ubuntu 11.10) gzip compression won’t work on php pages, content is chunked

apache-2.2compressiondeflatePHP

I'm running into a problem with a new production server whereto I'm transferring projects. The HTML output of the PHP applications isn't compressed by the Apache mod_deflate module. Other resources, as stylesheet and javascript files, even html pages, which are served with the same Content-type (text/html) as the PHP output, are compressed!

The projects use the following rules (from HTML5 boilerplate) in the .htaccess:

<IfModule mod_deflate.c>
  # Force deflate for mangled headers developer.yahoo.com/blogs/ydn/posts/2010/12/pushing-beyond-gzipping/
  <IfModule mod_setenvif.c>
    <IfModule mod_headers.c>
      SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding
      RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding
    </IfModule>
  </IfModule>

  # HTML, TXT, CSS, JavaScript, JSON, XML, HTC:
  <IfModule filter_module>
    FilterDeclare   COMPRESS
    FilterProvider  COMPRESS  DEFLATE resp=Content-Type $text/html
    FilterProvider  COMPRESS  DEFLATE resp=Content-Type $text/css
    FilterProvider  COMPRESS  DEFLATE resp=Content-Type $text/plain
    FilterProvider  COMPRESS  DEFLATE resp=Content-Type $text/xml
    FilterProvider  COMPRESS  DEFLATE resp=Content-Type $text/x-component
    FilterProvider  COMPRESS  DEFLATE resp=Content-Type $application/javascript
    FilterProvider  COMPRESS  DEFLATE resp=Content-Type $application/json
    FilterProvider  COMPRESS  DEFLATE resp=Content-Type $application/xml
    FilterProvider  COMPRESS  DEFLATE resp=Content-Type $application/xhtml+xml
    FilterProvider  COMPRESS  DEFLATE resp=Content-Type $application/rss+xml
    FilterProvider  COMPRESS  DEFLATE resp=Content-Type $application/atom+xml
    FilterProvider  COMPRESS  DEFLATE resp=Content-Type $application/vnd.ms-fontobject
    FilterProvider  COMPRESS  DEFLATE resp=Content-Type $image/svg+xml
    FilterProvider  COMPRESS  DEFLATE resp=Content-Type $image/x-icon
    FilterProvider  COMPRESS  DEFLATE resp=Content-Type $application/x-font-ttf
    FilterProvider  COMPRESS  DEFLATE resp=Content-Type $font/opentype
    FilterChain     COMPRESS
    FilterProtocol  COMPRESS  DEFLATE change=yes;byteranges=no
  </IfModule>
 </IfModule>                                                                                                                                                                 

We have a testing machine that runs the same Apache, OS and PHP version. On that machine the compression works just fine on the PHP output. I've checked and compared Apache and PHP config files, all the same as far as I can tell.

I've tried several manners of outputting the content of the PHP, using output buffering or just plain echoing the content. Same thing, no compression.

Example response headers of a PHP output:

HTTP/1.1 200 OK
Date: Wed, 25 Apr 2012 23:30:59 GMT
Server: Apache
Accept-Ranges: bytes
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: public
Pragma: no-cache
Vary: User-Agent
Keep-Alive: timeout=5, max=98
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html; charset=utf-8

Example of response headers on a css file:

HTTP/1.1 200 OK
Date: Wed, 25 Apr 2012 23:30:59 GMT
Server: Apache
Last-Modified: Mon, 04 Jul 2011 19:12:36 GMT
Vary: Accept-Encoding,User-Agent
Content-Encoding: gzip
Cache-Control: public
Expires: Fri, 25 May 2012 23:30:59 GMT
Content-Length: 714
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/css; charset=utf-8

Does anyone has a clue or experienced the same "problem"?

thanks!

Best Answer

If Apache can't tell how big the returned content is, it will automatically resort to chunked encoding. Depending on how your PHP script is being run (CGI, FastCGI, etc.), Apache may not know the size of the content when it begins returning it to the user. I.e., if you have it outputting content throughout the script, it may write that data to the client's buffer immediately.

The reason it works with static files is because Apache knows the size of them when it begins returning it. This may point to an issue with your Apache/PHP configuration (i.e., it begins writing the moment output is returned from the script), or in how your script itself works.

In other words, this sounds like its a problem with PHP or your Apache/PHP connector, not with mod_deflate.