"Stephen R. van den Berg" <[email protected]> wrote: > server/modules/filters/gziponthefly.pike | 102 > ++++++++++++++++++++++++++++++
Just recently, Marty (cc'd) made an experimental patch to get compression directly in the http protocol. One reason to do that was to make it happen after the protocol module has fixed the charset encoding. Another is that it can be tied in with the protocol cache (it might not be wise to spend cpu on compressing dynamic answers). Maybe you can compare solutions? diff --git a/server/modules/filters/gziponthefly.pike b/server/modules/filters/gziponthefly.pike new file mode 100644 index 0000000..dae088e --- /dev/null +++ b/server/modules/filters/gziponthefly.pike @@ -0,0 +1,102 @@ +// This is a roxen module which provides gzip-on-the-fly compression support. +// Copyright (c) 2002-2009, Stephen R. van den Berg, The Netherlands. +// <[email protected]> +// +// This module is open source software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation; either version 2, or (at your option) any +// later version. +// + +#define _(X,Y) _DEF_LOCALE("mod_gziponthefly",X,Y) + +constant thread_safe = 1; + +#include <module.h> + +inherit "module"; + +constant module_type = MODULE_FILTER; +LocaleString module_name = _(1,"Filters: Gzip-on-the-fly"); +LocaleString module_doc = _(2, + "This module provides the gzip-on-the-fly filter.<br />" + "<p>Copyright © 2002-2009, by " + "<a href='mailto:[email protected]'>Stephen R. van den Berg</a>, " + "The Netherlands.</p>" + "<p>Due to implementation mistakes by Microsoft this filter " + "uses the gzip format instead of deflate. </p> " + "<p>By setting a browser-cookie of gzip=0 one can disable compression, " + "whereas setting gzip=1 will force compression. </p> " + "<p>This module is open source software; you can redistribute it and/or " + "modify it under the terms of the GNU General Public License as published " + "by the Free Software Foundation; either version 2, or (at your option) any " + "later version.</p>"); + +#define COMPRESSION_LEVEL 1 + +void create() { + set_module_creator("Stephen R. van den Berg <[email protected]>"); + defvar ("compressionlevel", 1, + _(3,"Compressionlevel"), TYPE_INT, + _(4,"Use 1 for fast compression, use 9 for slow compression.") + ); + defvar ("minfilesize", 1024, + _(5,"Minimum file size"), TYPE_INT, + _(6,"Any data equal to or below this size limit will be sent " + "uncompressed.") + ); +} + +int before, after, nosupport, fixed, nowant; +float time_spent; + +string status() +{ + return sprintf("%.1fM of %.1fM (%.1f%%) have been gained " + "by using %.2f CPU seconds." + "<br/>%d+%d/%d request%s were sent uncompressed " + "due to lack of gzip support", + (before-after)/1024.0/1024.0, before/1024.0/1024.0, + (before-after)*100 / (before+0.1), time_spent, + nowant,nosupport, fixed, ((nowant+nosupport)==1?"":"s")); +} + +mapping filter( mapping result, RequestID id ) +{ + int len; + if( id->misc->internal_get + || id->misc->gzippedalready + || !result + || !stringp(result->data) + || String.width(result->data)>8 + || (len=sizeof(result->data))<=query("minfilesize") + || result->type + && !has_prefix(result->type, "text/") + && !has_prefix(result->type, "application/x-javascript")) + return 0; + + id->misc->gzippedalready = 1; + before+=len; + fixed++; + if( (id->cookies->gzip != "1" + && (!id->request_headers["accept-encoding"] || + !has_value(id->request_headers["accept-encoding"], "gzip" ))) + || id->cookies->gzip=="0") + { + if( id->cookies->gzip=="0" ) + nowant++; + else + nosupport++; + return 0; + } + time_spent+=gauge { + StringFile out=StringFile(); + Gz._file c = Gz._file(out,"ab"); + c->setparams(query("compressionlevel"),Gz.DEFAULT_STRATEGY); + c->write(result->data); + c->close(); + result->data = out->outdata*""; // Transform back to single string + }; + after+=sizeof(result->data); + result->encoding="gzip"; +}
