302566 GZIP handler for embedded Jetty servers

git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@3406 7e9141cc-0065-0410-87d8-b60c137991c4
This commit is contained in:
Michael Gorovoy 2011-06-21 02:26:18 +00:00
parent 418ebe8268
commit 8c63ca989b
12 changed files with 935 additions and 1420 deletions

View File

@ -1,5 +1,6 @@
jetty-7.4.3-SNAPSHOT
+ 295832 ProxyServlet more extensible and configurable
+ 302566 GZIP handler for embedded Jetty servers
+ 347617 Dynamically install/update/remove OSGi bundles discovered in the contexts folder
+ 347717 start.jar destroys dependent child of --exec
+ 347898 Close channel on JVM exceptions

View File

@ -48,5 +48,16 @@
<artifactId>jetty-websocket</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>test-jetty-servlet</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -11,7 +11,7 @@
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.server.handler;
package org.eclipse.jetty.embedded;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@ -32,6 +32,9 @@ import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.handler.GzipHandler;
import org.eclipse.jetty.testing.HttpTester;
import org.eclipse.jetty.util.IO;
import org.junit.After;
import org.junit.Before;

View File

@ -17,6 +17,11 @@
<artifactId>jetty-io</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>

View File

@ -0,0 +1,394 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.http.gzip;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.Set;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import org.eclipse.jetty.util.StringUtil;
/* ------------------------------------------------------------ */
/**
*/
public class GzipResponseWrapper extends HttpServletResponseWrapper
{
private HttpServletRequest _request;
private Set<String> _mimeTypes;
private int _bufferSize=8192;
private int _minGzipSize=256;
private PrintWriter _writer;
private GzipStream _gzStream;
private long _contentLength=-1;
private boolean _noGzip;
/**
* Instantiates a new gzip response wrapper.
*
* @param request the request
* @param response the response
*/
public GzipResponseWrapper(HttpServletRequest request, HttpServletResponse response)
{
super(response);
_request=request;
}
/* ------------------------------------------------------------ */
/**
* Sets the mime types.
*
* @param mimeTypes the new mime types
*/
public void setMimeTypes(Set<String> mimeTypes)
{
_mimeTypes = mimeTypes;
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.ServletResponseWrapper#setBufferSize(int)
*/
public void setBufferSize(int bufferSize)
{
_bufferSize = bufferSize;
}
/* ------------------------------------------------------------ */
/**
* Sets the min gzip size.
*
* @param minGzipSize the new min gzip size
*/
public void setMinGzipSize(int minGzipSize)
{
_minGzipSize = minGzipSize;
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.ServletResponseWrapper#setContentType(java.lang.String)
*/
public void setContentType(String ct)
{
super.setContentType(ct);
if (ct!=null)
{
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 && (ct==null||!_mimeTypes.contains(StringUtil.asciiToLowerCase(ct)))))
{
noGzip();
}
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.http.HttpServletResponseWrapper#setStatus(int, java.lang.String)
*/
public void setStatus(int sc, String sm)
{
super.setStatus(sc,sm);
if (sc<200||sc>=300)
noGzip();
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.http.HttpServletResponseWrapper#setStatus(int)
*/
public void setStatus(int sc)
{
super.setStatus(sc);
if (sc<200||sc>=300)
noGzip();
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.ServletResponseWrapper#setContentLength(int)
*/
public void setContentLength(int length)
{
_contentLength=length;
if (_gzStream!=null)
_gzStream.setContentLength(length);
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.http.HttpServletResponseWrapper#addHeader(java.lang.String, java.lang.String)
*/
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);
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.http.HttpServletResponseWrapper#setHeader(java.lang.String, java.lang.String)
*/
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);
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.http.HttpServletResponseWrapper#setIntHeader(java.lang.String, int)
*/
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);
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.ServletResponseWrapper#flushBuffer()
*/
public void flushBuffer() throws IOException
{
if (_writer!=null)
_writer.flush();
if (_gzStream!=null)
_gzStream.finish();
else
getResponse().flushBuffer();
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.ServletResponseWrapper#reset()
*/
public void reset()
{
super.reset();
if (_gzStream!=null)
_gzStream.resetBuffer();
_writer=null;
_gzStream=null;
_noGzip=false;
_contentLength=-1;
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.ServletResponseWrapper#resetBuffer()
*/
public void resetBuffer()
{
super.resetBuffer();
if (_gzStream!=null)
_gzStream.resetBuffer();
_writer=null;
_gzStream=null;
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.http.HttpServletResponseWrapper#sendError(int, java.lang.String)
*/
public void sendError(int sc, String msg) throws IOException
{
resetBuffer();
super.sendError(sc,msg);
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.http.HttpServletResponseWrapper#sendError(int)
*/
public void sendError(int sc) throws IOException
{
resetBuffer();
super.sendError(sc);
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.http.HttpServletResponseWrapper#sendRedirect(java.lang.String)
*/
public void sendRedirect(String location) throws IOException
{
resetBuffer();
super.sendRedirect(location);
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.ServletResponseWrapper#getOutputStream()
*/
public ServletOutputStream getOutputStream() throws IOException
{
if (_gzStream==null)
{
if (getResponse().isCommitted() || _noGzip)
return getResponse().getOutputStream();
_gzStream=newGzipStream(_request,(HttpServletResponse)getResponse(),_contentLength,_bufferSize,_minGzipSize);
}
else if (_writer!=null)
throw new IllegalStateException("getWriter() called");
return _gzStream;
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.ServletResponseWrapper#getWriter()
*/
public PrintWriter getWriter() throws IOException
{
if (_writer==null)
{
if (_gzStream!=null)
throw new IllegalStateException("getOutputStream() called");
if (getResponse().isCommitted() || _noGzip)
return getResponse().getWriter();
_gzStream=newGzipStream(_request,(HttpServletResponse)getResponse(),_contentLength,_bufferSize,_minGzipSize);
_writer=newWriter(_gzStream,getCharacterEncoding());
}
return _writer;
}
/* ------------------------------------------------------------ */
/**
* No gzip.
*/
public void noGzip()
{
_noGzip=true;
if (_gzStream!=null)
{
try
{
_gzStream.doNotGzip();
}
catch (IOException e)
{
throw new IllegalStateException(e);
}
}
}
/* ------------------------------------------------------------ */
/**
* Finish.
*
* @throws IOException Signals that an I/O exception has occurred.
*/
public void finish() throws IOException
{
if (_writer!=null && !_gzStream._closed)
_writer.flush();
if (_gzStream!=null)
_gzStream.finish();
}
/* ------------------------------------------------------------ */
/**
* Allows derived implementations to replace GzipStream implementation.
*
* @param request the request
* @param response the response
* @param contentLength the content length
* @param bufferSize the buffer size
* @param minGzipSize the min gzip size
* @return the gzip stream
* @throws IOException Signals that an I/O exception has occurred.
*/
protected GzipStream newGzipStream(HttpServletRequest request,HttpServletResponse response,long contentLength,int bufferSize, int minGzipSize) throws IOException
{
return new GzipStream(request,response,contentLength,bufferSize,minGzipSize);
}
/* ------------------------------------------------------------ */
/**
* Allows derived implementations to replace PrintWriter implementation.
*
* @param out the out
* @param encoding the encoding
* @return the prints the writer
* @throws UnsupportedEncodingException the unsupported encoding exception
*/
protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
{
return encoding==null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding));
}
}

View File

@ -0,0 +1,300 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.http.gzip;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.zip.GZIPOutputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.util.ByteArrayOutputStream2;
/* ------------------------------------------------------------ */
/**
*/
public class GzipStream extends ServletOutputStream
{
protected HttpServletRequest _request;
protected HttpServletResponse _response;
protected OutputStream _out;
protected ByteArrayOutputStream2 _bOut;
protected GZIPOutputStream _gzOut;
protected boolean _closed;
protected int _bufferSize;
protected int _minGzipSize;
protected long _contentLength;
/**
* Instantiates a new gzip stream.
*
* @param request the request
* @param response the response
* @param contentLength the content length
* @param bufferSize the buffer size
* @param minGzipSize the min gzip size
* @throws IOException Signals that an I/O exception has occurred.
*/
public GzipStream(HttpServletRequest request,HttpServletResponse response,long contentLength,int bufferSize, int minGzipSize) throws IOException
{
_request=request;
_response=response;
_contentLength=contentLength;
_bufferSize=bufferSize;
_minGzipSize=minGzipSize;
if (minGzipSize==0)
doGzip();
}
/**
* Reset buffer.
*/
public void resetBuffer()
{
if (_response.isCommitted())
throw new IllegalStateException("Committed");
_closed=false;
_out=null;
_bOut=null;
if (_gzOut!=null)
_response.setHeader("Content-Encoding",null);
_gzOut=null;
}
/**
* Sets the content length.
*
* @param length the new content length
*/
public void setContentLength(long length)
{
_contentLength=length;
}
/* ------------------------------------------------------------ */
/**
* @see java.io.OutputStream#flush()
*/
public void flush() throws IOException
{
if (_out==null || _bOut!=null)
{
if (_contentLength>0 && _contentLength<_minGzipSize)
doNotGzip();
else
doGzip();
}
_out.flush();
}
/* ------------------------------------------------------------ */
/**
* @see java.io.OutputStream#close()
*/
public void close() throws IOException
{
if (_closed)
return;
if (_request.getAttribute("javax.servlet.include.request_uri")!=null)
flush();
else
{
if (_bOut!=null)
{
if (_contentLength<0)
_contentLength=_bOut.getCount();
if (_contentLength<_minGzipSize)
doNotGzip();
else
doGzip();
}
else if (_out==null)
{
doNotGzip();
}
if (_gzOut!=null)
_gzOut.close();
else
_out.close();
_closed=true;
}
}
/**
* Finish.
*
* @throws IOException Signals that an I/O exception has occurred.
*/
public void finish() throws IOException
{
if (!_closed)
{
if (_out==null || _bOut!=null)
{
if (_contentLength>0 && _contentLength<_minGzipSize)
doNotGzip();
else
doGzip();
}
if (_gzOut!=null && !_closed)
{
_closed=true;
_gzOut.close();
}
}
}
/* ------------------------------------------------------------ */
/**
* @see java.io.OutputStream#write(int)
*/
public void write(int b) throws IOException
{
checkOut(1);
_out.write(b);
}
/* ------------------------------------------------------------ */
/**
* @see java.io.OutputStream#write(byte[])
*/
public void write(byte b[]) throws IOException
{
checkOut(b.length);
_out.write(b);
}
/* ------------------------------------------------------------ */
/**
* @see java.io.OutputStream#write(byte[], int, int)
*/
public void write(byte b[], int off, int len) throws IOException
{
checkOut(len);
_out.write(b,off,len);
}
/**
* Sets the content encoding gzip.
*
* @return true, if successful
*/
protected boolean setContentEncodingGzip()
{
_response.setHeader("Content-Encoding", "gzip");
return _response.containsHeader("Content-Encoding");
}
/**
* Do gzip.
*
* @throws IOException Signals that an I/O exception has occurred.
*/
public void doGzip() throws IOException
{
if (_gzOut==null)
{
if (_response.isCommitted())
throw new IllegalStateException();
if (setContentEncodingGzip())
{
_out=_gzOut=new GZIPOutputStream(_response.getOutputStream(),_bufferSize);
if (_bOut!=null)
{
_out.write(_bOut.getBuf(),0,_bOut.getCount());
_bOut=null;
}
}
else
doNotGzip();
}
}
/**
* Do not gzip.
*
* @throws IOException Signals that an I/O exception has occurred.
*/
public void doNotGzip() throws IOException
{
if (_gzOut!=null)
throw new IllegalStateException();
if (_out==null || _bOut!=null )
{
_out=_response.getOutputStream();
if (_contentLength>=0)
{
if(_contentLength<Integer.MAX_VALUE)
_response.setContentLength((int)_contentLength);
else
_response.setHeader("Content-Length",Long.toString(_contentLength));
}
if (_bOut!=null)
_out.write(_bOut.getBuf(),0,_bOut.getCount());
_bOut=null;
}
}
/**
* Check out.
*
* @param length the length
* @throws IOException Signals that an I/O exception has occurred.
*/
private void checkOut(int length) throws IOException
{
if (_closed)
throw new IOException("CLOSED");
if (_out==null)
{
if (_response.isCommitted() || (_contentLength>=0 && _contentLength<_minGzipSize))
doNotGzip();
else if (length>_minGzipSize)
doGzip();
else
_out=_bOut=new ByteArrayOutputStream2(_bufferSize);
}
else if (_bOut!=null)
{
if (_response.isCommitted() || (_contentLength>=0 && _contentLength<_minGzipSize))
doNotGzip();
else if (length>=(_bOut.getBuf().length -_bOut.getCount()))
doGzip();
}
}
/**
* Allows derived implementations to replace PrintWriter implementation.
*/
protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
{
return encoding==null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding));
}
}

View File

@ -21,21 +21,17 @@ import java.io.UnsupportedEncodingException;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.zip.GZIPOutputStream;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import org.eclipse.jetty.continuation.Continuation;
import org.eclipse.jetty.continuation.ContinuationListener;
import org.eclipse.jetty.continuation.ContinuationSupport;
import org.eclipse.jetty.http.HttpMethods;
import org.eclipse.jetty.http.gzip.GzipResponseWrapper;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.util.ByteArrayOutputStream2;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.log.Log;
/* ------------------------------------------------------------ */
@ -64,6 +60,7 @@ public class GzipHandler extends HandlerWrapper
/* ------------------------------------------------------------ */
/**
* Instantiates a new gzip handler.
*/
public GzipHandler()
{
@ -199,6 +196,10 @@ public class GzipHandler extends HandlerWrapper
_minGzipSize = minGzipSize;
}
/* ------------------------------------------------------------ */
/**
* @see org.eclipse.jetty.server.handler.HandlerWrapper#handle(java.lang.String, org.eclipse.jetty.server.Request, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
@ -218,7 +219,7 @@ public class GzipHandler extends HandlerWrapper
}
}
final GZIPResponseWrapper wrappedResponse = newGZIPResponseWrapper(request,response);
final GzipResponseWrapper wrappedResponse = newGzipResponseWrapper(request,response);
boolean exceptional=true;
try
@ -265,435 +266,41 @@ public class GzipHandler extends HandlerWrapper
}
}
protected GZIPResponseWrapper newGZIPResponseWrapper(HttpServletRequest request, HttpServletResponse response)
/**
* Allows derived implementations to replace ResponseWrapper implementation.
*
* @param request the request
* @param response the response
* @return the gzip response wrapper
*/
protected GzipResponseWrapper newGzipResponseWrapper(HttpServletRequest request, HttpServletResponse response)
{
return new GZIPResponseWrapper(request,response);
return new GzipResponseWrapper(request, response)
{
{
_mimeTypes = GzipHandler.this._mimeTypes;
_bufferSize = GzipHandler.this._bufferSize;
_minGzipSize = GzipHandler.this._minGzipSize;
}
/*
* Allows derived implementations to replace PrintWriter implementation
@Override
protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
{
return GzipHandler.this.newWriter(out,encoding);
}
};
}
/**
* Allows derived implementations to replace PrintWriter implementation.
*
* @param out the out
* @param encoding the encoding
* @return the prints the writer
* @throws UnsupportedEncodingException
*/
protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
{
return encoding==null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding));
}
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);
if (ct != null)
{
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
&& (ct == 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;
_contentLength = -1;
}
public void resetBuffer()
{
super.resetBuffer();
if (_gzStream != null)
_gzStream.resetBuffer();
_writer = null;
_gzStream = null;
}
public void sendError(int sc, String msg) throws IOException
{
resetBuffer();
super.sendError(sc,msg);
}
public void sendError(int sc) throws IOException
{
resetBuffer();
super.sendError(sc);
}
public void sendRedirect(String location) throws IOException
{
resetBuffer();
super.sendRedirect(location);
}
public ServletOutputStream getOutputStream() throws IOException
{
if (_gzStream == null)
{
if (getResponse().isCommitted() || _noGzip)
return getResponse().getOutputStream();
_gzStream = newGzipStream(_request,(HttpServletResponse)getResponse(),_contentLength,_bufferSize,_minGzipSize);
}
else if (_writer != null)
throw new IllegalStateException("getWriter() called");
return _gzStream;
}
public PrintWriter getWriter() throws IOException
{
if (_writer == null)
{
if (_gzStream != null)
throw new IllegalStateException("getOutputStream() called");
if (getResponse().isCommitted() || _noGzip)
return getResponse().getWriter();
_gzStream = newGzipStream(_request,(HttpServletResponse)getResponse(),_contentLength,_bufferSize,_minGzipSize);
_writer = newWriter(_gzStream,getCharacterEncoding());
}
return _writer;
}
void noGzip()
{
_noGzip = true;
if (_gzStream != null)
{
try
{
_gzStream.doNotGzip();
}
catch (IOException e)
{
throw new IllegalStateException(e);
}
}
}
void finish() throws IOException
{
if (_writer != null && !_gzStream._closed)
_writer.flush();
if (_gzStream != null)
_gzStream.finish();
}
protected GzipStream newGzipStream(HttpServletRequest request, HttpServletResponse response, long contentLength, int bufferSize, int minGzipSize)
throws IOException
{
return new GzipStream(request,response,contentLength,bufferSize,minGzipSize);
}
}
public static class GzipStream extends ServletOutputStream
{
protected HttpServletRequest _request;
protected HttpServletResponse _response;
protected OutputStream _out;
protected ByteArrayOutputStream2 _bOut;
protected GZIPOutputStream _gzOut;
protected boolean _closed;
protected int _bufferSize;
protected int _minGzipSize;
protected long _contentLength;
public GzipStream(HttpServletRequest request, HttpServletResponse response, long contentLength, int bufferSize, int minGzipSize) throws IOException
{
_request = request;
_response = response;
_contentLength = contentLength;
_bufferSize = bufferSize;
_minGzipSize = minGzipSize;
if (minGzipSize == 0)
doGzip();
}
public void resetBuffer()
{
if (_response.isCommitted())
throw new IllegalStateException("Committed");
_closed = false;
_out = null;
_bOut = null;
if (_gzOut != null)
_response.setHeader("Content-Encoding",null);
_gzOut = null;
}
public void setContentLength(long length)
{
_contentLength = length;
}
public void flush() throws IOException
{
if (_out == null || _bOut != null)
{
if (_contentLength > 0 && _contentLength < _minGzipSize)
doNotGzip();
else
doGzip();
}
_out.flush();
}
public void close() throws IOException
{
if (_closed)
return;
if (_request.getAttribute("javax.servlet.include.request_uri") != null)
flush();
else
{
if (_bOut != null)
{
if (_contentLength < 0)
_contentLength = _bOut.getCount();
if (_contentLength < _minGzipSize)
doNotGzip();
else
doGzip();
}
else if (_out == null)
{
doNotGzip();
}
if (_gzOut != null)
_gzOut.close();
else
_out.close();
_closed = true;
}
}
public void finish() throws IOException
{
if (!_closed)
{
if (_out == null || _bOut != null)
{
if (_contentLength > 0 && _contentLength < _minGzipSize)
doNotGzip();
else
doGzip();
}
if (_gzOut != null && !_closed)
{
_closed = true;
_gzOut.close();
}
}
}
public void write(int b) throws IOException
{
checkOut(1);
_out.write(b);
}
public void write(byte b[]) throws IOException
{
checkOut(b.length);
_out.write(b);
}
public void write(byte b[], int off, int len) throws IOException
{
checkOut(len);
_out.write(b,off,len);
}
protected boolean setContentEncodingGzip()
{
_response.setHeader("Content-Encoding","gzip");
return _response.containsHeader("Content-Encoding");
}
public void doGzip() throws IOException
{
if (_gzOut == null)
{
if (_response.isCommitted())
throw new IllegalStateException();
if (setContentEncodingGzip())
{
_out = _gzOut = new GZIPOutputStream(_response.getOutputStream(),_bufferSize);
if (_bOut != null)
{
_out.write(_bOut.getBuf(),0,_bOut.getCount());
_bOut = null;
}
}
else
doNotGzip();
}
}
public void doNotGzip() throws IOException
{
if (_gzOut != null)
throw new IllegalStateException();
if (_out == null || _bOut != null)
{
_out = _response.getOutputStream();
if (_contentLength >= 0)
{
if (_contentLength < Integer.MAX_VALUE)
_response.setContentLength((int)_contentLength);
else
_response.setHeader("Content-Length",Long.toString(_contentLength));
}
if (_bOut != null)
_out.write(_bOut.getBuf(),0,_bOut.getCount());
_bOut = null;
}
}
private void checkOut(int length) throws IOException
{
if (_closed)
throw new IOException("CLOSED");
if (_out == null)
{
if (_response.isCommitted() || (_contentLength >= 0 && _contentLength < _minGzipSize))
doNotGzip();
else if (length > _minGzipSize)
doGzip();
else
_out = _bOut = new ByteArrayOutputStream2(_bufferSize);
}
else if (_bOut != null)
{
if (_response.isCommitted() || (_contentLength >= 0 && _contentLength < _minGzipSize))
doNotGzip();
else if (length >= (_bOut.getBuf().length - _bOut.getCount()))
doGzip();
}
}
}
}

View File

@ -1,537 +0,0 @@
// ========================================================================
// Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.server.handler;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.http.Cookie;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpGenerator;
import org.eclipse.jetty.http.HttpHeaders;
import org.eclipse.jetty.http.HttpParser;
import org.eclipse.jetty.http.HttpVersions;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.io.SimpleBuffers;
import org.eclipse.jetty.io.View;
import org.eclipse.jetty.io.bio.StringEndPoint;
import org.eclipse.jetty.util.ByteArrayOutputStream2;
/* ------------------------------------------------------------ */
/** Test support class.
* Assist with parsing and generating HTTP requests and responses.
*
* <pre>
* HttpTester tester = new HttpTester();
*
* tester.parse(
* "GET /uri HTTP/1.1\r\n"+
* "Host: fakehost\r\n"+
* "Content-Length: 10\r\n" +
* "\r\n");
*
* System.err.println(tester.getMethod());
* System.err.println(tester.getURI());
* System.err.println(tester.getVersion());
* System.err.println(tester.getHeader("Host"));
* System.err.println(tester.getContent());
* </pre>
*
*
* @see org.eclipse.jetty.testing.ServletTester
*/
public class HttpTester
{
protected HttpFields _fields=new HttpFields();
protected String _method;
protected String _uri;
protected String _version;
protected int _status;
protected String _reason;
protected ByteArrayOutputStream2 _parsedContent;
protected byte[] _genContent;
private String _charset, _defaultCharset;
private Buffer _contentType;
public HttpTester()
{
this("UTF-8");
}
public HttpTester(String charset)
{
_defaultCharset = charset;
}
public void reset()
{
_fields.clear();
_method=null;
_uri=null;
_version=null;
_status=0;
_reason=null;
_parsedContent=null;
_genContent=null;
}
private String getString(Buffer buffer)
{
return getString(buffer.asArray());
}
private String getString(byte[] b)
{
if(_charset==null)
return new String(b);
try
{
return new String(b, _charset);
}
catch(Exception e)
{
return new String(b);
}
}
private byte[] getByteArray(String str)
{
if(_charset==null)
return str.getBytes();
try
{
return str.getBytes(_charset);
}
catch(Exception e)
{
return str.getBytes();
}
}
/* ------------------------------------------------------------ */
/**
* Parse one HTTP request or response
* @param rawHTTP Raw HTTP to parse
* @return Any unparsed data in the rawHTTP (eg pipelined requests)
* @throws IOException
*/
public String parse(String rawHTTP) throws IOException
{
_charset = _defaultCharset;
ByteArrayBuffer buf = new ByteArrayBuffer(getByteArray(rawHTTP));
View view = new View(buf);
HttpParser parser = new HttpParser(view,new PH());
parser.parse();
return getString(view.asArray());
}
/* ------------------------------------------------------------ */
/**
* Parse one HTTP request or response
* @param rawHTTP Raw HTTP to parse
* @return Any unparsed data in the rawHTTP (eg pipelined requests)
* @throws IOException
*/
public byte[] parse(byte[] rawHTTP) throws IOException
{
_charset = _defaultCharset;
ByteArrayBuffer buf = new ByteArrayBuffer(rawHTTP);
View view = new View(buf);
HttpParser parser = new HttpParser(view,new PH());
parser.parse();
return view.asArray();
}
/* ------------------------------------------------------------ */
public String generate() throws IOException
{
_charset = _defaultCharset;
_contentType = _fields.get(HttpHeaders.CONTENT_TYPE_BUFFER);
if(_contentType!=null)
{
String charset = MimeTypes.getCharsetFromContentType(_contentType);
if(charset!=null)
_charset = charset;
}
Buffer bb=new ByteArrayBuffer(32*1024 + (_genContent!=null?_genContent.length:0));
Buffer sb=new ByteArrayBuffer(4*1024);
StringEndPoint endp = new StringEndPoint(_charset);
HttpGenerator generator = new HttpGenerator(new SimpleBuffers(sb,bb),endp);
if (_method!=null)
{
generator.setRequest(getMethod(),getURI());
if (_version==null)
generator.setVersion(HttpVersions.HTTP_1_1_ORDINAL);
else
generator.setVersion(HttpVersions.CACHE.getOrdinal(HttpVersions.CACHE.lookup(_version)));
generator.completeHeader(_fields,false);
if (_genContent!=null)
generator.addContent(new View(new ByteArrayBuffer(_genContent)),false);
else if (_parsedContent!=null)
generator.addContent(new ByteArrayBuffer(_parsedContent.toByteArray()),false);
}
generator.complete();
generator.flushBuffer();
return endp.getOutput();
}
/* ------------------------------------------------------------ */
/**
* @return the method
*/
public String getMethod()
{
return _method;
}
/* ------------------------------------------------------------ */
/**
* @param method the method to set
*/
public void setMethod(String method)
{
_method=method;
}
/* ------------------------------------------------------------ */
/**
* @return the reason
*/
public String getReason()
{
return _reason;
}
/* ------------------------------------------------------------ */
/**
* @param reason the reason to set
*/
public void setReason(String reason)
{
_reason=reason;
}
/* ------------------------------------------------------------ */
/**
* @return the status
*/
public int getStatus()
{
return _status;
}
/* ------------------------------------------------------------ */
/**
* @param status the status to set
*/
public void setStatus(int status)
{
_status=status;
}
/* ------------------------------------------------------------ */
/**
* @return the uri
*/
public String getURI()
{
return _uri;
}
/* ------------------------------------------------------------ */
/**
* @param uri the uri to set
*/
public void setURI(String uri)
{
_uri=uri;
}
/* ------------------------------------------------------------ */
/**
* @return the version
*/
public String getVersion()
{
return _version;
}
/* ------------------------------------------------------------ */
/**
* @param version the version to set
*/
public void setVersion(String version)
{
_version=version;
}
/* ------------------------------------------------------------ */
public String getContentType()
{
return getString(_contentType);
}
/* ------------------------------------------------------------ */
public String getCharacterEncoding()
{
return _charset;
}
/* ------------------------------------------------------------ */
/**
* @param name
* @param value
* @throws IllegalArgumentException
* @see org.eclipse.jetty.http.HttpFields#add(java.lang.String, java.lang.String)
*/
public void addHeader(String name, String value) throws IllegalArgumentException
{
_fields.add(name,value);
}
/* ------------------------------------------------------------ */
/**
* @param name
* @param date
* @see org.eclipse.jetty.http.HttpFields#addDateField(java.lang.String, long)
*/
public void addDateHeader(String name, long date)
{
_fields.addDateField(name,date);
}
/* ------------------------------------------------------------ */
/**
* @param name
* @param value
* @see org.eclipse.jetty.http.HttpFields#addLongField(java.lang.String, long)
*/
public void addLongHeader(String name, long value)
{
_fields.addLongField(name,value);
}
/* ------------------------------------------------------------ */
/**
* @param cookie
* @see org.eclipse.jetty.http.HttpFields#addSetCookie(org.eclipse.jetty.http.HttpCookie)
*/
public void addSetCookie(Cookie cookie)
{
_fields.addSetCookie(
cookie.getName(),
cookie.getValue(),
cookie.getDomain(),
cookie.getPath(),
cookie.getMaxAge(),
cookie.getComment(),
cookie.getSecure(),
false,
cookie.getVersion());
}
/* ------------------------------------------------------------ */
/**
* @param name
* @return the header value as a date
* @see org.eclipse.jetty.http.HttpFields#getDateField(java.lang.String)
*/
public long getDateHeader(String name)
{
return _fields.getDateField(name);
}
/* ------------------------------------------------------------ */
/**
* @return the header value names
* @see org.eclipse.jetty.http.HttpFields#getFieldNames()
*/
public Enumeration getHeaderNames()
{
return _fields.getFieldNames();
}
/* ------------------------------------------------------------ */
/**
* @param name
* @return the header value as a long
* @throws NumberFormatException
* @see org.eclipse.jetty.http.HttpFields#getLongField(java.lang.String)
*/
public long getLongHeader(String name) throws NumberFormatException
{
return _fields.getLongField(name);
}
/* ------------------------------------------------------------ */
/**
* @param name
* @return the header value
* @see org.eclipse.jetty.http.HttpFields#getStringField(java.lang.String)
*/
public String getHeader(String name)
{
return _fields.getStringField(name);
}
/* ------------------------------------------------------------ */
/**
* @param name
* @return the header values
* @see org.eclipse.jetty.http.HttpFields#getValues(java.lang.String)
*/
public Enumeration getHeaderValues(String name)
{
return _fields.getValues(name);
}
/* ------------------------------------------------------------ */
/**
* @param name
* @param value
* @see org.eclipse.jetty.http.HttpFields#put(java.lang.String, java.lang.String)
*/
public void setHeader(String name, String value)
{
_fields.put(name,value);
}
/* ------------------------------------------------------------ */
/**
* @param name
* @param date
* @see org.eclipse.jetty.http.HttpFields#putDateField(java.lang.String, long)
*/
public void setDateHeader(String name, long date)
{
_fields.putDateField(name,date);
}
/* ------------------------------------------------------------ */
/**
* @param name
* @param value
* @see org.eclipse.jetty.http.HttpFields#putLongField(java.lang.String, long)
*/
public void setLongHeader(String name, long value)
{
_fields.putLongField(name,value);
}
/* ------------------------------------------------------------ */
/**
* @param name
* @see org.eclipse.jetty.http.HttpFields#remove(java.lang.String)
*/
public void removeHeader(String name)
{
_fields.remove(name);
}
/* ------------------------------------------------------------ */
public String getContent()
{
if (_parsedContent!=null)
return getString(_parsedContent.toByteArray());
if (_genContent!=null)
return getString(_genContent);
return null;
}
/* ------------------------------------------------------------ */
public byte[] getContentBytes()
{
if (_parsedContent!=null)
return _parsedContent.toByteArray();
if (_genContent!=null)
return _genContent;
return null;
}
/* ------------------------------------------------------------ */
public void setContent(String content)
{
_parsedContent=null;
if (content!=null)
{
_genContent=getByteArray(content);
setLongHeader(HttpHeaders.CONTENT_LENGTH,_genContent.length);
}
else
{
removeHeader(HttpHeaders.CONTENT_LENGTH);
_genContent=null;
}
}
/* ------------------------------------------------------------ */
private class PH extends HttpParser.EventHandler
{
@Override
public void startRequest(Buffer method, Buffer url, Buffer version) throws IOException
{
reset();
_method=getString(method);
_uri=getString(url);
_version=getString(version);
}
@Override
public void startResponse(Buffer version, int status, Buffer reason) throws IOException
{
reset();
_version=getString(version);
_status=status;
_reason=getString(reason);
}
@Override
public void parsedHeader(Buffer name, Buffer value) throws IOException
{
_fields.add(name,value);
}
@Override
public void headerComplete() throws IOException
{
_contentType = _fields.get(HttpHeaders.CONTENT_TYPE_BUFFER);
if(_contentType!=null)
{
String charset = MimeTypes.getCharsetFromContentType(_contentType);
if(charset!=null)
_charset = charset;
}
}
@Override
public void messageComplete(long contextLength) throws IOException
{
}
@Override
public void content(Buffer ref) throws IOException
{
if (_parsedContent==null)
_parsedContent=new ByteArrayOutputStream2();
_parsedContent.write(ref.asArray());
}
}
}

View File

@ -20,24 +20,20 @@ import java.io.UnsupportedEncodingException;
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.eclipse.jetty.continuation.Continuation;
import org.eclipse.jetty.continuation.ContinuationListener;
import org.eclipse.jetty.continuation.ContinuationSupport;
import org.eclipse.jetty.http.HttpMethods;
import org.eclipse.jetty.util.ByteArrayOutputStream2;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.http.gzip.GzipResponseWrapper;
import org.eclipse.jetty.util.log.Log;
/* ------------------------------------------------------------ */
@ -65,11 +61,15 @@ import org.eclipse.jetty.util.log.Log;
*/
public class GzipFilter extends UserAgentFilter
{
protected Set _mimeTypes;
protected Set<String> _mimeTypes;
protected int _bufferSize=8192;
protected int _minGzipSize=256;
protected Set _excluded;
protected Set<String> _excluded;
/* ------------------------------------------------------------ */
/**
* @see org.eclipse.jetty.servlets.UserAgentFilter#init(javax.servlet.FilterConfig)
*/
public void init(FilterConfig filterConfig) throws ServletException
{
super.init(filterConfig);
@ -85,7 +85,7 @@ public class GzipFilter extends UserAgentFilter
tmp=filterConfig.getInitParameter("mimeTypes");
if (tmp!=null)
{
_mimeTypes=new HashSet();
_mimeTypes=new HashSet<String>();
StringTokenizer tok = new StringTokenizer(tmp,",",false);
while (tok.hasMoreTokens())
_mimeTypes.add(tok.nextToken());
@ -94,17 +94,25 @@ public class GzipFilter extends UserAgentFilter
tmp=filterConfig.getInitParameter("excludedAgents");
if (tmp!=null)
{
_excluded=new HashSet();
_excluded=new HashSet<String>();
StringTokenizer tok = new StringTokenizer(tmp,",",false);
while (tok.hasMoreTokens())
_excluded.add(tok.nextToken());
}
}
/* ------------------------------------------------------------ */
/**
* @see org.eclipse.jetty.servlets.UserAgentFilter#destroy()
*/
public void destroy()
{
}
/* ------------------------------------------------------------ */
/**
* @see org.eclipse.jetty.servlets.UserAgentFilter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
*/
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException
{
@ -125,7 +133,7 @@ public class GzipFilter extends UserAgentFilter
}
}
final GZIPResponseWrapper wrappedResponse=newGZIPResponseWrapper(request,response);
final GzipResponseWrapper wrappedResponse=newGzipResponseWrapper(request,response);
boolean exceptional=true;
try
@ -171,436 +179,41 @@ public class GzipFilter extends UserAgentFilter
}
}
protected GZIPResponseWrapper newGZIPResponseWrapper(HttpServletRequest request, HttpServletResponse response)
/**
* Allows derived implementations to replace ResponseWrapper implementation.
*
* @param request the request
* @param response the response
* @return the gzip response wrapper
*/
protected GzipResponseWrapper newGzipResponseWrapper(HttpServletRequest request, HttpServletResponse response)
{
return new GZIPResponseWrapper(request,response);
return new GzipResponseWrapper(request, response)
{
{
_mimeTypes = GzipFilter.this._mimeTypes;
_bufferSize = GzipFilter.this._bufferSize;
_minGzipSize = GzipFilter.this._minGzipSize;
}
/*
* Allows derived implementations to replace PrintWriter implementation
@Override
protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
{
return GzipFilter.this.newWriter(out,encoding);
}
};
}
/**
* Allows derived implementations to replace PrintWriter implementation.
*
* @param out the out
* @param encoding the encoding
* @return the prints the writer
* @throws UnsupportedEncodingException
*/
protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
{
return encoding==null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding));
}
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);
if (ct!=null)
{
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 && (ct==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;
_contentLength=-1;
}
public void resetBuffer()
{
super.resetBuffer();
if (_gzStream!=null)
_gzStream.resetBuffer();
_writer=null;
_gzStream=null;
}
public void sendError(int sc, String msg) throws IOException
{
resetBuffer();
super.sendError(sc,msg);
}
public void sendError(int sc) throws IOException
{
resetBuffer();
super.sendError(sc);
}
public void sendRedirect(String location) throws IOException
{
resetBuffer();
super.sendRedirect(location);
}
public ServletOutputStream getOutputStream() throws IOException
{
if (_gzStream==null)
{
if (getResponse().isCommitted() || _noGzip)
return getResponse().getOutputStream();
_gzStream=newGzipStream(_request,(HttpServletResponse)getResponse(),_contentLength,_bufferSize,_minGzipSize);
}
else if (_writer!=null)
throw new IllegalStateException("getWriter() called");
return _gzStream;
}
public PrintWriter getWriter() throws IOException
{
if (_writer==null)
{
if (_gzStream!=null)
throw new IllegalStateException("getOutputStream() called");
if (getResponse().isCommitted() || _noGzip)
return getResponse().getWriter();
_gzStream=newGzipStream(_request,(HttpServletResponse)getResponse(),_contentLength,_bufferSize,_minGzipSize);
_writer=newWriter(_gzStream,getCharacterEncoding());
}
return _writer;
}
void noGzip()
{
_noGzip=true;
if (_gzStream!=null)
{
try
{
_gzStream.doNotGzip();
}
catch (IOException e)
{
throw new IllegalStateException(e);
}
}
}
void finish() throws IOException
{
if (_writer!=null && !_gzStream._closed)
_writer.flush();
if (_gzStream!=null)
_gzStream.finish();
}
protected GzipStream newGzipStream(HttpServletRequest request,HttpServletResponse response,long contentLength,int bufferSize, int minGzipSize) throws IOException
{
return new GzipStream(request,response,contentLength,bufferSize,minGzipSize);
}
}
public static class GzipStream extends ServletOutputStream
{
protected HttpServletRequest _request;
protected HttpServletResponse _response;
protected OutputStream _out;
protected ByteArrayOutputStream2 _bOut;
protected GZIPOutputStream _gzOut;
protected boolean _closed;
protected int _bufferSize;
protected int _minGzipSize;
protected long _contentLength;
public GzipStream(HttpServletRequest request,HttpServletResponse response,long contentLength,int bufferSize, int minGzipSize) throws IOException
{
_request=request;
_response=response;
_contentLength=contentLength;
_bufferSize=bufferSize;
_minGzipSize=minGzipSize;
if (minGzipSize==0)
doGzip();
}
public void resetBuffer()
{
if (_response.isCommitted())
throw new IllegalStateException("Committed");
_closed=false;
_out=null;
_bOut=null;
if (_gzOut!=null)
_response.setHeader("Content-Encoding",null);
_gzOut=null;
}
public void setContentLength(long length)
{
_contentLength=length;
}
public void flush() throws IOException
{
if (_out==null || _bOut!=null)
{
if (_contentLength>0 && _contentLength<_minGzipSize)
doNotGzip();
else
doGzip();
}
_out.flush();
}
public void close() throws IOException
{
if (_closed)
return;
if (_request.getAttribute("javax.servlet.include.request_uri")!=null)
flush();
else
{
if (_bOut!=null)
{
if (_contentLength<0)
_contentLength=_bOut.getCount();
if (_contentLength<_minGzipSize)
doNotGzip();
else
doGzip();
}
else if (_out==null)
{
doNotGzip();
}
if (_gzOut!=null)
_gzOut.close();
else
_out.close();
_closed=true;
}
}
public void finish() throws IOException
{
if (!_closed)
{
if (_out==null || _bOut!=null)
{
if (_contentLength>0 && _contentLength<_minGzipSize)
doNotGzip();
else
doGzip();
}
if (_gzOut!=null && !_closed)
{
_closed=true;
_gzOut.close();
}
}
}
public void write(int b) throws IOException
{
checkOut(1);
_out.write(b);
}
public void write(byte b[]) throws IOException
{
checkOut(b.length);
_out.write(b);
}
public void write(byte b[], int off, int len) throws IOException
{
checkOut(len);
_out.write(b,off,len);
}
protected boolean setContentEncodingGzip()
{
_response.setHeader("Content-Encoding", "gzip");
return _response.containsHeader("Content-Encoding");
}
public void doGzip() throws IOException
{
if (_gzOut==null)
{
if (_response.isCommitted())
throw new IllegalStateException();
if (setContentEncodingGzip())
{
_out=_gzOut=new GZIPOutputStream(_response.getOutputStream(),_bufferSize);
if (_bOut!=null)
{
_out.write(_bOut.getBuf(),0,_bOut.getCount());
_bOut=null;
}
}
else
doNotGzip();
}
}
public void doNotGzip() throws IOException
{
if (_gzOut!=null)
throw new IllegalStateException();
if (_out==null || _bOut!=null )
{
_out=_response.getOutputStream();
if (_contentLength>=0)
{
if(_contentLength<Integer.MAX_VALUE)
_response.setContentLength((int)_contentLength);
else
_response.setHeader("Content-Length",Long.toString(_contentLength));
}
if (_bOut!=null)
_out.write(_bOut.getBuf(),0,_bOut.getCount());
_bOut=null;
}
}
private void checkOut(int length) throws IOException
{
if (_closed)
throw new IOException("CLOSED");
if (_out==null)
{
if (_response.isCommitted() || (_contentLength>=0 && _contentLength<_minGzipSize))
doNotGzip();
else if (length>_minGzipSize)
doGzip();
else
_out=_bOut=new ByteArrayOutputStream2(_bufferSize);
}
else if (_bOut!=null)
{
if (_response.isCommitted() || (_contentLength>=0 && _contentLength<_minGzipSize))
doNotGzip();
else if (length>=(_bOut.getBuf().length -_bOut.getCount()))
doGzip();
}
}
}
}

