📄 gzipfilter.java
字号:
//========================================================================//Copyright 2007 Mort Bay Consulting Pty. Ltd.//------------------------------------------------------------------------//Licensed under the Apache License, Version 2.0 (the "License");//you may not use this file except in compliance with the License.//You may obtain a copy of the License at //http://www.apache.org/licenses/LICENSE-2.0//Unless required by applicable law or agreed to in writing, software//distributed under the License is distributed on an "AS IS" BASIS,//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.//See the License for the specific language governing permissions and//limitations under the License.//========================================================================package org.mortbay.servlet;import java.io.IOException;import java.io.OutputStream;import java.io.OutputStreamWriter;import java.io.PrintWriter;import java.util.HashSet;import java.util.Set;import java.util.StringTokenizer;import java.util.zip.GZIPOutputStream;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletOutputStream;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpServletResponseWrapper;import org.mortbay.util.ByteArrayOutputStream2;import org.mortbay.util.StringUtil;/* ------------------------------------------------------------ *//** GZIP Filter * This filter will gzip the content of a response iff: <ul> * <li>The filter is mapped to a matching path</li> * <li>The response status code is >=200 and <300 * <li>The content length is unknown or more than the <code>minGzipSize</code> initParameter or the minGzipSize is 0(default)</li> * <li>The content-type is in the coma separated list of mimeTypes set in the <code>mimeTypes</code> initParameter or * if no mimeTypes are defined the content-type is not "application/gzip"</li> * <li>No content-encoding is specified by the resource</li> * </ul> * * <p> * Compressing the content can greatly improve the network bandwidth usage, but at a cost of memory and * CPU cycles. If this filter is mapped for static content, then use of efficient direct NIO may be * prevented, thus use of the gzip mechanism of the {@link org.mortbay.jetty.servlet.DefaultServlet} is * advised instead. * </p> * <p> * This filter extends {@link UserAgentFilter} and if the the initParameter <code>excludedAgents</code> * is set to a comma separated list of user agents, then these agents will be excluded from gzip content. * </p> * * @author gregw * */public class GzipFilter extends UserAgentFilter{ protected Set _mimeTypes; protected int _bufferSize=8192; protected int _minGzipSize=0; protected Set _excluded; public void init(FilterConfig filterConfig) throws ServletException { super.init(filterConfig); String tmp=filterConfig.getInitParameter("bufferSize"); if (tmp!=null) _bufferSize=Integer.parseInt(tmp); tmp=filterConfig.getInitParameter("minGzipSize"); if (tmp!=null) _minGzipSize=Integer.parseInt(tmp); tmp=filterConfig.getInitParameter("mimeTypes"); if (tmp!=null) { _mimeTypes=new HashSet(); StringTokenizer tok = new StringTokenizer(tmp,",",false); while (tok.hasMoreTokens()) _mimeTypes.add(tok.nextToken()); } tmp=filterConfig.getInitParameter("excludedAgents"); if (tmp!=null) { _excluded=new HashSet(); StringTokenizer tok = new StringTokenizer(tmp,",",false); while (tok.hasMoreTokens()) _excluded.add(tok.nextToken()); } } public void destroy() { } public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request=(HttpServletRequest)req; HttpServletResponse response=(HttpServletResponse)res; String ae = request.getHeader("accept-encoding"); if (ae != null && ae.indexOf("gzip")>=0 && !response.containsHeader("Content-Encoding")) { if (_excluded!=null) { String ua=getUserAgent(request); if (_excluded.contains(ua)) { super.doFilter(request,response,chain); return; } } GZIPResponseWrapper wrappedResponse=newGZIPResponseWrapper(request,response); boolean exceptional=true; try { super.doFilter(request,wrappedResponse,chain); exceptional=false; } finally { if (exceptional && !response.isCommitted()) { wrappedResponse.resetBuffer(); wrappedResponse.noGzip(); } else wrappedResponse.finish(); } } else { super.doFilter(request,response,chain); } } protected GZIPResponseWrapper newGZIPResponseWrapper(HttpServletRequest request, HttpServletResponse response) { return new GZIPResponseWrapper(request,response); } public class GZIPResponseWrapper extends HttpServletResponseWrapper { HttpServletRequest _request; boolean _noGzip; PrintWriter _writer; GzipStream _gzStream; long _contentLength=-1; public GZIPResponseWrapper(HttpServletRequest request, HttpServletResponse response) { super(response); _request=request; } public void setContentType(String ct) { super.setContentType(ct); int colon=ct.indexOf(";"); if (colon>0) ct=ct.substring(0,colon); if ((_gzStream==null || _gzStream._out==null) && (_mimeTypes==null && "application/gzip".equalsIgnoreCase(ct) || _mimeTypes!=null && !_mimeTypes.contains(StringUtil.asciiToLowerCase(ct)))) { noGzip(); } } public void setStatus(int sc, String sm) { super.setStatus(sc,sm); if (sc<200||sc>=300) noGzip(); } public void setStatus(int sc) { super.setStatus(sc); if (sc<200||sc>=300) noGzip(); } public void setContentLength(int length) { _contentLength=length; if (_gzStream!=null) _gzStream.setContentLength(length); } public void addHeader(String name, String value) { if ("content-length".equalsIgnoreCase(name)) { _contentLength=Long.parseLong(value); if (_gzStream!=null) _gzStream.setContentLength(_contentLength); } else if ("content-type".equalsIgnoreCase(name)) { setContentType(value); } else if ("content-encoding".equalsIgnoreCase(name)) { super.addHeader(name,value); if (!isCommitted()) { noGzip(); } } else super.addHeader(name,value); } public void setHeader(String name, String value) { if ("content-length".equalsIgnoreCase(name)) { _contentLength=Long.parseLong(value); if (_gzStream!=null) _gzStream.setContentLength(_contentLength); } else if ("content-type".equalsIgnoreCase(name)) { setContentType(value); } else if ("content-encoding".equalsIgnoreCase(name)) { super.setHeader(name,value); if (!isCommitted()) { noGzip(); } } else super.setHeader(name,value); } public void setIntHeader(String name, int value) { if ("content-length".equalsIgnoreCase(name)) { _contentLength=value; if (_gzStream!=null) _gzStream.setContentLength(_contentLength); } else super.setIntHeader(name,value); } public void flushBuffer() throws IOException { if (_writer!=null) _writer.flush(); if (_gzStream!=null) _gzStream.finish(); else getResponse().flushBuffer(); } public void reset() { super.reset(); if (_gzStream!=null) _gzStream.resetBuffer(); _writer=null; _gzStream=null; _noGzip=false;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -