cpr::Download with POST method
Hi, can I cpr::Download using a POST method and payload? Something like
session.SetUrl({"http://localhost/file"});
session.SetPayload({{"file_hash", "12345"}});
// Set post method ?
// session.download...
Currently no. But this is something that should be easy to fix. However I won't have time for it until the 15th of October.
Any chance you would like have a look at this and create a PR?
Sure, thanks for your reply.
I'm keeping this issue open until we solved it :)
Unfortunately, I don't have enough c++ programming experience to write this enhancement =(
I can have a look into this one
@ATM-SALEH You are more thank welcome to look at this. Let me know in case you need any help.
@ATM-SALEH any updates from your side? The 1.10.0 release date is coming closer and I also can have a look at it.
@COM8 - Apologies, I couldn't manage time to look into this.
Feel free to have a look
@COM8 @ATM-SALEH Can I look into this? but I will take some time as I am new to this repo.
@harcool sure. You are more than welcome to. Let me know when you need some help/pointers. As soon as you actually start I can assign the issue to you.
Hi @COM8 I have started looking into this. Currently we can only download the file from get method (due to hardcoded option here - https://github.com/libcpr/cpr/blob/e3413506f73eeeafcecabb4ac652aa5560b8fde7/cpr/session.cpp#L860 ). We can download the file using this -
std::ofstream of("1.jpg", std::ios::binary);
cpr::Response r = cpr::Download(of, cpr::Url{"http://www.httpbin.org/1.jpg"});
std::cout << "http status code = " << r.status_code << std::endl << std::endl;
To download using post, We need to set - curl_easy_setopt(curl_->handle, CURLOPT_HTTPPOST, 1); in preparedownload function.
I am thinking like creating a setPostDownload() function in session class. which would set CURLOPT_HTTPPOST to 1.
and then call the download function with that session object. It would look like this -
session.SetUrl({"http://localhost/file"});
session.SetPayload({{"file_hash", "12345"}});
session.setpostdownload();
cpr::download(<ofstream object> , session);
Let me know your thoughts on this.
First I was thinking about adding a new cpr::Download(...) call like cpr::DownloadPost(...) This would solve this quite easily. BUT it's not scalable in my eyes. I like your approach better. We should add a cpr::DownloadPost{true} option like we are doing it for cpr::Verbose{true}. This is the way to here in my eyes.
TLDR; Yes, I agree with your approach.
okay got it. I will take inspiration from cpr::Verbose and raise a PR . I wanted to understand the flow for verbose. Let's say I want to enable verbose for download api.
auto res= cpr::Download(<ostream obj> , cpr::Verbose{true})
my intuition says that cpr::Verbose{true} this would call session::setoption(const verbose& verbose) function but I am not able to understand how it would call. Can you give some pointers on it?
Take a look inside api.h. There you find more information. But the TLDR is:
cpr::Download(cpr::Verbose{true}) -> priv::set_option(session, std::forward<Ts>(ts)...) (recursive for all options) -> session.SetOption(cpr::Verbose{true}) -> session.SetVerbose(cpr::Verbose{true}).
Also a god way to checkout something like this is setting a breakpoint inside cpr::Session::SetVerbose and then inspect the callstack.