View File

@ -24,6 +24,8 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.gzip.GzipResponseWrapper;
import org.eclipse.jetty.http.gzip.GzipStream;
import org.eclipse.jetty.io.UncheckedPrintWriter;
@ -55,16 +57,20 @@ public class IncludableGzipFilter extends GzipFilter
}
@Override
protected GZIPResponseWrapper newGZIPResponseWrapper(HttpServletRequest request, HttpServletResponse response)
protected GzipResponseWrapper newGzipResponseWrapper(HttpServletRequest request, HttpServletResponse response)
{
return new IncludableResponseWrapper(request,response);
}
public class IncludableResponseWrapper extends GzipFilter.GZIPResponseWrapper
public class IncludableResponseWrapper extends GzipResponseWrapper
{
public IncludableResponseWrapper(HttpServletRequest request, HttpServletResponse response)
{
super(request,response);
_mimeTypes = IncludableGzipFilter.this._mimeTypes;
_bufferSize = IncludableGzipFilter.this._bufferSize;
_minGzipSize = IncludableGzipFilter.this._minGzipSize;
}
@Override
@ -72,9 +78,15 @@ public class IncludableGzipFilter extends GzipFilter
{
return new IncludableGzipStream(request,response,contentLength,bufferSize,minGzipSize);
}
@Override
protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
{
return IncludableGzipFilter.this.newWriter(out,encoding);
}
}
public class IncludableGzipStream extends GzipFilter.GzipStream
public class IncludableGzipStream extends GzipStream
{
public IncludableGzipStream(HttpServletRequest request, HttpServletResponse response, long contentLength, int bufferSize, int minGzipSize)
throws IOException

View File

@ -13,21 +13,15 @@
package org.eclipse.jetty.servlets;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringReader;
import java.net.Socket;
import java.net.URL;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.zip.GZIPInputStream;
import javax.servlet.http.HttpServletResponse;
@ -43,9 +37,6 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class GzipFilterTest
{
private static String __content =

View File

@ -0,0 +1,115 @@
// ========================================================================
// Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.servlets;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.zip.GZIPInputStream;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.testing.HttpTester;
import org.eclipse.jetty.testing.ServletTester;
import org.eclipse.jetty.toolchain.test.TestingDir;
import org.eclipse.jetty.util.IO;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
public class IncludableGzipFilterTest
{
private static String __content =
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. In quis felis nunc. "+
"Quisque suscipit mauris et ante auctor ornare rhoncus lacus aliquet. Pellentesque "+
"habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. "+
"Vestibulum sit amet felis augue, vel convallis dolor. Cras accumsan vehicula diam "+
"at faucibus. Etiam in urna turpis, sed congue mi. Morbi et lorem eros. Donec vulputate "+
"velit in risus suscipit lobortis. Aliquam id urna orci, nec sollicitudin ipsum. "+
"Cras a orci turpis. Donec suscipit vulputate cursus. Mauris nunc tellus, fermentum "+
"eu auctor ut, mollis at diam. Quisque porttitor ultrices metus, vitae tincidunt massa "+
"sollicitudin a. Vivamus porttitor libero eget purus hendrerit cursus. Integer aliquam "+
"consequat mauris quis luctus. Cras enim nibh, dignissim eu faucibus ac, mollis nec neque. "+
"Aliquam purus mauris, consectetur nec convallis lacinia, porta sed ante. Suspendisse "+
"et cursus magna. Donec orci enim, molestie a lobortis eu, imperdiet vitae neque.";
@Rule
public TestingDir testdir = new TestingDir();
private ServletTester tester;
@Before
public void setUp() throws Exception
{
testdir.ensureEmpty();
File testFile = testdir.getFile("file.txt");
BufferedOutputStream testOut = new BufferedOutputStream(new FileOutputStream(testFile));
ByteArrayInputStream testIn = new ByteArrayInputStream(__content.getBytes("ISO8859_1"));
IO.copy(testIn,testOut);
testOut.close();
tester=new ServletTester();
tester.setContextPath("/context");
tester.setResourceBase(testdir.getDir().getCanonicalPath());
tester.addServlet(org.eclipse.jetty.servlet.DefaultServlet.class, "/");
FilterHolder holder = tester.addFilter(IncludableGzipFilter.class,"/*",0);
holder.setInitParameter("mimeTypes","text/plain");
tester.start();
}
@After
public void tearDown() throws Exception
{
tester.stop();
IO.delete(testdir.getDir());
}
@Test
public void testGzipFilter() throws Exception
{
// generated and parsed test
HttpTester request = new HttpTester();
HttpTester response = new HttpTester();
request.setMethod("GET");
request.setVersion("HTTP/1.0");
request.setHeader("Host","tester");
request.setHeader("accept-encoding","gzip");
request.setURI("/context/file.txt");
ByteArrayBuffer reqsBuff = new ByteArrayBuffer(request.generate().getBytes());
ByteArrayBuffer respBuff = tester.getResponses(reqsBuff);
response.parse(respBuff.asArray());
assertTrue(response.getMethod()==null);
assertTrue(response.getHeader("Content-Encoding").equalsIgnoreCase("gzip"));
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
InputStream testIn = new GZIPInputStream(new ByteArrayInputStream(response.getContentBytes()));
ByteArrayOutputStream testOut = new ByteArrayOutputStream();
IO.copy(testIn,testOut);
assertEquals(__content, testOut.toString("ISO8859_1"));
}
}