Skip to content

Commit

Permalink
chore: Json publisher produces Content-Length header.
Browse files Browse the repository at this point in the history
  • Loading branch information
nstdio committed Dec 25, 2022
1 parent a07056c commit ee94d87
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 13 deletions.
42 changes: 29 additions & 13 deletions src/main/java/io/github/nstdio/http/ext/BodyPublishers.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@
import java.net.http.HttpRequest.BodyPublisher;
import java.nio.ByteBuffer;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.Flow;
import java.util.concurrent.ForkJoinPool;
import java.util.function.Supplier;

/**
* Implementations of various useful {@link BodyPublisher}s.
Expand Down Expand Up @@ -95,6 +96,7 @@ static final class JsonPublisher implements BodyPublisher {
private final Object body;
private final JsonMappingProvider provider;
private final Executor executor;
private volatile CompletableFuture<byte[]> result;

JsonPublisher(Object body, JsonMappingProvider provider, Executor executor) {
this.body = body;
Expand All @@ -104,27 +106,41 @@ static final class JsonPublisher implements BodyPublisher {

@Override
public void subscribe(Flow.Subscriber<? super ByteBuffer> subscriber) {
var subscription = ByteArraySubscription.ofByteBuffer(subscriber, bytesSupplier(), executor);
var subscription = ByteArraySubscription.ofByteBuffer(subscriber, this::resultUncheckedGet, executor);

subscriber.onSubscribe(subscription);
}

private Supplier<byte[]> bytesSupplier() {
return () -> {
var os = new ByteArrayOutputStream();
try {
provider.get().write(body, os);
} catch (Throwable e) {
Throwables.sneakyThrow(e);
}
private byte[] resultUncheckedGet() {
try {
return result.get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}

private byte[] json() {
var os = new ByteArrayOutputStream();
try {
provider.get().write(body, os);
} catch (Throwable e) {
Throwables.sneakyThrow(e);
}

return os.toByteArray();
};
return os.toByteArray();
}

@Override
public long contentLength() {
return -1;
if (result == null) {
synchronized (this) {
if (result == null) {
result = CompletableFuture.supplyAsync(this::json, executor);
}
}
}

return resultUncheckedGet().length;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ class BodyPublishersTest(private val mockWebServer: MockWebServer) {
actual.headers["Content-Type"]
.shouldNotBeNull()
.shouldBe("application/json")
actual.headers["Content-Length"]
.shouldNotBeNull()
.shouldBe("13")
}
}

Expand Down

0 comments on commit ee94d87

Please sign in to comment.