⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tefilter.java

📁 很棒的web服务器源代码
💻 JAVA
字号:
// TEFilter.java// $Id: TEFilter.java,v 1.6 2002/02/05 16:34:38 ylafon Exp $// (c) COPYRIGHT MIT and INRIA, 1996.// Please first read the full copyright statement in file COPYRIGHT.htmlpackage org.w3c.jigsaw.filters;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.io.PipedInputStream;import java.io.PipedOutputStream;import java.util.zip.DeflaterOutputStream;import java.util.zip.GZIPOutputStream;import org.w3c.tools.resources.Attribute;import org.w3c.tools.resources.AttributeRegistry;import org.w3c.tools.resources.ProtocolException;import org.w3c.tools.resources.ReplyInterface;import org.w3c.tools.resources.RequestInterface;import org.w3c.tools.resources.Resource;import org.w3c.tools.resources.ResourceFilter;import org.w3c.tools.resources.ResourceFrame;import org.w3c.tools.resources.StringArrayAttribute;import org.w3c.www.mime.MimeType;import org.w3c.jigsaw.http.Reply;import org.w3c.jigsaw.http.Request;import org.w3c.www.http.HttpAcceptEncoding;import org.w3c.www.http.HttpEntityMessage;import org.w3c.www.http.HttpMessage;import org.w3c.www.http.HttpRequestMessage;/** * This filter will compress the content of replies using GZIP or whatever * encoding scheme requested in the TE: header of the request. * Compression is done <em>on the fly</em>. This assumes that you're really * on a slow link, where you have lots of CPU, but not much bandwidth. * <p>A nifty usage for that filter, is to plug it on top of a * <code>org.w3c.jigsaw.proxy.ProxyFrame</code>, in which case it * will encode the data when it flies out of the proxy. */public class TEFilter extends ResourceFilter {    /**     * Attribute index - List of MIME type that we can compress     */    protected static int ATTR_MIME_TYPES = -1;    static {	Class     c = null;	Attribute a = null;	try {	    c = Class.forName("org.w3c.jigsaw.filters.TEFilter");	} catch (Exception ex) {	    ex.printStackTrace();	    System.exit(1);	}	// Register the MIME types attribute:	a = new StringArrayAttribute("mime-types"				     , null				     , Attribute.EDITABLE);	ATTR_MIME_TYPES = AttributeRegistry.registerAttribute(c, a);    }    /**     * The set of MIME types we are allowed to compress.     */    protected MimeType types[] = null;    // grumble... DeflateInputStream with a compression/decompression    // flag would have been better in the core API ;)    private class DataMover extends Thread {	InputStream in = null;	OutputStream out = null;	public void run() {	    try {		byte buf[] = new byte[1024];		int  got   = -1;		while ((got = in.read(buf)) >= 0) 		    out.write(buf, 0, got);	    } catch (IOException ex) {		ex.printStackTrace();	    } finally {		try { in.close(); } catch (Exception ex) {};		try { out.close(); } catch (Exception ex) {} ;	    }	}	DataMover(InputStream in, OutputStream out) {	    this.in  = in;	    this.out = out;	    setName("DataMover");	    start();	}    }    /**     * Catch the setting of mime types to compress.     * @param idx The attribute being set.     * @param val The new attribute value.     */    public void setValue(int idx, Object value) {	super.setValue(idx, value);	if ( idx == ATTR_MIME_TYPES ) {	    synchronized (this) {		types = null;	    }	}    }        /**     * Get the set of MIME types to match:     * @return An array of MimeType instances.     */    public synchronized MimeType[] getMimeTypes() {	if ( types == null ) {	    String strtypes[] = (String[]) getValue(ATTR_MIME_TYPES, null);	    if ( strtypes == null )		return null;	    types = new MimeType[strtypes.length];	    for (int i = 0 ; i < types.length ; i++) {		try {		    types[i] = new MimeType(strtypes[i]);		} catch (Exception ex) {		    types[i] = null;		}	    }	}	return types;    }    protected double getCompressibilityFactor(Reply reply) {        // Match possible mime types:	MimeType t[]     = getMimeTypes();	if ( t != null ) {	    for (int i = 0 ; i < t.length ; i++) {		if ( t[i] == null )		    continue;		if ( t[i].match(reply.getContentType()) > 0 ) {		    String enc[] = reply.getContentEncoding();		    if (enc != null ) {			for (int j=0; j< enc.length; j++) {			    if ((enc[j].indexOf("gzip") >= 0) ||				(enc[j].indexOf("deflate") >= 0) ||				(enc[j].indexOf("compress") >= 0)) {				// no more compression				return 0.001;			    }			}		    }		    return 1.0;		}	    }	}	return 0.001; // minimal value    }    protected void doEncoding(HttpAcceptEncoding enc, Reply reply) {        // Anything to compress ?	if ( ! reply.hasStream() )	    return;	// Match possible mime types:	MimeType t[]     = getMimeTypes();	boolean  matched = false;	if ( t != null ) {	    for (int i = 0 ; i < t.length ; i++) {		if ( t[i] == null )		    continue;		if ( t[i].match(reply.getContentType()) > 0 ) {		    matched = true;		    break;		}	    }	}	if ( ! matched ) 	    return;		InputStream orig_is = reply.openStream();	// do the gzip encoding	if (enc.getEncoding().equals("gzip")) {	    try {		PipedOutputStream gzpout = new PipedOutputStream();		PipedInputStream  gzpin  = new PipedInputStream(gzpout);		new DataMover(reply.openStream()			      , new GZIPOutputStream(gzpout));		reply.setStream(gzpin);	    } catch (IOException ex) {		ex.printStackTrace();		reply.setStream(orig_is);		return;	    }	    reply.addTransferEncoding("gzip");	    reply.setContentLength(-1);	} else if (enc.getEncoding().equals("deflate")) {	    // do the deflate encoding	    try {		PipedOutputStream zpout = new PipedOutputStream();		PipedInputStream  zpin  = new PipedInputStream(zpout);		new DataMover(reply.openStream()			      , new DeflaterOutputStream(zpout));		reply.setStream(zpin);	    } catch (IOException ex) {		ex.printStackTrace();		reply.setStream(orig_is);		return;	    }	    reply.addTransferEncoding("deflate");	    reply.setContentLength(-1);	}	return;    }    /**     * @param request The original request.     * @param reply It's original reply.      * @return A Reply instance, or <strong>null</strong> if processing      * should continue normally.      * @exception ProtocolException If processing should be interrupted,       * because an abnormal situation occured.      */    public ReplyInterface outgoingFilter(RequestInterface req,					 ReplyInterface rep) 	throws ProtocolException    {      Request request = (Request) req;      Reply   reply   = (Reply) rep;      HttpAcceptEncoding encs[] = request.getTE();      String trenc[] = reply.getTransferEncoding();            // Anything to compress ?      if ( ! reply.hasStream() )	  return null;            if (trenc != null) {	  // don't mess with already encoded stuff	  // otherwise we have to dechunk/rechunk and it would be painful	  return null;      }      if (encs != null) { // identity and chucked always ok	  double max = -1.0;	  double identity = 1.0; // some dummy default values	  double chunked = 1.0;	  double comp_factor = getCompressibilityFactor(reply);	  HttpAcceptEncoding best = null;	  for (int i = 0 ; i < encs.length ; i++) {	      if (encs[i].getEncoding().equals("identity")) {		  identity = encs[i].getQuality();		  continue;	      } else if (encs[i].getEncoding().equals("chunked")) {		  chunked = encs[i].getQuality();		  continue;	      } else if (encs[i].getEncoding().equals("trailers")) {		  // means that the client understand trailers.. check 		  // that with pending trailers impl		  // req.setTrailerOk();		  continue;	      }	      if (encs[i].getQuality() * comp_factor > max) {		  best = encs[i];		  max = encs[i].getQuality() * comp_factor;		  if (max == 1.0) // can't be better		      break;	      }	  }	  if (best != null && (max >= identity)) {	      doEncoding(best, reply);	  } else {	      if (identity > 0) {		  if (chunked > identity)		      reply.setContentLength(-1);	      } else {		  // spec says: chunked always acceptable		  reply.setContentLength(-1);	      }	  }      }      return null;    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -