--- /dev/null
+// GZIPFilter.java\r
+// $Id: GZIPFilter.java,v 1.2 2010/06/15 17:52:54 smhuang Exp $\r
+// (c) COPYRIGHT MIT, Keio and ERCIM, 1996, 2003\r
+// Please first read the full copyright statement in file COPYRIGHT.html\r
+\r
+package org.w3c.jigsaw.filters;\r
+\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.io.OutputStream;\r
+import java.io.PipedInputStream;\r
+import java.io.PipedOutputStream;\r
+\r
+import java.util.zip.GZIPOutputStream;\r
+\r
+import org.w3c.tools.resources.Attribute;\r
+import org.w3c.tools.resources.AttributeRegistry;\r
+import org.w3c.tools.resources.ProtocolException;\r
+import org.w3c.tools.resources.ReplyInterface;\r
+import org.w3c.tools.resources.RequestInterface;\r
+import org.w3c.tools.resources.Resource;\r
+import org.w3c.tools.resources.ResourceFilter;\r
+import org.w3c.tools.resources.ResourceFrame;\r
+import org.w3c.tools.resources.StringArrayAttribute;\r
+\r
+import org.w3c.www.mime.MimeType;\r
+\r
+import org.w3c.jigsaw.http.Reply;\r
+import org.w3c.jigsaw.http.Request;\r
+\r
+class GZIPDataMover extends Thread {\r
+ InputStream in = null;\r
+ OutputStream out = null;\r
+\r
+ public void run() {\r
+ try {\r
+ byte buf[] = new byte[1024];\r
+ int got = -1;\r
+ while ((got = in.read(buf)) >= 0) \r
+ out.write(buf, 0, got);\r
+ } catch (IOException ex) {\r
+ ex.printStackTrace();\r
+ } finally {\r
+ try { in.close(); } catch (Exception ex) {};\r
+ try { out.close(); } catch (Exception ex) {} ;\r
+ }\r
+ }\r
+\r
+ GZIPDataMover(InputStream in, OutputStream out) {\r
+ this.in = in;\r
+ this.out = out;\r
+ setName("GZIPDataMover");\r
+ start();\r
+ }\r
+}\r
+\r
+/**\r
+ * This filter will compress the content of replies using GZIP.\r
+ * Compression is done <em>on the fly</em>. This assumes that you're really\r
+ * on a slow link, where you have lots of CPU, but not much bandwidth.\r
+ * <p>NOTE that as it change the Content-Encoding of the served content,\r
+ * it MUST NOT be used on a proxy or a proxy/cache..\r
+ */\r
+\r
+public class GZIPFilter extends ResourceFilter {\r
+ /**\r
+ * Attribute index - List of MIME type that we can compress\r
+ */\r
+ protected static int ATTR_MIME_TYPES = -1;\r
+\r
+ static {\r
+ Class c = null;\r
+ Attribute a = null;\r
+ try {\r
+ c = Class.forName("org.w3c.jigsaw.filters.GZIPFilter");\r
+ //Added by Jeff Huang\r
+ //TODO: FIXIT\r
+ } catch (Exception ex) {\r
+ ex.printStackTrace();\r
+ System.exit(1);\r
+ }\r
+ // Register the MIME types attribute:\r
+ a = new StringArrayAttribute("mime-types"\r
+ , null\r
+ , Attribute.EDITABLE);\r
+ ATTR_MIME_TYPES = AttributeRegistry.registerAttribute(c, a);\r
+ }\r
+\r
+ /**\r
+ * The set of MIME types we are allowed to compress.\r
+ */\r
+ protected MimeType types[] = null;\r
+\r
+ /**\r
+ * Catch the setting of mime types to compress.\r
+ * @param idx The attribute being set.\r
+ * @param val The new attribute value.\r
+ */\r
+\r
+ public void setValue(int idx, Object value) {\r
+ super.setValue(idx, value);\r
+ if ( idx == ATTR_MIME_TYPES ) {\r
+ synchronized (this) {\r
+ types = null;\r
+ }\r
+ }\r
+ }\r
+\r
+ \r
+ /**\r
+ * Get the set of MIME types to match:\r
+ * @return An array of MimeType instances.\r
+ */\r
+\r
+ public synchronized MimeType[] getMimeTypes() {\r
+ if ( types == null ) {\r
+ String strtypes[] = (String[]) getValue(ATTR_MIME_TYPES, null);\r
+ if ( strtypes == null )\r
+ return null;\r
+ types = new MimeType[strtypes.length];\r
+ for (int i = 0 ; i < types.length ; i++) {\r
+ try {\r
+ types[i] = new MimeType(strtypes[i]);\r
+ } catch (Exception ex) {\r
+ types[i] = null;\r
+ }\r
+ }\r
+ }\r
+ return types;\r
+ }\r
+\r
+ /**\r
+ * @param request The original request.\r
+ * @param reply It's original reply. \r
+ * @return A Reply instance, or <strong>null</strong> if processing \r
+ * should continue normally. \r
+ * @exception ProtocolException If processing should be interrupted, \r
+ * because an abnormal situation occured. \r
+ */\r
+ public ReplyInterface outgoingFilter(RequestInterface req,\r
+ ReplyInterface rep) \r
+ throws ProtocolException\r
+ {\r
+ Request request = (Request) req;\r
+ Reply reply = (Reply) rep;\r
+ // Anything to compress ?\r
+ if ( ! reply.hasStream() ) {\r
+ return null;\r
+ }\r
+ // if there is already a Content-Encoding, skip this\r
+ if (reply.getContentEncoding() != null) {\r
+ return null;\r
+ }\r
+ // Match possible mime types:\r
+ MimeType t[] = getMimeTypes();\r
+ boolean matched = false;\r
+ if ( t != null ) {\r
+ for (int i = 0 ; i < t.length ; i++) {\r
+ if ( t[i] == null )\r
+ continue;\r
+ if ( t[i].match(reply.getContentType()) > 0 ) {\r
+ matched = true;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ if ( ! matched ) \r
+ return null;\r
+ // Compress:\r
+ try {\r
+ PipedOutputStream pout = new PipedOutputStream();\r
+ PipedInputStream pin = new PipedInputStream(pout);\r
+ new GZIPDataMover(reply.openStream()\r
+ , new GZIPOutputStream(pout));\r
+ reply.addContentEncoding("gzip");\r
+ reply.setContentLength(-1);\r
+ reply.setStream(pin);\r
+ } catch (Exception ex) {\r
+ ex.printStackTrace();\r
+ }\r
+ return null;\r
+ }\r
+\r
+}\r