Skip to content

Commit 929d77e

Browse files
committed
add gzip capability
1 parent fd72d4d commit 929d77e

2 files changed

Lines changed: 310 additions & 60 deletions

File tree

modules/openapi-generator/src/main/resources/Java/libraries/native/ApiClient.mustache

Lines changed: 137 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ import org.openapitools.jackson.nullable.JsonNullableModule;
1111
{{/openApiNullable}}
1212

1313
import java.io.InputStream;
14+
import java.io.IOException;
15+
{{#useGzipFeature}}
16+
import java.io.ByteArrayOutputStream;
17+
{{/useGzipFeature}}
1418
import java.net.URI;
1519
import java.net.URLEncoder;
1620
import java.net.http.HttpClient;
@@ -25,6 +29,13 @@ import java.util.Collections;
2529
import java.util.List;
2630
import java.util.StringJoiner;
2731
import java.util.function.Consumer;
32+
import java.util.Optional;
33+
import java.util.zip.GZIPInputStream;
34+
{{#useGzipFeature}}
35+
import java.util.function.Supplier;
36+
import java.util.Objects;
37+
import java.util.zip.GZIPOutputStream;
38+
{{/useGzipFeature}}
2839
import java.util.stream.Collectors;
2940

3041
import static java.nio.charset.StandardCharsets.UTF_8;
@@ -54,7 +65,7 @@ public class ApiClient {
5465
protected String basePath;
5566
protected Consumer<HttpRequest.Builder> interceptor;
5667
protected Consumer<HttpResponse<InputStream>> responseInterceptor;
57-
protected Consumer<HttpResponse<String>> asyncResponseInterceptor;
68+
protected Consumer<HttpResponse<InputStream>> asyncResponseInterceptor;
5869
protected Duration readTimeout;
5970
protected Duration connectTimeout;
6071
@@ -378,7 +389,7 @@ public class ApiClient {
378389
* of null resets the interceptor to a no-op.
379390
* @return This object.
380391
*/
381-
public ApiClient setAsyncResponseInterceptor(Consumer<HttpResponse<String>> interceptor) {
392+
public ApiClient setAsyncResponseInterceptor(Consumer<HttpResponse<InputStream>> interceptor) {
382393
this.asyncResponseInterceptor = interceptor;
383394
return this;
384395
}
@@ -388,7 +399,7 @@ public class ApiClient {
388399
*
389400
* @return The custom interceptor that was set, or null if there isn't any.
390401
*/
391-
public Consumer<HttpResponse<String>> getAsyncResponseInterceptor() {
402+
public Consumer<HttpResponse<InputStream>> getAsyncResponseInterceptor() {
392403
return asyncResponseInterceptor;
393404
}
394405

@@ -448,4 +459,127 @@ public class ApiClient {
448459
public Duration getConnectTimeout() {
449460
return connectTimeout;
450461
}
462+
463+
public static InputStream getResponseBody(HttpResponse<InputStream> response) throws IOException {
464+
if (response == null) {
465+
return null;
466+
}
467+
InputStream body = response.body();
468+
if (body == null) {
469+
return null;
470+
}
471+
Optional<String> encoding = response.headers().firstValue("Content-Encoding");
472+
if (encoding.isPresent()) {
473+
for (String token : encoding.get().split(",")) {
474+
if ("gzip".equalsIgnoreCase(token.trim())) {
475+
return new GZIPInputStream(body);
476+
}
477+
}
478+
}
479+
return body;
480+
}
481+
482+
{{#useGzipFeature}}
483+
public static HttpRequest.BodyPublisher gzipRequestBody(Supplier<InputStream> bodySupplier) {
484+
Objects.requireNonNull(bodySupplier, "bodySupplier must not be null");
485+
return HttpRequest.BodyPublishers.ofInputStream(() -> new GzipCompressingInputStream(bodySupplier));
486+
}
487+
488+
private static final class GzipCompressingInputStream extends InputStream {
489+
private final Supplier<InputStream> supplier;
490+
private final byte[] readBuffer = new byte[8192];
491+
private final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
492+
private InputStream source;
493+
private GZIPOutputStream gzipStream;
494+
private byte[] currentChunk = new byte[0];
495+
private int chunkPosition = 0;
496+
private boolean finished = false;
497+
498+
private GzipCompressingInputStream(Supplier<InputStream> supplier) {
499+
this.supplier = Objects.requireNonNull(supplier, "bodySupplier must not be null");
500+
}
501+
502+
private void ensureInitialized() throws IOException {
503+
if (source == null) {
504+
source = Objects.requireNonNull(supplier.get(), "bodySupplier returned null InputStream");
505+
gzipStream = new GZIPOutputStream(buffer, true);
506+
}
507+
}
508+
509+
private boolean fillBuffer() throws IOException {
510+
ensureInitialized();
511+
while (chunkPosition >= currentChunk.length) {
512+
buffer.reset();
513+
if (finished) {
514+
return false;
515+
}
516+
int bytesRead = source.read(readBuffer);
517+
if (bytesRead == -1) {
518+
gzipStream.finish();
519+
gzipStream.close();
520+
source.close();
521+
finished = true;
522+
} else {
523+
gzipStream.write(readBuffer, 0, bytesRead);
524+
gzipStream.flush();
525+
}
526+
currentChunk = buffer.toByteArray();
527+
chunkPosition = 0;
528+
if (currentChunk.length == 0 && !finished) {
529+
continue;
530+
}
531+
if (currentChunk.length == 0 && finished) {
532+
return false;
533+
}
534+
return true;
535+
}
536+
return true;
537+
}
538+
539+
@Override
540+
public int read() throws IOException {
541+
if (!fillBuffer()) {
542+
return -1;
543+
}
544+
return currentChunk[chunkPosition++] & 0xFF;
545+
}
546+
547+
@Override
548+
public int read(byte[] b, int off, int len) throws IOException {
549+
if (!fillBuffer()) {
550+
return -1;
551+
}
552+
int bytesToCopy = Math.min(len, currentChunk.length - chunkPosition);
553+
System.arraycopy(currentChunk, chunkPosition, b, off, bytesToCopy);
554+
chunkPosition += bytesToCopy;
555+
return bytesToCopy;
556+
}
557+
558+
@Override
559+
public void close() throws IOException {
560+
IOException exception = null;
561+
if (source != null) {
562+
try {
563+
source.close();
564+
} catch (IOException e) {
565+
exception = e;
566+
} finally {
567+
source = null;
568+
}
569+
}
570+
if (gzipStream != null) {
571+
try {
572+
gzipStream.close();
573+
} catch (IOException e) {
574+
exception = exception == null ? e : exception;
575+
} finally {
576+
gzipStream = null;
577+
}
578+
}
579+
if (exception != null) {
580+
throw exception;
581+
}
582+
}
583+
}
584+
{{/useGzipFeature}}
451585
}

0 commit comments

Comments
 (0)