Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Download Callback interface issue #1191

Open
Chrys4lisfag opened this issue Mar 3, 2025 · 2 comments
Open

Download Callback interface issue #1191

Chrys4lisfag opened this issue Mar 3, 2025 · 2 comments
Assignees

Comments

@Chrys4lisfag
Copy link

Chrys4lisfag commented Mar 3, 2025

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?

@COM8
Copy link
Member

COM8 commented Mar 7, 2025

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 COM8 self-assigned this Mar 7, 2025
@Chrys4lisfag
Copy link
Author

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants