mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
fix bugs
This commit is contained in:
parent
f288c497b8
commit
3fe722554c
@ -11,6 +11,7 @@
|
||||
*
|
||||
### 🐞Bug修复
|
||||
* 【extra 】 修复TinyPinyinEngine空构造造成可能的误判问题
|
||||
* 【http 】 修复在gzip模式下Content-Length服务端设置异常导致的阶段
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
@ -22,6 +22,9 @@ public class FastByteArrayOutputStream extends OutputStream {
|
||||
|
||||
private final FastByteBuffer buffer;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*/
|
||||
public FastByteArrayOutputStream() {
|
||||
this(1024);
|
||||
}
|
||||
|
@ -40,10 +40,13 @@ public class FastByteBuffer {
|
||||
private final int minChunkLen;
|
||||
|
||||
public FastByteBuffer() {
|
||||
this.minChunkLen = 1024;
|
||||
this(1024);
|
||||
}
|
||||
|
||||
public FastByteBuffer(int size) {
|
||||
if(size <= 0){
|
||||
size = 1024;
|
||||
}
|
||||
this.minChunkLen = Math.abs(size);
|
||||
}
|
||||
|
||||
@ -282,4 +285,4 @@ public class FastByteBuffer {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ public class IoUtil extends NioUtil {
|
||||
* @return 传输的byte数
|
||||
* @throws IORuntimeException IO异常
|
||||
*/
|
||||
public static long copy(Reader reader, Writer writer, int bufferSize, int count, StreamProgress streamProgress) throws IORuntimeException {
|
||||
public static long copy(Reader reader, Writer writer, int bufferSize, long count, StreamProgress streamProgress) throws IORuntimeException {
|
||||
return new ReaderWriterCopier(bufferSize, count, streamProgress).copy(reader, writer);
|
||||
}
|
||||
|
||||
@ -157,7 +157,7 @@ public class IoUtil extends NioUtil {
|
||||
* @throws IORuntimeException IO异常
|
||||
* @since 5.7.8
|
||||
*/
|
||||
public static long copy(InputStream in, OutputStream out, int bufferSize, int count, StreamProgress streamProgress) throws IORuntimeException {
|
||||
public static long copy(InputStream in, OutputStream out, int bufferSize, long count, StreamProgress streamProgress) throws IORuntimeException {
|
||||
return new StreamCopier(bufferSize, count, streamProgress).copy(in, out);
|
||||
}
|
||||
|
||||
|
@ -117,6 +117,26 @@ public class HttpResponse extends HttpBase<HttpResponse> implements Closeable {
|
||||
return header(Header.CONTENT_ENCODING);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取内容长度,以下情况长度无效:
|
||||
* <ul>
|
||||
* <li>Transfer-Encoding: Chunked</li>
|
||||
* <li>Content-Encoding: XXX</li>
|
||||
* </ul>
|
||||
* 参考:https://blog.csdn.net/jiang7701037/article/details/86304302
|
||||
*
|
||||
* @return 长度,-1表示服务端未返回或长度无效
|
||||
* @since 5.7.9
|
||||
*/
|
||||
public long contentLength() {
|
||||
long contentLength = Convert.toLong(header(Header.CONTENT_LENGTH), -1L);
|
||||
if (contentLength > 0 && (isChunked() || StrUtil.isNotBlank(contentEncoding()))) {
|
||||
//按照HTTP协议规范,在 Transfer-Encoding和Content-Encoding设置后 Content-Length 无效。
|
||||
contentLength = -1;
|
||||
}
|
||||
return contentLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为gzip压缩过的内容
|
||||
*
|
||||
@ -254,9 +274,9 @@ public class HttpResponse extends HttpBase<HttpResponse> implements Closeable {
|
||||
if (null == out) {
|
||||
throw new NullPointerException("[out] is null!");
|
||||
}
|
||||
final int contentLength = Convert.toInt(header(Header.CONTENT_LENGTH), -1);
|
||||
final long contentLength = contentLength();
|
||||
try {
|
||||
return IoUtil.copyByNIO(bodyStream(), out, IoUtil.DEFAULT_BUFFER_SIZE, contentLength, streamProgress);
|
||||
return copyBody(bodyStream(), out, contentLength, streamProgress);
|
||||
} finally {
|
||||
IoUtil.close(this);
|
||||
if (isCloseOut) {
|
||||
@ -452,33 +472,6 @@ public class HttpResponse extends HttpBase<HttpResponse> implements Closeable {
|
||||
return this.isAsync ? this : forceSync();
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取主体,忽略EOFException异常
|
||||
*
|
||||
* @param in 输入流
|
||||
* @throws IORuntimeException IO异常
|
||||
*/
|
||||
private void readBody(InputStream in) throws IORuntimeException {
|
||||
if (ignoreBody) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int contentLength = Convert.toInt(header(Header.CONTENT_LENGTH), -1);
|
||||
final FastByteArrayOutputStream out = contentLength > 0 ?
|
||||
new FastByteArrayOutputStream(contentLength) : new FastByteArrayOutputStream();
|
||||
try {
|
||||
IoUtil.copy(in, out, -1, contentLength, null);
|
||||
} catch (IORuntimeException e) {
|
||||
//noinspection StatementWithEmptyBody
|
||||
if (e.getCause() instanceof EOFException || StrUtil.containsIgnoreCase(e.getMessage(), "Premature EOF")) {
|
||||
// 忽略读取HTTP流中的EOF错误
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
this.bodyBytes = out.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 强制同步,用于初始化<br>
|
||||
* 强制同步后变化如下:
|
||||
@ -512,6 +505,53 @@ public class HttpResponse extends HttpBase<HttpResponse> implements Closeable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取主体,忽略EOFException异常
|
||||
*
|
||||
* @param in 输入流
|
||||
* @throws IORuntimeException IO异常
|
||||
*/
|
||||
private void readBody(InputStream in) throws IORuntimeException {
|
||||
if (ignoreBody) {
|
||||
return;
|
||||
}
|
||||
|
||||
final long contentLength = contentLength();
|
||||
final FastByteArrayOutputStream out = new FastByteArrayOutputStream((int)contentLength);
|
||||
copyBody(in, out, contentLength, null);
|
||||
this.bodyBytes = out.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将响应内容写出到{@link OutputStream}<br>
|
||||
* 异步模式下直接读取Http流写出,同步模式下将存储在内存中的响应内容写出<br>
|
||||
* 写出后会关闭Http流(异步模式)
|
||||
*
|
||||
* @param in 输入流
|
||||
* @param out 写出的流
|
||||
* @param contentLength 总长度,-1表示未知
|
||||
* @param streamProgress 进度显示接口,通过实现此接口显示下载进度
|
||||
* @return 拷贝长度
|
||||
*/
|
||||
private static long copyBody(InputStream in, OutputStream out, long contentLength, StreamProgress streamProgress) {
|
||||
if (null == out) {
|
||||
throw new NullPointerException("[out] is null!");
|
||||
}
|
||||
|
||||
long copyLength = -1;
|
||||
try {
|
||||
copyLength = IoUtil.copy(in, out, IoUtil.DEFAULT_BUFFER_SIZE, contentLength, streamProgress);
|
||||
} catch (IORuntimeException e) {
|
||||
//noinspection StatementWithEmptyBody
|
||||
if (e.getCause() instanceof EOFException || StrUtil.containsIgnoreCase(e.getMessage(), "Premature EOF")) {
|
||||
// 忽略读取HTTP流中的EOF错误
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
return copyLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从Content-Disposition头中获取文件名
|
||||
*
|
||||
|
@ -19,7 +19,9 @@ public class HttpUtilTest {
|
||||
@Test
|
||||
@Ignore
|
||||
public void postTest() {
|
||||
String result = HttpUtil.createPost("api.uhaozu.com/goods/description/1120448506").charset(CharsetUtil.UTF_8).execute().body();
|
||||
String result = HttpUtil.createPost("api.uhaozu.com/goods/description/1120448506")
|
||||
.charset(CharsetUtil.UTF_8)
|
||||
.execute().body();
|
||||
Console.log(result);
|
||||
}
|
||||
|
||||
@ -45,6 +47,7 @@ public class HttpUtilTest {
|
||||
@Test
|
||||
@Ignore
|
||||
public void getTest2() {
|
||||
// 此链接较为特殊,User-Agent去掉后进入一个JS跳转页面,如果设置了,需要开启302跳转
|
||||
// 自定义的默认header无效
|
||||
String result = HttpRequest
|
||||
.get("https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=101457313&redirect_uri=http%3A%2F%2Fwww.benmovip.com%2Fpay-cloud%2Fqqlogin%2FgetCode&state=ok")
|
||||
|
Loading…
x
Reference in New Issue
Block a user