You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commons-dev@ws.apache.org by ve...@apache.org on 2009/06/05 09:41:46 UTC
svn commit: r781934 - in
/webservices/commons/trunk/modules/tcpmon/modules/tcpmon-core/src:
main/java/org/apache/ws/commons/tcpmon/core/filter/
main/java/org/apache/ws/commons/tcpmon/core/filter/http/
main/java/org/apache/ws/commons/tcpmon/core/filter/...
Author: veithen
Date: Fri Jun 5 07:41:45 2009
New Revision: 781934
URL: http://svn.apache.org/viewvc?rev=781934&view=rev
Log:
Added support for gzip content-encoding.
Added:
webservices/commons/trunk/modules/tcpmon/modules/tcpmon-core/src/main/java/org/apache/ws/commons/tcpmon/core/filter/zip/GZIPEncoder.java (with props)
webservices/commons/trunk/modules/tcpmon/modules/tcpmon-core/src/test/java/org/apache/ws/commons/tcpmon/core/filter/zip/GZIPEncoderTest.java (with props)
Modified:
webservices/commons/trunk/modules/tcpmon/modules/tcpmon-core/src/main/java/org/apache/ws/commons/tcpmon/core/filter/StreamUtil.java
webservices/commons/trunk/modules/tcpmon/modules/tcpmon-core/src/main/java/org/apache/ws/commons/tcpmon/core/filter/http/HttpFilter.java
Modified: webservices/commons/trunk/modules/tcpmon/modules/tcpmon-core/src/main/java/org/apache/ws/commons/tcpmon/core/filter/StreamUtil.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/tcpmon/modules/tcpmon-core/src/main/java/org/apache/ws/commons/tcpmon/core/filter/StreamUtil.java?rev=781934&r1=781933&r2=781934&view=diff
==============================================================================
--- webservices/commons/trunk/modules/tcpmon/modules/tcpmon-core/src/main/java/org/apache/ws/commons/tcpmon/core/filter/StreamUtil.java (original)
+++ webservices/commons/trunk/modules/tcpmon/modules/tcpmon-core/src/main/java/org/apache/ws/commons/tcpmon/core/filter/StreamUtil.java Fri Jun 5 07:41:45 2009
@@ -16,8 +16,6 @@
package org.apache.ws.commons.tcpmon.core.filter;
-import java.io.IOException;
-import java.io.InputStream;
import java.io.UnsupportedEncodingException;
/**
@@ -113,4 +111,26 @@
public static int readUShort(Stream stream) {
return stream.get(1) << 8 | stream.get(0);
}
+
+ /**
+ * Insert an integer in little endian byte order.
+ *
+ * @param stream
+ * @param i
+ */
+ public static void insertInt(Stream stream, int i) {
+ insertShort(stream, i & 0xffff);
+ insertShort(stream, (i >> 16) & 0xffff);
+ }
+
+ /**
+ * Insert a short integer in little endian byte order.
+ *
+ * @param stream
+ * @param s
+ */
+ public static void insertShort(Stream stream, int s) {
+ stream.insert((byte)(s & 0xff));
+ stream.insert((byte)((s >> 8) & 0xff));
+ }
}
Modified: webservices/commons/trunk/modules/tcpmon/modules/tcpmon-core/src/main/java/org/apache/ws/commons/tcpmon/core/filter/http/HttpFilter.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/tcpmon/modules/tcpmon-core/src/main/java/org/apache/ws/commons/tcpmon/core/filter/http/HttpFilter.java?rev=781934&r1=781933&r2=781934&view=diff
==============================================================================
--- webservices/commons/trunk/modules/tcpmon/modules/tcpmon-core/src/main/java/org/apache/ws/commons/tcpmon/core/filter/http/HttpFilter.java (original)
+++ webservices/commons/trunk/modules/tcpmon/modules/tcpmon-core/src/main/java/org/apache/ws/commons/tcpmon/core/filter/http/HttpFilter.java Fri Jun 5 07:41:45 2009
@@ -30,6 +30,8 @@
import org.apache.ws.commons.tcpmon.core.filter.StreamFilter;
import org.apache.ws.commons.tcpmon.core.filter.StreamUtil;
import org.apache.ws.commons.tcpmon.core.filter.mime.ContentFilterFactory;
+import org.apache.ws.commons.tcpmon.core.filter.zip.GZIPDecoder;
+import org.apache.ws.commons.tcpmon.core.filter.zip.GZIPEncoder;
/**
* Base class for {@link HttpRequestFilter} and {@link HttpResponseFilter}.
@@ -40,15 +42,15 @@
private static final int STATE_CONTENT = 2;
private static final int STATE_COMPLETE = 3;
- private final boolean decodeTransferEncoding;
+ private final boolean decode;
private int state = STATE_FIRST_LINE;
private final Headers headers = new Headers();
private ContentFilterFactory contentFilterFactory;
private EntityProcessor transferDecoder;
private StreamFilter[] contentFilterChain;
- public HttpFilter(boolean decodeTransferEncoding) {
- this.decodeTransferEncoding = decodeTransferEncoding;
+ public HttpFilter(boolean decode) {
+ this.decode = decode;
}
public void setContentFilterFactory(ContentFilterFactory contentFilterFactory) {
@@ -97,7 +99,7 @@
case STATE_CONTENT: {
if (transferDecoder != null) {
Stream decoderStream =
- decodeTransferEncoding ? stream : new ReadOnlyStream(stream);
+ decode ? stream : new ReadOnlyStream(stream);
if (transferDecoder.process(decoderStream)) {
state = STATE_COMPLETE;
if (contentFilterChain != null) {
@@ -130,6 +132,8 @@
boolean hasEntity = false;
boolean discardHeaders = false;
StreamFilter transferEncoder = null;
+ StreamFilter contentDecoder = null;
+ StreamFilter contentEncoder = null;
for (Iterator it = headers.iterator(); it.hasNext(); ) {
Header header = (Header)it.next();
String name = header.getName();
@@ -155,6 +159,11 @@
// If the content type is unparseable, just continue
}
}
+ } else if (name.equalsIgnoreCase("Content-Encoding")) {
+ if (value.equals("gzip")) {
+ contentDecoder = new GZIPDecoder();
+ contentEncoder = new GZIPEncoder();
+ }
}
}
@@ -170,15 +179,29 @@
if (hasEntity) {
if (contentFilterChain != null) {
- if (transferEncoder != null && !decodeTransferEncoding) {
- stream.pushFilter(transferEncoder);
+ if (!decode) {
+ if (transferEncoder != null) {
+ stream.pushFilter(transferEncoder);
+ }
+ if (contentEncoder != null) {
+ stream.pushFilter(contentEncoder);
+ }
}
for (int i=contentFilterChain.length-1; i>=0; i--) {
stream.pushFilter(contentFilterChain[i]);
}
+ if (contentDecoder != null) {
+ stream.pushFilter(contentDecoder);
+ }
} else {
- if (transferDecoder != null && !decodeTransferEncoding) {
- transferDecoder = new ReadOnlyEntityProcessorWrapper(transferDecoder);
+ if (decode) {
+ if (contentDecoder != null) {
+ stream.pushFilter(contentDecoder);
+ }
+ } else {
+ if (transferDecoder != null) {
+ transferDecoder = new ReadOnlyEntityProcessorWrapper(transferDecoder);
+ }
}
}
state = STATE_CONTENT;
Added: webservices/commons/trunk/modules/tcpmon/modules/tcpmon-core/src/main/java/org/apache/ws/commons/tcpmon/core/filter/zip/GZIPEncoder.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/tcpmon/modules/tcpmon-core/src/main/java/org/apache/ws/commons/tcpmon/core/filter/zip/GZIPEncoder.java?rev=781934&view=auto
==============================================================================
--- webservices/commons/trunk/modules/tcpmon/modules/tcpmon-core/src/main/java/org/apache/ws/commons/tcpmon/core/filter/zip/GZIPEncoder.java (added)
+++ webservices/commons/trunk/modules/tcpmon/modules/tcpmon-core/src/main/java/org/apache/ws/commons/tcpmon/core/filter/zip/GZIPEncoder.java Fri Jun 5 07:41:45 2009
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.commons.tcpmon.core.filter.zip;
+
+import java.util.zip.CRC32;
+import java.util.zip.Deflater;
+
+import org.apache.ws.commons.tcpmon.core.filter.Stream;
+import org.apache.ws.commons.tcpmon.core.filter.StreamFilter;
+import org.apache.ws.commons.tcpmon.core.filter.StreamUtil;
+
+public class GZIPEncoder implements StreamFilter {
+ private static final byte[] header = { 0x1f, (byte)0x8b, 8, 0, 0, 0, 0, 0, 0, -1 };
+
+ private final Deflater deflater;
+ private final CRC32 crc = new CRC32();
+ private final byte[] inBuffer = new byte[256];
+ private final byte[] outBuffer = new byte[256];
+ private boolean isStart = true;
+
+ public GZIPEncoder() {
+ this.deflater = new Deflater(Deflater.DEFAULT_COMPRESSION, true);
+ }
+
+ public void invoke(Stream stream) {
+ if (isStart) {
+ stream.insert(header, 0, 10);
+ isStart = false;
+ }
+ do {
+ int in = Math.min(inBuffer.length, stream.available());
+ stream.read(inBuffer, 0, in);
+ deflater.setInput(inBuffer, 0, in);
+ stream.discard(in);
+ if (stream.isEndOfStream()) {
+ deflater.finish();
+ }
+ crc.update(inBuffer, 0, in);
+ while (true) {
+ int out = deflater.deflate(outBuffer);
+ if (out > 0) {
+ stream.insert(outBuffer, 0, out);
+ } else {
+ break;
+ }
+ }
+ } while (stream.available() > 0);
+ if (stream.isEndOfStream()) {
+ // Write trailer
+ StreamUtil.insertInt(stream, (int)crc.getValue());
+ StreamUtil.insertInt(stream, deflater.getTotalIn());
+ }
+ }
+}
Propchange: webservices/commons/trunk/modules/tcpmon/modules/tcpmon-core/src/main/java/org/apache/ws/commons/tcpmon/core/filter/zip/GZIPEncoder.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: webservices/commons/trunk/modules/tcpmon/modules/tcpmon-core/src/test/java/org/apache/ws/commons/tcpmon/core/filter/zip/GZIPEncoderTest.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/tcpmon/modules/tcpmon-core/src/test/java/org/apache/ws/commons/tcpmon/core/filter/zip/GZIPEncoderTest.java?rev=781934&view=auto
==============================================================================
--- webservices/commons/trunk/modules/tcpmon/modules/tcpmon-core/src/test/java/org/apache/ws/commons/tcpmon/core/filter/zip/GZIPEncoderTest.java (added)
+++ webservices/commons/trunk/modules/tcpmon/modules/tcpmon-core/src/test/java/org/apache/ws/commons/tcpmon/core/filter/zip/GZIPEncoderTest.java Fri Jun 5 07:41:45 2009
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.commons.tcpmon.core.filter.zip;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.Random;
+import java.util.zip.GZIPInputStream;
+
+import junit.framework.TestCase;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.ws.commons.tcpmon.core.filter.Pipeline;
+import org.apache.ws.commons.tcpmon.core.filter.Tee;
+
+public class GZIPEncoderTest extends TestCase {
+ public void test() throws Exception {
+ byte[] content = new byte[10000];
+ Random random = new Random();
+ random.nextBytes(content);
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ Pipeline pipeline = new Pipeline();
+ pipeline.addFilter(new GZIPEncoder());
+ pipeline.addFilter(new Tee(baos));
+ OutputStream out = pipeline.getOutputStream();
+ out.write(content);
+ out.close();
+ byte[] content2 = IOUtils.toByteArray(new GZIPInputStream(new ByteArrayInputStream(baos.toByteArray())));
+ assertTrue(Arrays.equals(content, content2));
+ }
+}
Propchange: webservices/commons/trunk/modules/tcpmon/modules/tcpmon-core/src/test/java/org/apache/ws/commons/tcpmon/core/filter/zip/GZIPEncoderTest.java
------------------------------------------------------------------------------
svn:eol-style = native