cpr icon indicating copy to clipboard operation
cpr copied to clipboard

Download Callback interface issue

Open Chrys4lisfag opened this issue 10 months ago • 2 comments

I am trying to async callback download image to memory and Download interface is not user-friendly for me.

so we have write callback for DownloadAsync method but we don't have DownloadCallback method where I could have response ctx or some sort where I could just do:

const auto buffer = std::make_shared<std::vector<uint8_t>>();
auto f = session->DownloadAsync( cpr::WriteCallback{
[buffer]( std::string_view data, intptr_t /*userdata*/, auto ctx ) -> bool
{
	buffer->insert( buffer->end(), data.begin(), data.end() );

	if ( ctx->finished && ctx->status_code == 200 )
	{
			//somelogic	
	}

	return true;
} } );

or just DownloadCallback that accepts cpr::Response& and called when download finished where body has payload bytes

Currently, I don't know how conveniently do such thing. session->GetDownloadFileLength() - it does request inside, so the logic is not async anymore SetProgressCallback - sure we can use it but why do we need two callbacks to simply downloading file?

So am I missing something here to conveniently download the file in a callback way?

Chrys4lisfag avatar Mar 03 '25 13:03 Chrys4lisfag

You are right @Chrys4lisfag out of the box cpr does not directly support this use case. You could try something like this:

#include <future>
#include <cpr/async_wrapper.h>
#include <cpr/cpr.h>

template <typename... Ts>
cpr::AsyncResponse fancyDownloadAsync(const cpr::WriteCallback&& writeCb, const std::function<void(const cpr::Response&)>&& responseCb, Ts&&... ts) {
    return cpr::AsyncWrapper{std::async(
        std::launch::async,
        [](const cpr::WriteCallback&& writeCb, const std::function<void(const cpr::Response&)>&& responseCb, Ts&&... ts) {
            const cpr::Response response = cpr::Download(std::move(writeCb), std::forward<Ts>(ts)...);
            responseCb(response);
            return response;
        },
        std::move(writeCb), std::move(responseCb), std::move(ts)...)};
}

COM8 avatar Mar 07 '25 09:03 COM8

Yeah. I did something similar in the end. Would be cool to see some fancy build in way in the future

Chrys4lisfag avatar Mar 07 '25 10:03 Chrys4lisfag