When web browser plays video, firstly it sends HTTP request with header Range: bytes=0-. From this request it only retrieves first few hunderds of kilobytes and the information about total length from header Content-Length, then the request is cancelled by the browser. Subsequentualy there are requests with HTTP header Range: bytes=123000-456000, but when user starts seeking the request gets cancelled before all the data from requested range are fetched.
I am trying to do the same thing with Apache HttpClient 5.4 over the HTTP/2 with the code like this:
var future = client.execute(
new BasicRequestProducer(videoReq, null),
consumer,
new FutureCallback<>() {
// shortened for readability
@Override
public void cancelled() {
log.info("CANCELLED");
}
});
try {
future.get(100, TimeUnit.MILLISECONDS);
} catch (TimeoutException ex) {
future.cancel(true);
}
where consumer is something like this:
public class Consumer extends AbstractBinResponseConsumer<Void> {
// shortened for readability
@Override
protected void data(ByteBuffer byteBuffer, boolean endOfStream) throws IOException {
int dataAvailable = byteBuffer.remaining();
bytesReceived += dataAvailable;
log.info("Total data received: {}", bytesReceived);
}
}
I can see the CANCELLED message in the log, but even after this message I can see that data are consumed to the end of the stream (which might be hundreds of megabytes).
Does anybody know to properly cancel HTTP/2 async request with Apache HttpClient 5.4?
Why am I doing this? I have reported the issue in Jetty webserver which only occurs on HTTP/2 connections. It was already fixed in Jetty 11, but in Jetty 12 it is hard to reproduce and I am trying to create test application that reproduces the bug on each try, but I am unsuccessful because there is no stream reset done by Apache HttpClient library.
