From 0b3554180238e9412960d6a4f6266bb7873b6d95 Mon Sep 17 00:00:00 2001 From: Ryan Bergman Date: Wed, 26 Oct 2022 07:43:29 -0500 Subject: [PATCH] allow use of progressmonitor for byte bodies --- .../BehaviorTests/DownloadProgressTest.java | 20 ++++++++ .../main/java/kong/unirest/BaseRequest.java | 6 +-- .../main/java/kong/unirest/ByteResponse.java | 46 ++++++++++++++++++- .../kong/unirest/MonitoringInputStream.java | 25 ++++++++-- .../kong/unirest/apache/ApacheResponse.java | 31 +------------ 5 files changed, 90 insertions(+), 38 deletions(-) diff --git a/unirest-bdd-tests/src/test/java/BehaviorTests/DownloadProgressTest.java b/unirest-bdd-tests/src/test/java/BehaviorTests/DownloadProgressTest.java index 021e32b39..c283b3fdf 100644 --- a/unirest-bdd-tests/src/test/java/BehaviorTests/DownloadProgressTest.java +++ b/unirest-bdd-tests/src/test/java/BehaviorTests/DownloadProgressTest.java @@ -64,4 +64,24 @@ void canAddUploadProgressAsync() throws Exception { monitor.assertSpideyFileDownload("spidey.jpg"); } + + @Test + void canAddUploadProgressWithBytes() { + Unirest.get(MockServer.BINARYFILE) + .downloadMonitor(monitor) + .asBytes(); + + monitor.assertSpideyFileDownload("body"); + } + + @Test + void canAddUploadProgressWithBytesAsync() throws Exception { + Unirest.get(MockServer.BINARYFILE) + .downloadMonitor(monitor) + .asBytesAsync() + .get(); + + monitor.assertSpideyFileDownload("body"); + } + } diff --git a/unirest/src/main/java/kong/unirest/BaseRequest.java b/unirest/src/main/java/kong/unirest/BaseRequest.java index 0702872c2..65c7b36d0 100644 --- a/unirest/src/main/java/kong/unirest/BaseRequest.java +++ b/unirest/src/main/java/kong/unirest/BaseRequest.java @@ -226,17 +226,17 @@ public CompletableFuture> asStringAsync(Callback ca @Override public HttpResponse asBytes() { - return request(ByteResponse::new, byte[].class); + return request(r -> new ByteResponse(r, downloadMonitor), byte[].class); } @Override public CompletableFuture> asBytesAsync() { - return config.getAsyncClient().request(this, ByteResponse::new, new CompletableFuture<>(), byte[].class); + return config.getAsyncClient().request(this, r -> new ByteResponse(r, downloadMonitor), new CompletableFuture<>(), byte[].class); } @Override public CompletableFuture> asBytesAsync(Callback callback) { - return config.getAsyncClient().request(this, ByteResponse::new, wrap(callback), byte[].class); + return config.getAsyncClient().request(this, r -> new ByteResponse(r, downloadMonitor), wrap(callback), byte[].class); } @Override diff --git a/unirest/src/main/java/kong/unirest/ByteResponse.java b/unirest/src/main/java/kong/unirest/ByteResponse.java index c98684e9e..56c9d9863 100644 --- a/unirest/src/main/java/kong/unirest/ByteResponse.java +++ b/unirest/src/main/java/kong/unirest/ByteResponse.java @@ -25,12 +25,54 @@ package kong.unirest; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; + public class ByteResponse extends BaseResponse { private final byte[] body; - public ByteResponse(RawResponse r) { + public ByteResponse(RawResponse r, ProgressMonitor downloadMonitor) { super(r); - this.body = r.getContentAsBytes(); + if(downloadMonitor == null) { + this.body = r.getContentAsBytes(); + } else { + MonitoringInputStream ip = new MonitoringInputStream(r.getContent(), downloadMonitor, (String)null, r); + try { + body = getBytes(ip); + } catch (IOException e){ + throw new UnirestException(e); + } + } + } + + public static byte[] getBytes(InputStream is) throws IOException { + try { + int len; + int size = 1024; + byte[] buf; + + if (is instanceof ByteArrayInputStream) { + size = is.available(); + buf = new byte[size]; + len = is.read(buf, 0, size); + } else { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + buf = new byte[size]; + while ((len = is.read(buf, 0, size)) != -1) { + bos.write(buf, 0, len); + } + buf = bos.toByteArray(); + } + return buf; + } finally { + is.close(); + } + } + + public static boolean isGzipped(String value) { + return "gzip".equalsIgnoreCase(value.toLowerCase().trim()); } @Override diff --git a/unirest/src/main/java/kong/unirest/MonitoringInputStream.java b/unirest/src/main/java/kong/unirest/MonitoringInputStream.java index 8a2a6bfad..4bb3ce82b 100644 --- a/unirest/src/main/java/kong/unirest/MonitoringInputStream.java +++ b/unirest/src/main/java/kong/unirest/MonitoringInputStream.java @@ -28,6 +28,7 @@ import java.io.IOException; import java.io.InputStream; import java.nio.file.Path; +import java.util.zip.GZIPInputStream; class MonitoringInputStream extends InputStream { private final InputStream content; @@ -36,11 +37,27 @@ class MonitoringInputStream extends InputStream { private long byteCount = 0; private String fileName; - MonitoringInputStream(InputStream content, ProgressMonitor downloadMonitor, Path target, RawResponse contentSize) { - this.content = content; + MonitoringInputStream(InputStream content, ProgressMonitor downloadMonitor, Path target, RawResponse rawResponse) { + this(content, downloadMonitor, target.getFileName().toString(), rawResponse); + } + + MonitoringInputStream(InputStream content, ProgressMonitor downloadMonitor, String fileName, RawResponse rawResponse) { + this.content = wrap(content, rawResponse); this.downloadMonitor = downloadMonitor; - this.fileName = target.getFileName().toString(); - this.totalSize = getBodySize(contentSize); + this.fileName = fileName; + this.totalSize = getBodySize(rawResponse); + } + + private InputStream wrap(InputStream is , RawResponse rawResponse) { + try { + if (is.available() > 0 && "gzip".equalsIgnoreCase(rawResponse.getContentType())) { + return new GZIPInputStream(is); + } else { + return is; + } + }catch (Exception e){ + throw new UnirestException(e); + } } private Long getBodySize(RawResponse r) { diff --git a/unirest/src/main/java/kong/unirest/apache/ApacheResponse.java b/unirest/src/main/java/kong/unirest/apache/ApacheResponse.java index 610c77be9..579c95c2f 100644 --- a/unirest/src/main/java/kong/unirest/apache/ApacheResponse.java +++ b/unirest/src/main/java/kong/unirest/apache/ApacheResponse.java @@ -81,10 +81,10 @@ public byte[] getContentAsBytes() { } try { InputStream is = getContent(); - if (is.available() > 0 && isGzipped(getEncoding())) { + if (is.available() > 0 && ByteResponse.isGzipped(getEncoding())) { is = new GZIPInputStream(getContent()); } - return getBytes(is); + return ByteResponse.getBytes(is); } catch (IOException e2) { throw new UnirestException(e2); } finally { @@ -149,31 +149,4 @@ public String getEncoding() { return ""; } - private static byte[] getBytes(InputStream is) throws IOException { - try { - int len; - int size = 1024; - byte[] buf; - - if (is instanceof ByteArrayInputStream) { - size = is.available(); - buf = new byte[size]; - len = is.read(buf, 0, size); - } else { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - buf = new byte[size]; - while ((len = is.read(buf, 0, size)) != -1) { - bos.write(buf, 0, len); - } - buf = bos.toByteArray(); - } - return buf; - } finally { - is.close(); - } - } - - private static boolean isGzipped(String value) { - return "gzip".equalsIgnoreCase(value.toLowerCase().trim()); - } }