diff --git a/RELEASE_NOTES.txt b/RELEASE_NOTES.txt index 41373b981..4380d5892 100644 --- a/RELEASE_NOTES.txt +++ b/RELEASE_NOTES.txt @@ -19,6 +19,10 @@ Changelog: * [HTTPCLIENT-1836] DefaultHostnameVerifier#getSubjectAltNames(X509Certificate) throws java.lang.ClassCastException. Contributed by Gary Gregory , Ilian Iliev + +* [HTTPCLIENT-1845]: Extract InputStreamFactory classes out of GzipDecompressingEntity and + DeflateDecompressingEntity for reuse and to create less garbage. + Contributed by Gary Gregory Release 4.5.3 ------------------- diff --git a/httpclient/src/main/java/org/apache/http/client/entity/DeflateDecompressingEntity.java b/httpclient/src/main/java/org/apache/http/client/entity/DeflateDecompressingEntity.java index 1d3cd7fe7..6551a4ba4 100644 --- a/httpclient/src/main/java/org/apache/http/client/entity/DeflateDecompressingEntity.java +++ b/httpclient/src/main/java/org/apache/http/client/entity/DeflateDecompressingEntity.java @@ -26,9 +26,6 @@ */ package org.apache.http.client.entity; -import java.io.IOException; -import java.io.InputStream; - import org.apache.http.HttpEntity; /** @@ -57,14 +54,7 @@ public class DeflateDecompressingEntity extends DecompressingEntity { * a non-null {@link HttpEntity} to be wrapped */ public DeflateDecompressingEntity(final HttpEntity entity) { - super(entity, new InputStreamFactory() { - - @Override - public InputStream create(final InputStream instream) throws IOException { - return new DeflateInputStream(instream); - } - - }); + super(entity, DeflateInputStreamFactory.getInstance()); } } diff --git a/httpclient/src/main/java/org/apache/http/client/entity/DeflateInputStreamFactory.java b/httpclient/src/main/java/org/apache/http/client/entity/DeflateInputStreamFactory.java new file mode 100644 index 000000000..3853efea0 --- /dev/null +++ b/httpclient/src/main/java/org/apache/http/client/entity/DeflateInputStreamFactory.java @@ -0,0 +1,63 @@ +/* + * ==================================================================== + * 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 + * . + * + */ + +package org.apache.http.client.entity; + +import java.io.IOException; +import java.io.InputStream; + +import org.apache.http.annotation.Contract; +import org.apache.http.annotation.ThreadingBehavior; + +/** + * {@link InputStreamFactory} for handling Deflate Content Coded responses. + * + * @since 4.5.4 + */ +@Contract(threading = ThreadingBehavior.IMMUTABLE) +public class DeflateInputStreamFactory implements InputStreamFactory { + + /** + * Singleton instance. + */ + private static final DeflateInputStreamFactory INSTANCE = new DeflateInputStreamFactory(); + + /** + * Gets the singleton instance. + * + * @return the singleton instance. + */ + public static DeflateInputStreamFactory getInstance() { + return INSTANCE; + } + + @Override + public InputStream create(final InputStream inputStream) throws IOException { + return new DeflateInputStream(inputStream); + } + +} diff --git a/httpclient/src/main/java/org/apache/http/client/entity/GZIPInputStreamFactory.java b/httpclient/src/main/java/org/apache/http/client/entity/GZIPInputStreamFactory.java new file mode 100644 index 000000000..f52fd12e8 --- /dev/null +++ b/httpclient/src/main/java/org/apache/http/client/entity/GZIPInputStreamFactory.java @@ -0,0 +1,64 @@ +/* + * ==================================================================== + * 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 + * . + * + */ + +package org.apache.http.client.entity; + +import java.io.IOException; +import java.io.InputStream; +import java.util.zip.GZIPInputStream; + +import org.apache.http.annotation.Contract; +import org.apache.http.annotation.ThreadingBehavior; + +/** + * {@link InputStreamFactory} for handling GZIPContent Coded responses. + * + * @since 4.5.4 + */ +@Contract(threading = ThreadingBehavior.IMMUTABLE) +public class GZIPInputStreamFactory implements InputStreamFactory { + + /** + * Singleton instance. + */ + private static final GZIPInputStreamFactory INSTANCE = new GZIPInputStreamFactory(); + + /** + * Gets the singleton instance. + * + * @return the singleton instance. + */ + public static GZIPInputStreamFactory getInstance() { + return INSTANCE; + } + + @Override + public InputStream create(final InputStream inputStream) throws IOException { + return new GZIPInputStream(inputStream); + } + +} diff --git a/httpclient/src/main/java/org/apache/http/client/entity/GzipDecompressingEntity.java b/httpclient/src/main/java/org/apache/http/client/entity/GzipDecompressingEntity.java index ca45b59bb..4fa1ecc6d 100644 --- a/httpclient/src/main/java/org/apache/http/client/entity/GzipDecompressingEntity.java +++ b/httpclient/src/main/java/org/apache/http/client/entity/GzipDecompressingEntity.java @@ -26,10 +26,6 @@ */ package org.apache.http.client.entity; -import java.io.IOException; -import java.io.InputStream; -import java.util.zip.GZIPInputStream; - import org.apache.http.HttpEntity; /** @@ -48,14 +44,7 @@ public class GzipDecompressingEntity extends DecompressingEntity { * the non-null {@link HttpEntity} to be wrapped */ public GzipDecompressingEntity(final HttpEntity entity) { - super(entity, new InputStreamFactory() { - - @Override - public InputStream create(final InputStream instream) throws IOException { - return new GZIPInputStream(instream); - } - - }); + super(entity, GZIPInputStreamFactory.getInstance()); } } diff --git a/httpclient/src/main/java/org/apache/http/client/protocol/ResponseContentEncoding.java b/httpclient/src/main/java/org/apache/http/client/protocol/ResponseContentEncoding.java index 8bb63c657..476eb6320 100644 --- a/httpclient/src/main/java/org/apache/http/client/protocol/ResponseContentEncoding.java +++ b/httpclient/src/main/java/org/apache/http/client/protocol/ResponseContentEncoding.java @@ -27,9 +27,7 @@ package org.apache.http.client.protocol; import java.io.IOException; -import java.io.InputStream; import java.util.Locale; -import java.util.zip.GZIPInputStream; import org.apache.http.Header; import org.apache.http.HeaderElement; @@ -41,7 +39,8 @@ import org.apache.http.annotation.Contract; import org.apache.http.annotation.ThreadingBehavior; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.entity.DecompressingEntity; -import org.apache.http.client.entity.DeflateInputStream; +import org.apache.http.client.entity.DeflateInputStreamFactory; +import org.apache.http.client.entity.GZIPInputStreamFactory; import org.apache.http.client.entity.InputStreamFactory; import org.apache.http.config.Lookup; import org.apache.http.config.RegistryBuilder; @@ -61,23 +60,6 @@ public class ResponseContentEncoding implements HttpResponseInterceptor { public static final String UNCOMPRESSED = "http.client.response.uncompressed"; - private final static InputStreamFactory GZIP = new InputStreamFactory() { - - @Override - public InputStream create(final InputStream instream) throws IOException { - return new GZIPInputStream(instream); - } - }; - - private final static InputStreamFactory DEFLATE = new InputStreamFactory() { - - @Override - public InputStream create(final InputStream instream) throws IOException { - return new DeflateInputStream(instream); - } - - }; - private final Lookup decoderRegistry; private final boolean ignoreUnknown; @@ -87,9 +69,9 @@ public class ResponseContentEncoding implements HttpResponseInterceptor { public ResponseContentEncoding(final Lookup decoderRegistry, final boolean ignoreUnknown) { this.decoderRegistry = decoderRegistry != null ? decoderRegistry : RegistryBuilder.create() - .register("gzip", GZIP) - .register("x-gzip", GZIP) - .register("deflate", DEFLATE) + .register("gzip", GZIPInputStreamFactory.getInstance()) + .register("x-gzip", GZIPInputStreamFactory.getInstance()) + .register("deflate", DeflateInputStreamFactory.getInstance()) .build(); this.ignoreUnknown = ignoreUnknown; }