Forum OpenACS Q&A: Re: How to enable gzip compression

Posted by Jeff Rogers on
For AOLserver specifically, 3 things are needed:
- the ns_zlib module must be included in the config

ns_section "ns/server/${server}/modules"
    ns_param nszlib

- gzip must be enabled for the server in the config:

ns_section "ns/server/${server}"
    ns_param gzip on

- gzip must be enabled on each connection. There is no default way to do this. An easy way is to set up a preauth filter; put this in the tcl lib directory (e.g., serverroot/modules/tcl/filter_gzip.tcl):

proc _ns_filter_gzip {args} {
    ns_conn gzip 1
    return filter_ok

ns_register_filter preauth * * _ns_filter_gzip

This should get gzip compression enabled on most pages (there's a further consideration with some static content, but OACS's request filter I think bypasses this).

Posted by Gustaf Neumann on
For NaviServer, the situation is simpler. NaviServer does not require an extra module, the "configure" script determines at compile time of NaviServer the availability of zlib (which is pretty ubiquitous). In the startup script, one can enable/configure gzip compression for dynamic content (adp pages) via the following parameters:
ns_section ns/server/${server} 
   # Compress response character data: ns_return, ADP etc.
   ns_param    compressenable	on	;# false, use "ns_conn compress" to override
   #ns_param    compresslevel       4	;# 4, 1-9 where 9 is high compression, high overhead
   #ns_param    compressminsize     512	;# Compress responses larger than this
So far Naviserver does not handle gzip compression for static content automatically. Does one really want to gzip a 500MB video file? For static content one would need at least some additional configuration on what files compression is wanted. It can be discussed, whether it is desirable to compress static content dynamically.

With the following snippet, one can deliver "precompressed" static files, if the client accepts gzipped content. To generate the gzipped content, one can iterate with a script over the file system, and produce the compressed content in addition to the uncompressed content.

set file graph.js
set fn [ns_info pageroot]/$file
set mime [ns_guesstype $file]

if {[ns_conn zipaccepted] && [ns_set iget [ns_conn headers] Range] eq ""} {
    if {![file readable $fn.gz] || [file mtime $fn] > [file mtime $fn.gz]} {
    exec gzip -9 <  $fn > $fn.gz
    if {[file readable $fn.gz]} {
    set fn $fn.gz
    ns_set put [ns_conn outputheaders] Vary Accept-Encoding
    ns_set put [ns_conn outputheaders] Content-Encoding gzip
ns_returnfile 200 $mime $fn 
The only NaviServer specific part is ns_conn zipaccepted which evaluates the "Accept-Encoding" rules from the client. This option was added recently and requires the head version, which is currently in quite active development (several commits every week). To get a more conservative version, download the tarfile for tag "naviserver-4.99.4" from Nov. 2012. It contains as well a sample startup script for openacs and works well with recent versions of OpenACS.

Hope this helps

Gustaf Neumann

Posted by Dafydd Crosby on
Awesome - putting the filter in got the pages gzipped. What would be involved in getting the static content gzipped?