You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I need to create a route that serves a fairly large file, of size initially unknown. For practical reasons, I am not able to generate this file as a stream; it gets generated in a single function call, and this takes several seconds. I am calling this route on a web page behind a "Download" button, and I would like the user to be immediately prompted for where to save the file when they click this button. Unfortunately, whatever I do, the "Save As..." prompt only appears after a few seconds, waiting for my slow function to finish executing to produce the whole file.
I thought that this would allow cpp-httplib to initiate the response, write the headers etc..., and start sending this initial data to the client which would prompt the "Save As..." dialog, and only then call my slow function. But no, I have to wait until my function finishes before the "Save As..." dialog appears.
After running some tests, I found that the "Save As..." dialog appears as soon as the content provider has written at least one byte of data to the sink:
response.set_content_provider("application/zip", [](std::size_t offset, DataSink& sink) {
// Send a dummy charchar c = 0;
sink.write(&c, 1);
// Send the real contentconstauto buffer = my_slow_function();
sink.write(buffer.data(), buffer.size());
sink.done();
returntrue;
});
Now... I can actually use this as a workaround, because the file I am sending is always a zip file which starts with the same 4 bytes, so a workaround (specifically for zips) is:
response.set_content_provider("application/zip", [](std::size_t offset, DataSink& sink) {
// Send first 4 bytes of zip header
sink.write("PK\x03\x04", 4);
// Send the real content, minus first 4 bytes which we already sentconstauto buffer = my_slow_function();
sink.write(buffer.data() + 4, buffer.size() - 4);
sink.done();
returntrue;
});
But this is inelegant (what if my_slow_function() returns another archive type some day?), and cannot be applied in a generic way.
Is there a way to somehow force cpp-httplib to send the response headers before the first sink.write() call?
The text was updated successfully, but these errors were encountered:
I need to create a route that serves a fairly large file, of size initially unknown. For practical reasons, I am not able to generate this file as a stream; it gets generated in a single function call, and this takes several seconds. I am calling this route on a web page behind a "Download" button, and I would like the user to be immediately prompted for where to save the file when they click this button. Unfortunately, whatever I do, the "Save As..." prompt only appears after a few seconds, waiting for my slow function to finish executing to produce the whole file.
I first tried using the content provider like so:
I thought that this would allow cpp-httplib to initiate the response, write the headers etc..., and start sending this initial data to the client which would prompt the "Save As..." dialog, and only then call my slow function. But no, I have to wait until my function finishes before the "Save As..." dialog appears.
After running some tests, I found that the "Save As..." dialog appears as soon as the content provider has written at least one byte of data to the sink:
Now... I can actually use this as a workaround, because the file I am sending is always a zip file which starts with the same 4 bytes, so a workaround (specifically for zips) is:
But this is inelegant (what if
my_slow_function()
returns another archive type some day?), and cannot be applied in a generic way.Is there a way to somehow force cpp-httplib to send the response headers before the first
sink.write()
call?The text was updated successfully, but these errors were encountered: