I was expecting when hitting the endpoint with Chrome that the response will be immediate and the file being downloaded during 10s.
Instead the response is taking 10s then the file is downloaded in a few ms.
I’m not sure how these metrics exactly work, but I tested the code above (well, almost, I’ve used Blaze not Ember - maybe that’s something to double-check) and it seems to work:
first, using curl -vN http://localhost:8080/file incrementaly shows the progress of downloading the data
second, using Chrome - the file is downloaded over 10 seconds, with a progress bar showing how much data has been received so far
Hm that’s interesting. I think it would be best to try to write a really simple http4s route directly (without tapir), to rule out tapir’s involvement. Although, we don’t even depend on blaze/ember, yet alone differentiate between the two when interpreting. Still, a pure-http4s example, if the problem is reproduced, would be what’s needed to open an issue in http4s itself
Hi Adam,
I’ve done more tests, one with a simple htt4ps with ember and it’s working as expected.
I noticed that the response header “Transfer-Encoding=chunked” was automatically added, so I’ve tried to add it in the tapir endpoint and it made it work too!
Here’s the code:
[deleted previous answer]
EDIT: I double-checked and ran some more tests. After all my answer above doesn’t apply because we’re not dealing with files. The example you gave uses streamBinaryBody, which is handled with empty content length, so it’s probably not Tapir who selects between chunked and non-chunked type of response. I think the same issue should happen on running a pure http4s+ember combo and returning a stream, so it doesn’t look like an issue on Tapir side.
I think tapir does the right thing, as transfer-encoding and content-length are mutually exclusive (you use transfer-encoding: chunked because you don’t know the length of the body, see here).
Extending the experiments I get the following results, on the /file endpoint (so chunking is never explicitly enabled):
tapir + ember: no streaming, only C-L set
http4s vanilla + ember: streaming, both T-E and C-L headers set
tapir + blaze: streaming, only C-L set
http4s vanilla + blaze: streaming, only T-E set
The only combination which behaves according to the user’s specification is tapir+blaze. vanilla+blaze discards the provided C-L info and chunks the response. I have no idea why tapir + ember doesn’t do streaming