Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Wilkins2013-12-04 23:52:32 +0000
committerGreg Wilkins2013-12-04 23:52:32 +0000
commite9df551352936d7e127480591b13a3f1efe1b75f (patch)
treee8e74e8ac4148d4f87cbe04626abf5e91447fd98
parent9c39b2e631ba8ae06154d1c5d3bf03ccaba8239f (diff)
downloadorg.eclipse.jetty.project-e9df551352936d7e127480591b13a3f1efe1b75f.tar.gz
org.eclipse.jetty.project-e9df551352936d7e127480591b13a3f1efe1b75f.tar.xz
org.eclipse.jetty.project-e9df551352936d7e127480591b13a3f1efe1b75f.zip
423005 reuse gzipfilter buffers
-rw-r--r--jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java25
-rw-r--r--jetty-servlets/src/main/java/org/eclipse/jetty/servlets/gzip/AbstractCompressedStream.java5
-rw-r--r--jetty-servlets/src/main/java/org/eclipse/jetty/servlets/gzip/DeflatedOutputStream.java83
-rw-r--r--jetty-servlets/src/main/java/org/eclipse/jetty/servlets/gzip/GzipOutputStream.java19
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)
{

Back to the top