diff --git a/hutool-http/pom.xml b/hutool-http/pom.xml
index 63a4a7dc3..d858816a9 100755
--- a/hutool-http/pom.xml
+++ b/hutool-http/pom.xml
@@ -22,6 +22,12 @@
hutool-core
${project.parent.version}
+
+ javax.xml.soap
+ javax.xml.soap-api
+ 1.4.0
+ provided
+
cn.hutool
hutool-json
@@ -29,10 +35,10 @@
test
- javax.xml.soap
- javax.xml.soap-api
- 1.4.0
- provided
+ org.brotli
+ dec
+ 0.1.2
+ test
diff --git a/hutool-http/src/main/java/cn/hutool/http/GlobalCompressStreamRegister.java b/hutool-http/src/main/java/cn/hutool/http/GlobalCompressStreamRegister.java
new file mode 100755
index 000000000..a0d13a9f3
--- /dev/null
+++ b/hutool-http/src/main/java/cn/hutool/http/GlobalCompressStreamRegister.java
@@ -0,0 +1,57 @@
+package cn.hutool.http;
+
+import cn.hutool.core.map.CaseInsensitiveMap;
+
+import java.io.InputStream;
+import java.util.Map;
+
+/**
+ * 全局响应内容压缩解压器注册中心
+ * 通过注册指定Accept-Encoding的流,来包装响应内容流,从而支持特殊压缩算法
+ *
+ * @author looly
+ * @since 6.0.0
+ */
+public enum GlobalCompressStreamRegister {
+ /**
+ * 单例对象
+ */
+ INSTANCE;
+
+ /**
+ * 存储内容压缩流信息
+ */
+ private final Map> compressMap = new CaseInsensitiveMap<>();
+
+ GlobalCompressStreamRegister() {
+ }
+
+ /**
+ * 获取解压器
+ *
+ * @param contentEncoding Accept-Encoding名称,如gzip、defalte、br等,不区分大小写
+ * @return 解压器
+ */
+ public Class extends InputStream> get(final String contentEncoding) {
+ return compressMap.get(contentEncoding);
+ }
+
+ /**
+ * 注册解压器
+ *
+ * @param contentEncoding Accept-Encoding名称,如gzip、defalte、br等,不区分大小写
+ * @param streamClass 解压类
+ */
+ synchronized public void register(final String contentEncoding, final Class extends InputStream> streamClass) {
+ this.compressMap.put(contentEncoding, streamClass);
+ }
+
+ /**
+ * 注销压缩器
+ *
+ * @param contentEncoding Accept-Encoding名称,如gzip、defalte、br等,不区分大小写
+ */
+ synchronized public void unRegister(final String contentEncoding) {
+ this.compressMap.remove(contentEncoding);
+ }
+}
diff --git a/hutool-http/src/main/java/cn/hutool/http/GlobalHeaders.java b/hutool-http/src/main/java/cn/hutool/http/GlobalHeaders.java
index 59f8590da..f3e6d539b 100644
--- a/hutool-http/src/main/java/cn/hutool/http/GlobalHeaders.java
+++ b/hutool-http/src/main/java/cn/hutool/http/GlobalHeaders.java
@@ -18,6 +18,9 @@ import java.util.Map.Entry;
* @author looly
*/
public enum GlobalHeaders {
+ /**
+ * 单例对象
+ */
INSTANCE;
/**
diff --git a/hutool-http/src/main/java/cn/hutool/http/HttpInputStream.java b/hutool-http/src/main/java/cn/hutool/http/HttpInputStream.java
index d7374b752..a26dcae34 100644
--- a/hutool-http/src/main/java/cn/hutool/http/HttpInputStream.java
+++ b/hutool-http/src/main/java/cn/hutool/http/HttpInputStream.java
@@ -1,5 +1,6 @@
package cn.hutool.http;
+import cn.hutool.core.reflect.ConstructorUtil;
import cn.hutool.core.text.StrUtil;
import java.io.ByteArrayInputStream;
@@ -92,17 +93,27 @@ public class HttpInputStream extends InputStream {
return;
}
- if (response.isGzip() && false == (response.in instanceof GZIPInputStream)) {
+ final String contentEncoding = response.contentEncoding();
+ if (StrUtil.equalsIgnoreCase("gzip", contentEncoding) && false == (response.in instanceof GZIPInputStream)) {
// Accept-Encoding: gzip
try {
this.in = new GZIPInputStream(this.in);
- } catch (final IOException e) {
+ } catch (final IOException ignore) {
// 在类似于Head等方法中无body返回,此时GZIPInputStream构造会出现错误,在此忽略此错误读取普通数据
// ignore
}
- } else if (response.isDeflate() && false == (this.in instanceof InflaterInputStream)) {
+ } else if (StrUtil.equalsIgnoreCase("deflate", contentEncoding) && false == (this.in instanceof InflaterInputStream)) {
// Accept-Encoding: defalte
this.in = new InflaterInputStream(this.in, new Inflater(true));
+ } else{
+ final Class extends InputStream> streamClass = GlobalCompressStreamRegister.INSTANCE.get(contentEncoding);
+ if(null != streamClass){
+ try {
+ this.in = ConstructorUtil.newInstance(streamClass, this.in);
+ } catch (final Exception ignore) {
+ // 对于构造错误的压缩算法,跳过之
+ }
+ }
}
}
}
diff --git a/hutool-http/src/main/java/cn/hutool/http/HttpResponse.java b/hutool-http/src/main/java/cn/hutool/http/HttpResponse.java
index 9f35ba946..078eaf700 100755
--- a/hutool-http/src/main/java/cn/hutool/http/HttpResponse.java
+++ b/hutool-http/src/main/java/cn/hutool/http/HttpResponse.java
@@ -143,27 +143,6 @@ public class HttpResponse extends HttpBase implements Closeable {
return contentLength;
}
- /**
- * 是否为gzip压缩过的内容
- *
- * @return 是否为gzip压缩过的内容
- */
- public boolean isGzip() {
- final String contentEncoding = contentEncoding();
- return "gzip".equalsIgnoreCase(contentEncoding);
- }
-
- /**
- * 是否为zlib(Deflate)压缩过的内容
- *
- * @return 是否为zlib(Deflate)压缩过的内容
- * @since 4.5.7
- */
- public boolean isDeflate() {
- final String contentEncoding = contentEncoding();
- return "deflate".equalsIgnoreCase(contentEncoding);
- }
-
/**
* 是否为Transfer-Encoding:Chunked的内容
*
diff --git a/hutool-http/src/test/java/cn/hutool/http/IssueI5XBCFTest.java b/hutool-http/src/test/java/cn/hutool/http/IssueI5XBCFTest.java
new file mode 100755
index 000000000..923884cc3
--- /dev/null
+++ b/hutool-http/src/test/java/cn/hutool/http/IssueI5XBCFTest.java
@@ -0,0 +1,20 @@
+package cn.hutool.http;
+
+import cn.hutool.core.lang.Console;
+import org.brotli.dec.BrotliInputStream;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class IssueI5XBCFTest {
+
+ @Test
+ @Ignore
+ public void getTest() {
+ GlobalCompressStreamRegister.INSTANCE.register("br", BrotliInputStream.class);
+
+ final HttpResponse s = HttpUtil.createGet("https://static-exp1.licdn.com/sc/h/br/1cp0oqz322bdprj3qd4pojqix")
+ .header(Header.ACCEPT_ENCODING, "br")
+ .execute();
+ Console.log(s.body());
+ }
+}