From 96e88307f806942029e499452d01ab342514728f Mon Sep 17 00:00:00 2001 From: Looly Date: Thu, 8 Jul 2021 09:29:02 +0800 Subject: [PATCH] fix alowPatch --- .../java/cn/hutool/http/HttpConnection.java | 24 +-------- .../java/cn/hutool/http/HttpGlobalConfig.java | 52 ++++++++++++++----- .../java/cn/hutool/http/HttpInputStream.java | 25 ++++----- 3 files changed, 55 insertions(+), 46 deletions(-) diff --git a/hutool-http/src/main/java/cn/hutool/http/HttpConnection.java b/hutool-http/src/main/java/cn/hutool/http/HttpConnection.java index 6d6b13285..44114a3ed 100644 --- a/hutool-http/src/main/java/cn/hutool/http/HttpConnection.java +++ b/hutool-http/src/main/java/cn/hutool/http/HttpConnection.java @@ -13,8 +13,6 @@ import javax.net.ssl.SSLSocketFactory; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; import java.net.HttpURLConnection; import java.net.ProtocolException; import java.net.Proxy; @@ -122,7 +120,7 @@ public class HttpConnection { // 增加PATCH方法支持 if (Method.PATCH.equals(method)) { - allowPatch(); + HttpGlobalConfig.allowPatch(); } } @@ -546,23 +544,5 @@ public class HttpConnection { private URLConnection openConnection() throws IOException { return (null == this.proxy) ? url.openConnection() : url.openConnection(this.proxy); } - - /** - * 增加支持的METHOD方法 - * see: https://stackoverflow.com/questions/25163131/httpurlconnection-invalid-http-method-patch - * - * @since 5.1.6 - */ - private static void allowPatch() { - final Field methodsField = ReflectUtil.getField(HttpURLConnection.class, "methods"); - if (null != methodsField) { - // 去除final修饰 - ReflectUtil.setFieldValue(methodsField, "modifiers", methodsField.getModifiers() & ~Modifier.FINAL); - final String[] methods = { - "GET", "POST", "HEAD", "OPTIONS", "PUT", "DELETE", "TRACE", "PATCH" - }; - ReflectUtil.setFieldValue(null, methodsField, methods); - } - } // --------------------------------------------------------------- Private Method end -} \ No newline at end of file +} diff --git a/hutool-http/src/main/java/cn/hutool/http/HttpGlobalConfig.java b/hutool-http/src/main/java/cn/hutool/http/HttpGlobalConfig.java index 3ed3605f4..93a70070b 100755 --- a/hutool-http/src/main/java/cn/hutool/http/HttpGlobalConfig.java +++ b/hutool-http/src/main/java/cn/hutool/http/HttpGlobalConfig.java @@ -1,13 +1,17 @@ package cn.hutool.http; -import java.io.Serializable; -import java.net.CookieManager; - +import cn.hutool.core.util.ReflectUtil; import cn.hutool.http.cookie.GlobalCookieManager; +import java.io.Serializable; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.net.CookieManager; +import java.net.HttpURLConnection; + /** * HTTP 全局参数配置 - * + * * @author Looly * @since 4.6.2 */ @@ -15,10 +19,11 @@ public class HttpGlobalConfig implements Serializable { private static final long serialVersionUID = 1L; protected static int timeout = -1; + private static boolean isAllowPatch = false; /** * 获取全局默认的超时时长 - * + * * @return 全局默认的超时时长 */ public static int getTimeout() { @@ -27,16 +32,16 @@ public class HttpGlobalConfig implements Serializable { /** * 设置默认的连接和读取超时时长 - * + * * @param customTimeout 超时时长 */ - public static void setTimeout(int customTimeout) { + synchronized public static void setTimeout(int customTimeout) { timeout = customTimeout; } - + /** * 获取Cookie管理器,用于自定义Cookie管理 - * + * * @return {@link CookieManager} * @since 4.1.0 * @see GlobalCookieManager#getCookieManager() @@ -47,7 +52,7 @@ public class HttpGlobalConfig implements Serializable { /** * 自定义{@link CookieManager} - * + * * @param customCookieManager 自定义的{@link CookieManager} * @since 4.5.14 * @see GlobalCookieManager#setCookieManager(CookieManager) @@ -55,14 +60,37 @@ public class HttpGlobalConfig implements Serializable { public static void setCookieManager(CookieManager customCookieManager) { GlobalCookieManager.setCookieManager(customCookieManager); } - + /** * 关闭Cookie - * + * * @since 4.1.9 * @see GlobalCookieManager#setCookieManager(CookieManager) */ public static void closeCookie() { GlobalCookieManager.setCookieManager(null); } + + /** + * 增加支持的METHOD方法
+ * 此方法通过注入方式修改{@link HttpURLConnection}中的methods静态属性,增加PATCH方法
+ * see: https://stackoverflow.com/questions/25163131/httpurlconnection-invalid-http-method-patch + * + * @since 5.7.4 + */ + synchronized public static void allowPatch() { + if(isAllowPatch){ + return; + } + final Field methodsField = ReflectUtil.getField(HttpURLConnection.class, "methods"); + if (null != methodsField) { + // 去除final修饰 + ReflectUtil.setFieldValue(methodsField, "modifiers", methodsField.getModifiers() & ~Modifier.FINAL); + final String[] methods = { + "GET", "POST", "HEAD", "OPTIONS", "PUT", "DELETE", "TRACE", "PATCH" + }; + ReflectUtil.setFieldValue(null, methodsField, methods); + isAllowPatch = true; + } + } } 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 d59fa5edf..9dc6b0205 100644 --- a/hutool-http/src/main/java/cn/hutool/http/HttpInputStream.java +++ b/hutool-http/src/main/java/cn/hutool/http/HttpInputStream.java @@ -12,7 +12,7 @@ import java.util.zip.InflaterInputStream; /** * HTTP输入流,此流用于包装Http请求响应内容的流,用于解析各种压缩、分段的响应流内容 - * + * * @author Looly * */ @@ -23,7 +23,7 @@ public class HttpInputStream extends InputStream { /** * 构造 - * + * * @param response 响应对象 */ public HttpInputStream(HttpResponse response) { @@ -34,37 +34,38 @@ public class HttpInputStream extends InputStream { public int read() throws IOException { return this.in.read(); } - + + @SuppressWarnings("NullableProblems") @Override public int read(byte[] b, int off, int len) throws IOException { return this.in.read(b, off, len); } - + @Override public long skip(long n) throws IOException { return this.in.skip(n); } - + @Override public int available() throws IOException { return this.in.available(); } - + @Override public void close() throws IOException { this.in.close(); } - + @Override public synchronized void mark(int readlimit) { this.in.mark(readlimit); } - + @Override public synchronized void reset() throws IOException { this.in.reset(); } - + @Override public boolean markSupported() { return this.in.markSupported(); @@ -72,7 +73,7 @@ public class HttpInputStream extends InputStream { /** * 初始化流 - * + * * @param response 响应对象 */ private void init(HttpResponse response) { @@ -84,13 +85,13 @@ public class HttpInputStream extends InputStream { } // 服务器无返回内容,忽略之 } - + // 在一些情况下,返回的流为null,此时提供状态码说明 if (null == this.in) { this.in = new ByteArrayInputStream(StrUtil.format("Error request, response status: {}", response.status).getBytes()); return; } - + if (response.isGzip() && false == (response.in instanceof GZIPInputStream)) { // Accept-Encoding: gzip try {