---
server/modules/filters/gziponthefly.pike | 102 ++++++++++++++++++++++++++++++
1 files changed, 102 insertions(+), 0 deletions(-)
create mode 100644 server/modules/filters/gziponthefly.pike
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.
+// <<srb[at]cuci.nl>>
+//
+// 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:<srb[at]cuci.nl>'>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 <<srb[at]cuci.nl>>");
+ 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";
+}
|