httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Paul Ausbeck <pa...@alumni.cse.ucsc.edu>
Subject Re: Compression via content negotiation
Date Thu, 03 Dec 1998 23:20:33 GMT
I have come to the conclusion that content negotiation is not the place
for compression. Here are some reasons:

1) After looking at the negotiation code it seemed like putting
compression there would be a significant performance hit.
2) Negotiation handles are confusing to browsers when the content is not
viewed inline. This is because the url itself has a role in determining
the browser's actions.
3) Public urls that have been compressed should not be content encoded.
For example, zip archives should not be decompressed by the browser but
by whatever tool the user has available at the client end.
4) Compression should be as transparent as possible to encourage
adoption.

So, I coded up a compression module this morning. Everything is hard
coded at the moment but all the salient points can be gleaned from the
initial implementation. The module is just a generic apache handler. I
configured my server to use the module universally:

<Location *>
SetHandler compress-handler
allow from all
</Location>

All the work gets done in the fixup phase. I have attached the code
below. The module first checks to see if it makes sense to compress
based upon what it knows about the client. If the client seems ok, it
then checks to see if a compressed version of the URL is available and
meets some security/sanity checks. The transaction is the altered to
point to the compressed file and vary and content-encoding headers are
added to the response. Note that the compressed file must be in the same
directory as the uncompressed in this simple implementation. The
compressor is not configurable in this initial implementation. If a
compressed file that meets its criteria is present, it is used.

I believe this scheme is http 1.1 compliant but I'm looking for
criticism.

Paul Ausbeck

/* Where the work gets done if any is to be done. */
static int compress_fixer_upper(request_rec *r)
{
    excfg *cfg = our_dconfig(r);

    char *compressed_file;
    struct stat cstat;
    table *hout = r->err_headers_out;
    const char *hin = ap_table_get(r->headers_in, "Accept-encoding");

    if (!r->finfo.st_mode || /* File doesn't exist. */
        S_ISDIR(r->finfo.st_mode) || /* File is a directory. */
        !(viewable_inline(r) || /* Is the mime type viewable inline? *?
        !accept_gzip(r)) /* Is there an accept-encoding gzip header */
        return DECLINED; /* Decline before doing a stat. */

    compressed_file = ap_pstrcat(r->pool, r->filename, ".gz", 0);
    stat(compressed_file, &cstat);
    if (!cstat.st_mode || /* Compressed file doesn't exist. */
        cstat.st_mode != r->finfo.st_mode || /* File permissions aren't
the same. */
        cstat.st_mtime < r->finfo.st_mtime || /* Compressed older than
uncompressed. */
        cstat.st_size >= r->finfo.st_size) /* No gain from compression.
*/
        return DECLINED;
     
    /* Setup for content encoding. */
    r->filename = compressed_file; /* Use compressed content. */
    ap_table_mergen(hout, "Vary", "accept-encoding"); /* Add Vary
header. */
    /* Content encoding is x-gzip if x-gzip asked for, gzip otherwise.
*/
    r->content_encoding = strstr(hin, "x-gzip") ? "x-gzip" : "gzip"; 

    return OK;
}


Mime
View raw message