diff options
author | Greg Wilkins | 2013-12-04 23:52:32 +0000 |
---|---|---|
committer | Greg Wilkins | 2013-12-04 23:52:32 +0000 |
commit | e9df551352936d7e127480591b13a3f1efe1b75f (patch) | |
tree | e8e74e8ac4148d4f87cbe04626abf5e91447fd98 | |
parent | 9c39b2e631ba8ae06154d1c5d3bf03ccaba8239f (diff) | |
download | org.eclipse.jetty.project-e9df551352936d7e127480591b13a3f1efe1b75f.tar.gz org.eclipse.jetty.project-e9df551352936d7e127480591b13a3f1efe1b75f.tar.xz org.eclipse.jetty.project-e9df551352936d7e127480591b13a3f1efe1b75f.zip |
423005 reuse gzipfilter buffers
4 files changed, 111 insertions, 21 deletions
diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java index 6f6da63007..f1c827f18e 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java @@ -20,13 +20,13 @@ package org.eclipse.jetty.servlets; import java.io.File; import java.io.IOException; +import java.io.OutputStream; import java.util.HashSet; import java.util.Locale; import java.util.Set; import java.util.StringTokenizer; import java.util.regex.Pattern; import java.util.zip.Deflater; -import java.util.zip.DeflaterOutputStream; import javax.servlet.AsyncEvent; import javax.servlet.AsyncListener; @@ -43,6 +43,7 @@ import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.MimeTypes; import org.eclipse.jetty.servlets.gzip.AbstractCompressedStream; import org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper; +import org.eclipse.jetty.servlets.gzip.DeflatedOutputStream; import org.eclipse.jetty.servlets.gzip.GzipOutputStream; import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.log.Log; @@ -142,6 +143,8 @@ public class GzipFilter extends UserAgentFilter // non-static, as other GzipFilter instances may have different configurations protected final ThreadLocal<Deflater> _deflater = new ThreadLocal<Deflater>(); + protected final static ThreadLocal<byte[]> _buffer= new ThreadLocal<byte[]>(); + protected final Set<String> _methods=new HashSet<String>(); protected Set<String> _excludedAgents; protected Set<Pattern> _excludedAgentPatterns; @@ -464,9 +467,10 @@ public class GzipFilter extends UserAgentFilter return new AbstractCompressedStream(compressionType,request,this,_vary) { private Deflater _allocatedDeflater; + private byte[] _allocatedBuffer; @Override - protected DeflaterOutputStream createStream() throws IOException + protected OutputStream createStream() throws IOException { if (compressionType == null) { @@ -483,12 +487,21 @@ public class GzipFilter extends UserAgentFilter _allocatedDeflater.reset(); } + // acquire buffer + _allocatedBuffer = _buffer.get(); + if (_allocatedBuffer==null) + _allocatedBuffer = new byte[_bufferSize]; + else + { + _buffer.remove(); + } + switch (compressionType) { case GZIP: - return new GzipOutputStream(_response.getOutputStream(),_allocatedDeflater,_bufferSize); + return new GzipOutputStream(_response.getOutputStream(),_allocatedDeflater,_allocatedBuffer); case DEFLATE: - return new DeflaterOutputStream(_response.getOutputStream(),_allocatedDeflater,_bufferSize); + return new DeflatedOutputStream(_response.getOutputStream(),_allocatedDeflater,_allocatedBuffer); } throw new IllegalStateException(compressionType + " not supported"); } @@ -501,6 +514,10 @@ public class GzipFilter extends UserAgentFilter { _deflater.set(_allocatedDeflater); } + if (_allocatedBuffer != null && _buffer.get() == null) + { + _buffer.set(_allocatedBuffer); + } } }; } diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/gzip/AbstractCompressedStream.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/gzip/AbstractCompressedStream.java index 56590d6fee..a5eba6ce2f 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/gzip/AbstractCompressedStream.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/gzip/AbstractCompressedStream.java @@ -23,7 +23,6 @@ import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; -import java.util.zip.DeflaterOutputStream; import javax.servlet.ServletOutputStream; import javax.servlet.WriteListener; @@ -46,7 +45,7 @@ public abstract class AbstractCompressedStream extends ServletOutputStream protected final HttpServletResponse _response; protected OutputStream _out; protected ByteArrayOutputStream2 _bOut; - protected DeflaterOutputStream _compressedOutputStream; + protected OutputStream _compressedOutputStream; protected boolean _closed; protected boolean _doNotCompress; @@ -392,7 +391,7 @@ public abstract class AbstractCompressedStream extends ServletOutputStream * @throws IOException * Signals that an I/O exception has occurred. */ - protected abstract DeflaterOutputStream createStream() throws IOException; + protected abstract OutputStream createStream() throws IOException; } diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/gzip/DeflatedOutputStream.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/gzip/DeflatedOutputStream.java new file mode 100644 index 0000000000..c6b0f9613c --- /dev/null +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/gzip/DeflatedOutputStream.java @@ -0,0 +1,83 @@ +package org.eclipse.jetty.servlets.gzip; + +import java.io.FilterOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.zip.Deflater; + +/** + * Reimplementation of {@link java.util.zip.DeflaterOutputStream} that supports reusing the buffer. + */ +public class DeflatedOutputStream extends FilterOutputStream +{ + protected final Deflater _def; + protected final byte[] _buf; + protected boolean closed = false; + + public DeflatedOutputStream(OutputStream out, Deflater deflater, byte[] buffer) + { + super(out); + _def = deflater; + _buf = buffer; + } + + @Override + public void write(int b) throws IOException + { + byte[] buf = new byte[1]; + buf[0] = (byte)(b & 0xff); + write(buf,0,1); + } + + @Override + public void write(byte[] b, int off, int len) throws IOException + { + if (_def.finished()) + throw new IOException("Stream already finished"); + if ((off | len | (off + len) | (b.length - (off + len))) < 0) + throw new IndexOutOfBoundsException(); + if (len == 0) + return; + if (!_def.finished()) + { + _def.setInput(b,off,len); + while (!_def.needsInput()) + { + deflate(); + } + } + } + + private void deflate() throws IOException + { + int len = _def.deflate(_buf,0,_buf.length); + if (len > 0) + { + out.write(_buf,0,len); + } + } + + public synchronized void finish() throws IOException + { + if (!_def.finished()) + { + _def.finish(); + while (!_def.finished()) + { + deflate(); + } + } + } + + @Override + public synchronized void close() throws IOException + { + if (!closed) + { + finish(); + out.close(); + closed = true; + } + } + +} diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/gzip/GzipOutputStream.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/gzip/GzipOutputStream.java index b6b45a67fb..2e4d64f408 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/gzip/GzipOutputStream.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/gzip/GzipOutputStream.java @@ -22,12 +22,11 @@ import java.io.IOException; import java.io.OutputStream; import java.util.zip.CRC32; import java.util.zip.Deflater; -import java.util.zip.DeflaterOutputStream; /** * Reimplementation of {@link java.util.zip.GZIPOutputStream} that supports reusing a {@link Deflater} instance. */ -public class GzipOutputStream extends DeflaterOutputStream +public class GzipOutputStream extends DeflatedOutputStream { private final static byte[] GZIP_HEADER = new byte[] @@ -35,9 +34,9 @@ public class GzipOutputStream extends DeflaterOutputStream private final CRC32 _crc = new CRC32(); - public GzipOutputStream(OutputStream out, Deflater deflater, int size) throws IOException + public GzipOutputStream(OutputStream out, Deflater deflater, byte[] buffer) throws IOException { - super(out,deflater,size); + super(out,deflater,buffer); out.write(GZIP_HEADER); } @@ -51,23 +50,15 @@ public class GzipOutputStream extends DeflaterOutputStream @Override public synchronized void finish() throws IOException { - if (!def.finished()) + if (!_def.finished()) { super.finish(); byte[] trailer = new byte[8]; writeInt((int)_crc.getValue(),trailer,0); - writeInt(def.getTotalIn(),trailer,4); + writeInt(_def.getTotalIn(),trailer,4); out.write(trailer); } } - - @Override - public synchronized void close() throws IOException - { - super.close(); - } - - private void writeInt(int i, byte[] buf, int offset) { |