You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by kw...@apache.org on 2013/05/29 22:24:37 UTC
svn commit: r1487630 - in /httpcomponents/httpclient/trunk: RELEASE_NOTES.txt
httpclient/src/main/java/org/apache/http/client/entity/DeflateDecompressingEntity.java
httpclient/src/main/java/org/apache/http/client/entity/DeflateInputStream.java
Author: kwright
Date: Wed May 29 20:24:37 2013
New Revision: 1487630
URL: http://svn.apache.org/r1487630
Log:
Fix for HTTPCLIENT-1360. Separate out DeflateInputStream class from DeflateEntity.
Added:
httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/client/entity/DeflateInputStream.java (with props)
Modified:
httpcomponents/httpclient/trunk/RELEASE_NOTES.txt
httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/client/entity/DeflateDecompressingEntity.java
Modified: httpcomponents/httpclient/trunk/RELEASE_NOTES.txt
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/RELEASE_NOTES.txt?rev=1487630&r1=1487629&r2=1487630&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/RELEASE_NOTES.txt (original)
+++ httpcomponents/httpclient/trunk/RELEASE_NOTES.txt Wed May 29 20:24:37 2013
@@ -1,6 +1,10 @@
Changes since release 4.3 BETA1
-------------------
+* [HTTPCLIENT-1360] separate out DeflateInputStream as an independent class,
+ so it can be used by others.
+ Contributed by Karl Wright <kwright at apache.org>
+
* [HTTPCLIENT-1359] repeated requests using the same context fail if they redirect.
Contributed by James Leigh <james at 3roundstones.com>
Modified: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/client/entity/DeflateDecompressingEntity.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/client/entity/DeflateDecompressingEntity.java?rev=1487630&r1=1487629&r2=1487630&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/client/entity/DeflateDecompressingEntity.java (original)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/client/entity/DeflateDecompressingEntity.java Wed May 29 20:24:37 2013
@@ -28,10 +28,6 @@ package org.apache.http.client.entity;
import java.io.IOException;
import java.io.InputStream;
-import java.io.PushbackInputStream;
-import java.util.zip.DataFormatException;
-import java.util.zip.Inflater;
-import java.util.zip.InflaterInputStream;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
@@ -72,86 +68,7 @@ public class DeflateDecompressingEntity
*/
@Override
InputStream decorate(final InputStream wrapped) throws IOException {
- /*
- * A zlib stream will have a header.
- *
- * CMF | FLG [| DICTID ] | ...compressed data | ADLER32 |
- *
- * * CMF is one byte.
- *
- * * FLG is one byte.
- *
- * * DICTID is four bytes, and only present if FLG.FDICT is set.
- *
- * Sniff the content. Does it look like a zlib stream, with a CMF, etc? c.f. RFC1950,
- * section 2.2. http://tools.ietf.org/html/rfc1950#page-4
- *
- * We need to see if it looks like a proper zlib stream, or whether it is just a deflate
- * stream. RFC2616 calls zlib streams deflate. Confusing, isn't it? That's why some servers
- * implement deflate Content-Encoding using deflate streams, rather than zlib streams.
- *
- * We could start looking at the bytes, but to be honest, someone else has already read
- * the RFCs and implemented that for us. So we'll just use the JDK libraries and exception
- * handling to do this. If that proves slow, then we could potentially change this to check
- * the first byte - does it look like a CMF? What about the second byte - does it look like
- * a FLG, etc.
- */
-
- /* We read a small buffer to sniff the content. */
- final byte[] peeked = new byte[6];
-
- final PushbackInputStream pushback = new PushbackInputStream(wrapped, peeked.length);
-
- final int headerLength = pushback.read(peeked);
-
- if (headerLength == -1) {
- throw new IOException("Unable to read the response");
- }
-
- /* We try to read the first uncompressed byte. */
- final byte[] dummy = new byte[1];
-
- final Inflater inf = new Inflater();
-
- try {
- int n;
- while ((n = inf.inflate(dummy)) == 0) {
- if (inf.finished()) {
-
- /* Not expecting this, so fail loudly. */
- throw new IOException("Unable to read the response");
- }
-
- if (inf.needsDictionary()) {
-
- /* Need dictionary - then it must be zlib stream with DICTID part? */
- break;
- }
-
- if (inf.needsInput()) {
- inf.setInput(peeked);
- }
- }
-
- if (n == -1) {
- throw new IOException("Unable to read the response");
- }
-
- /*
- * We read something without a problem, so it's a valid zlib stream. Just need to reset
- * and return an unused InputStream now.
- */
- pushback.unread(peeked, 0, headerLength);
- return new DeflateStream(pushback, new Inflater());
- } catch (final DataFormatException e) {
-
- /* Presume that it's an RFC1951 deflate stream rather than RFC1950 zlib stream and try
- * again. */
- pushback.unread(peeked, 0, headerLength);
- return new DeflateStream(pushback, new Inflater(true));
- } finally {
- inf.end();
- }
+ return new DeflateInputStream(wrapped);
}
/**
@@ -174,24 +91,4 @@ public class DeflateDecompressingEntity
return -1;
}
- static class DeflateStream extends InflaterInputStream {
-
- private boolean closed = false;
-
- public DeflateStream(final InputStream in, final Inflater inflater) {
- super(in, inflater);
- }
-
- @Override
- public void close() throws IOException {
- if (closed) {
- return;
- }
- closed = true;
- inf.end();
- super.close();
- }
-
- }
-
}
Added: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/client/entity/DeflateInputStream.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/client/entity/DeflateInputStream.java?rev=1487630&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/client/entity/DeflateInputStream.java (added)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/client/entity/DeflateInputStream.java Wed May 29 20:24:37 2013
@@ -0,0 +1,229 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.http.client.entity;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PushbackInputStream;
+import java.util.zip.DataFormatException;
+import java.util.zip.Inflater;
+import java.util.zip.InflaterInputStream;
+
+/** Deflate input stream. This class includes logic needed for various Rfc's in order
+* to reasonably implement the "deflate" compression style.
+*/
+public class DeflateInputStream extends InputStream
+{
+ private InputStream sourceStream;
+
+ public DeflateInputStream(final InputStream wrapped)
+ throws IOException
+ {
+ /*
+ * A zlib stream will have a header.
+ *
+ * CMF | FLG [| DICTID ] | ...compressed data | ADLER32 |
+ *
+ * * CMF is one byte.
+ *
+ * * FLG is one byte.
+ *
+ * * DICTID is four bytes, and only present if FLG.FDICT is set.
+ *
+ * Sniff the content. Does it look like a zlib stream, with a CMF, etc? c.f. RFC1950,
+ * section 2.2. http://tools.ietf.org/html/rfc1950#page-4
+ *
+ * We need to see if it looks like a proper zlib stream, or whether it is just a deflate
+ * stream. RFC2616 calls zlib streams deflate. Confusing, isn't it? That's why some servers
+ * implement deflate Content-Encoding using deflate streams, rather than zlib streams.
+ *
+ * We could start looking at the bytes, but to be honest, someone else has already read
+ * the RFCs and implemented that for us. So we'll just use the JDK libraries and exception
+ * handling to do this. If that proves slow, then we could potentially change this to check
+ * the first byte - does it look like a CMF? What about the second byte - does it look like
+ * a FLG, etc.
+ */
+
+ /* We read a small buffer to sniff the content. */
+ final byte[] peeked = new byte[6];
+
+ final PushbackInputStream pushback = new PushbackInputStream(wrapped, peeked.length);
+
+ final int headerLength = pushback.read(peeked);
+
+ if (headerLength == -1) {
+ throw new IOException("Unable to read the response");
+ }
+
+ /* We try to read the first uncompressed byte. */
+ final byte[] dummy = new byte[1];
+
+ final Inflater inf = new Inflater();
+
+ try {
+ int n;
+ while ((n = inf.inflate(dummy)) == 0) {
+ if (inf.finished()) {
+
+ /* Not expecting this, so fail loudly. */
+ throw new IOException("Unable to read the response");
+ }
+
+ if (inf.needsDictionary()) {
+
+ /* Need dictionary - then it must be zlib stream with DICTID part? */
+ break;
+ }
+
+ if (inf.needsInput()) {
+ inf.setInput(peeked);
+ }
+ }
+
+ if (n == -1) {
+ throw new IOException("Unable to read the response");
+ }
+
+ /*
+ * We read something without a problem, so it's a valid zlib stream. Just need to reset
+ * and return an unused InputStream now.
+ */
+ pushback.unread(peeked, 0, headerLength);
+ sourceStream = new DeflateStream(pushback, new Inflater());
+ } catch (final DataFormatException e) {
+
+ /* Presume that it's an RFC1951 deflate stream rather than RFC1950 zlib stream and try
+ * again. */
+ pushback.unread(peeked, 0, headerLength);
+ sourceStream = new DeflateStream(pushback, new Inflater(true));
+ } finally {
+ inf.end();
+ }
+
+ }
+
+ /** Read a byte.
+ */
+ @Override
+ public int read()
+ throws IOException
+ {
+ return sourceStream.read();
+ }
+
+ /** Read lots of bytes.
+ */
+ @Override
+ public int read(byte[] b)
+ throws IOException
+ {
+ return sourceStream.read(b);
+ }
+
+ /** Read lots of specific bytes.
+ */
+ @Override
+ public int read(byte[] b, int off, int len)
+ throws IOException
+ {
+ return sourceStream.read(b,off,len);
+ }
+
+ /** Skip
+ */
+ @Override
+ public long skip(long n)
+ throws IOException
+ {
+ return sourceStream.skip(n);
+ }
+
+ /** Get available.
+ */
+ @Override
+ public int available()
+ throws IOException
+ {
+ return sourceStream.available();
+ }
+
+ /** Mark.
+ */
+ @Override
+ public void mark(int readLimit)
+ {
+ sourceStream.mark(readLimit);
+ }
+
+ /** Reset.
+ */
+ @Override
+ public void reset()
+ throws IOException
+ {
+ sourceStream.reset();
+ }
+
+ /** Check if mark is supported.
+ */
+ @Override
+ public boolean markSupported()
+ {
+ return sourceStream.markSupported();
+ }
+
+ /** Close.
+ */
+ @Override
+ public void close()
+ throws IOException
+ {
+ sourceStream.close();
+ }
+
+ static class DeflateStream extends InflaterInputStream {
+
+ private boolean closed = false;
+
+ public DeflateStream(final InputStream in, final Inflater inflater) {
+ super(in, inflater);
+ }
+
+ @Override
+ public void close() throws IOException {
+ if (closed) {
+ return;
+ }
+ closed = true;
+ inf.end();
+ super.close();
+ }
+
+ }
+
+}
+
Propchange: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/client/entity/DeflateInputStream.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/client/entity/DeflateInputStream.java
------------------------------------------------------------------------------
svn:keywords = Id